如果程序的主程序返回i32,为什么$? (由调用它的外壳测量)截断为8位?

时间:2020-07-09 00:03:36

标签: llvm llvm-ir

很抱歉出现这样的菜鸟问题,但是为什么结果不是516

define i32 @main()
{
        %1 = add i32 6, 500
        %2 = add i32 5, 5
        %3 = add i32 %1, %2
        ret i32 %3
}

http://llvm.org/docs/LangRef.html#integer-type

i32一个32位整数。

用法:

./lli Program.ir; echo $?
4

预先感谢

2 个答案:

答案 0 :(得分:3)

Unix中进程的退出代码只有8位。无论是否涉及LLVM,任何较大的值都会被截断:

Map

答案 1 :(得分:3)

出口 code (我将区分程序返回的出口 value 和可用于实际上,在类似UNIX的操作系统中,启动程序的过程)是几个不同项目的集合,其中一个是退出值。例如,参见this link,其中包含(带有我的 强调 [extra information]):

不要将程序的退出状态[value]与进程的终止状态[code]混淆。除了完成程序之外,还有很多方法可以终止进程。但是,如果进程终止是由程序终止引起的(即exit),则程序的退出状态[value]会成为程序的 part 进程的终止状态[code]

从流程中获取实际退出状态的宏(请参见here)状态:

如果WIFEXITED的状态为true,则此宏返回子进程的退出状态值的 低8位

Linux exit_group系统调用的实际源代码也表明了这一点,该源代码最终被exit调用:

SYSCALL_DEFINE1(exit_group, int, error_code)
{
    do_group_exit((error_code & 0xff) << 8);
    /* NOTREACHED */
    return 0;
}

您可以在那里看到它仅使用退出值的低八位,并将其左移,以便可以在其中存储其他项(控制信息),在这种情况下全为零。与信号处理器发出的仅用于设置控制信息的 进行对比:

do_group_exit(ksig->info.si_signo)

换句话说,它还必须在进程退出代码中添加其他内容,例如哪个信号终止了它(如果终止了一个信号),是否转储了内核等等。上。这就是为什么将退出值限制在比您预期的范围更小的原因。

ISO标准(C11)在7.22.4.4 The exit function /5中也允许这样做(因为从main()返回整数值等效于用该值调用exit()

最后,控制权返回到主机环境。如果status的值为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式。如果status的值为EXIT_FAILURE,则返回实现定义的状态,表示状态失败终止。 否则返回的状态是实现定义的。