为什么 return 不退出 xv6 中的进程?

Why return does not exit a process in xv6?

这是我的 user/sleep.c:

代码
#include "kernel/types.h"
#include "user/user.h"

int
main(int argc, char *argv[])
{
        if (argc < 2)
        {
                printf("You have forgotten to pass an argument.");
                exit(1);
        }
        int arg = atoi(argv[1]);
        sleep(arg);
        exit(0);
        // return 0;
}

一切正常,但使用 return 0 而不是 exit(0),我收到以下错误:

usertrap(): unexpected scause 0x000000000000000d pid=4
            sepc=0x00000000000000f6 stval=0x0000000000003008

这是为什么?

因为xv6在这一点上不规范:

https://tnallen.people.clemson.edu/2019/03/04/intro-to-xv6.html

Returning after main is a special case that is not supported in XV6, so just remember to always exit() at the end of main instead of return. Otherwise, you will get a “trap 14,” which in this case is XV6-speak for “Segmentation Fault.” Finally, notice that our headers are different. There is no #include <stdio.h> as you might be used to. Again, this is because the standard library is different. Check out these headers to see what kind of user utilities you have available.


那么为什么我们在 xv6 中需要 exit()

因为,例如,当使用 gcc 为 linux 构建程序时,工具链会添加所需的 exit 调用:请参阅 https://en.wikipedia.org/wiki/Crt0

简而言之,在 linux,您的程序不是从 main 开始,而是从 start:

开始
void start(void) {
    /* get argc, argv, env) */

    int r = main(argc, argv, envp);  /*  << start calls the actual main */

    exit(r);
}

在 xv6 上,相反,当 OS 尝试从 main 到 return 时,真正的起点是 main,它没有地址弹出什么导致段错误