嵌套函数导致内核版本C中出现分段错误>;5.7
第一个问题,现在开始 我不是要求别人检查代码,我只是想弄清问题的真相。 如果有人知道内核中的什么变化会导致以下情况,这将是很有帮助的 在大学里,我们的任务是在一个用C语言编写的建模操作系统(由我的教授编写)中实现扩展功能,该系统用一个pthread对每个核心进行建模 这个项目由我负责 我们必须通过实现所需的系统调用来实现必要的功能。(多线程、套接字、管道、mlfq等) 在实现每个功能后,我们必须确认它正在使用该程序工作 问题时间: validate_api.c包含很多测试来检查操作系统的功能 启动测试:bare启动机器并测试一些东西 在进程内创建新线程的简单测试:嵌套函数导致内核版本C中出现分段错误>;5.7,c,operating-system,C,Operating System,第一个问题,现在开始 我不是要求别人检查代码,我只是想弄清问题的真相。 如果有人知道内核中的什么变化会导致以下情况,这将是很有帮助的 在大学里,我们的任务是在一个用C语言编写的建模操作系统(由我的教授编写)中实现扩展功能,该系统用一个pthread对每个核心进行建模 这个项目由我负责 我们必须通过实现所需的系统调用来实现必要的功能。(多线程、套接字、管道、mlfq等) 在实现每个功能后,我们必须确认它正在使用该程序工作 问题时间: validate_api.c包含很多测试来检查操作系统的功能 启
BOOT_TEST(test_create_join_thread,
"Test that a process thread can be created and joined. Also, that "
"the argument of the thread is passed correctly."
)
{
int flag = 0;
int task(int argl, void* args) {
ASSERT(args == &flag);
*(int*)args = 1;
return 2;
}
Tid_t t = CreateThread(task, sizeof(flag), &flag);
/* Success in creating thread */
ASSERT(t!=NOTHREAD);
int exitval;
/* Join should succeed */
ASSERT(ThreadJoin(t, &exitval)==0);
/* Exit status should be correct */
ASSERT(exitval==2);
/* Shared variable should be updates */
ASSERT(flag==1);
/* A second Join should fail! */
ASSERT(ThreadJoin(t, NULL)==-1);
return 0;
}
如您所见,有一个名为task()的嵌套函数,它是将使用我们实现的createThread()系统调用创建的线程的起点
问题在于尽管线程创建正确,但当计划运行时,程序退出时出现分段错误,无法访问任务函数的内存,gdb甚至无法将其识别为变量(在指向它的过程中)奇怪的是,只有在使用高于5.7的内核版本时才会发生这种情况。我在原始项目的回购协议中开了一家银行
运行实际操作系统及其程序没有任何问题,只是验证api由于嵌套函数而失败。如果我将任务函数移动到全局范围,那么测试将成功完成。同样的情况也适用于所有其他内部有嵌套函数的测试
注意:项目已经完成(现在1个月了),我降级到5.4只是为了测试我的实现
注2:我不需要任何功能实现方面的帮助(项目以任何方式完成),我只想弄清楚为什么它在内核>5.7上不起作用
注3:我来这里是因为我的教授没有回复我关于这个问题的多次电子邮件
我尝试使用-fno-stack-protector和-z-execstack编译,但没有成功。还有简单的嵌套函数,如:
int main(){
int foo(){
puts("Hello there");
}
foo();
}
使用任何内核
机器详细信息:
Arch Linux-5.10/5.4 LTS
GCC 10.2
多谢各位
更新:
测试加入了线程,因此它永远不会超出范围。@fredrarson我也尝试过使用gnu11编译,但没有成功。关于引导测试,你是说扩展BooToTeX的宏是用C++编写的吗?哦,代码> BooToTest< <代码>我读到了,作为<代码> BooStyTest< <代码>抱歉,这是不同的。我不知道什么是
BOOT\u TEST
。它是一个调用bios来启动操作系统的宏。在任何情况下,既然C标准不支持本地函数,为什么它在5.4内核上工作(-std=makefile中的c11)?我不相信嵌套函数所需的不同调用约定和堆栈帧/布局与线程创建兼容。我的意思是,通过使用不同的堆栈从父级外部调用一个函数,您正在打破嵌套函数提供的隔离:)此外,GCC是否仍然使用蹦床来访问嵌套函数,因为新线程的堆栈中将缺少蹦床代码。