考虑以下 C 程序:
int main()
{
waitpid(1337);
}
正如预期的那样,gcc 和 clang 都警告我关于 waitpid 的隐式声明,但生成的二进制文件可以正常工作。当ltrace
-ing 它时,我看到了
waitpid(1337, 0x7fff86950ec8, -2037051688)
叫做。现在三个问题:
- 为什么上面的 C 代码甚至可以工作?我应该必须包括
sys/wait.h
才能调用waitpid。printf
调用而不包括时也会发生同样的事情stdio.h
。输出有效。 - 所以 gcc 仍然可以调用 waitpid,但为什么即使它有 3 个参数,也可以只用一个参数调用它?
ltrace
多次调用暗示其他两个参数是随机值?Gcc 在单参数 waitpid 和三参数 waitpid 之间进行了一些转换,但是如何实现呢? - 如何使用 gdb 找出最后两个参数背后的值?其他两个值没有显示在源代码中,那么如何在 gcc 中访问它们?
我收集到的一些线索:我查看了 main 函数的汇编器输出:
0x000000000040050c <+0>: push %rbp
0x000000000040050d <+1>: mov %rsp,%rbp
0x0000000000400510 <+4>: mov $0x539,%edi
0x0000000000400515 <+9>: mov $0x0,%eax
0x000000000040051a <+14>: callq 0x4003f0 <waitpid@plt>
0x000000000040051f <+19>: pop %rbp
0x0000000000400520 <+20>: retq
所以我想这不是 gcc 做某事,因为确实似乎有一个 waitpid 函数只接受一个参数(1337)?