Issues compiling xv6 with latest gcc version
问题描述
在用高版本gcc编译 xv6 时,会出现以下错误(这里用的是 12.1.1 ):
make qemu
...
user/sh.c: In function 'runcmd':
user/sh.c:58:1: error: infinite recursion detected [-Werror=infinite-recursion]
58 | runcmd(struct cmd *cmd)
| ^~~~~~
...
这是因为gcc高版本加入了对无限递归函数的检测,在默认设置下会对这种行为发出警告。而 xv6 中的编译选项有-Werror,因此该警告会被视为错误。但是在操作系统中,很多功能都是不返回的,如exec更换进程上下文后正常执行是不会返回的,而sh在正常情况下在子进程结束后也将返回到本身,继续接收下一条命令。因此,不应将sh.c的这种写法视为错误。
解决方案
1. 为runcmd加上noreturn标签,这样编译器知道它是永不返回的,因而不会将它的无限递归调用视为错误。具体而言,可以在runcmd函数定义前面加上该标签,如
...
// Execute cmd. Never returns.
__attribute__((noreturn))
void
runcmd(struct cmd *cmd)
...或者直接加上一个带有noreturn标签的函数原型,如
...
struct cmd *parsecmd(char*);
void runcmd(struct cmd*) __attribute__((noreturn));
// Execute cmd. Never returns.
void
runcmd(struct cmd *cmd)
...2. 告知编译器,忽略无限递归的错误。在Makefile中找到以下行
CFLAGS = -Wall -Werror -O -fno-omit-frame-pointer -ggdb将其改为
CFLAGS = -Wall -Werror -Wno-error=infinite-recursion -O -fno-omit-frame-pointer -ggdb参考资料
https://github.com/mit-pdos/xv6-riscv/pull/126
鸣谢
感谢 Eastonman 为我提供的 GitHub pull request 链接。