嵌套函数导致内核版本C中出现分段错误>;5.7

嵌套函数导致内核版本C中出现分段错误>;5.7,c,operating-system,C,Operating System,第一个问题,现在开始 我不是要求别人检查代码,我只是想弄清问题的真相。 如果有人知道内核中的什么变化会导致以下情况,这将是很有帮助的 在大学里,我们的任务是在一个用C语言编写的建模操作系统(由我的教授编写)中实现扩展功能,该系统用一个pthread对每个核心进行建模 这个项目由我负责 我们必须通过实现所需的系统调用来实现必要的功能。(多线程、套接字、管道、mlfq等) 在实现每个功能后,我们必须确认它正在使用该程序工作 问题时间: validate_api.c包含很多测试来检查操作系统的功能 启

第一个问题,现在开始

我不是要求别人检查代码,我只是想弄清问题的真相。 如果有人知道内核中的什么变化会导致以下情况,这将是很有帮助的

在大学里,我们的任务是在一个用C语言编写的建模操作系统(由我的教授编写)中实现扩展功能,该系统用一个pthread对每个核心进行建模

这个项目由我负责

我们必须通过实现所需的系统调用来实现必要的功能。(多线程、套接字、管道、mlfq等)

在实现每个功能后,我们必须确认它正在使用该程序工作

问题时间:

validate_api.c包含很多测试来检查操作系统的功能

启动测试:bare启动机器并测试一些东西

在进程内创建新线程的简单测试:

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是否仍然使用蹦床来访问嵌套函数,因为新线程的堆栈中将缺少蹦床代码。