c - 在不包含 sys/wait.h 的情况下使用单个参数调用时 waitpid 的参数值

标签 c assembly

考虑以下 C 程序:

int main()
{
    waitpid(1337);
}

正如预期的那样,gcc 和 clang 都警告我有关 waitpid 的隐式声明,但生成的二进制文件工作正常。当 ltrace-ing 时,我看到了

waitpid(1337, 0x7fff86950ec8, -2037051688)

被调用。现在三个问题:

  1. 为什么上面的 C 代码可以工作?我必须包含 sys/wait.h 才能调用 waitpid。当调用 printf 并且不包含 stdio.h 时,也会发生同样的事情。输出有效。
  2. 所以 gcc 做了一些魔法来仍然调用 waitpid,但为什么可以只用一个参数调用它,即使它有三个参数?多次调用 ltrace 是否暗示其他两个参数是随机值? Gcc 在一个参数的 waitpid 和三个参数的 waitpid 之间做了一些转换,但是怎么做的?
  3. 如何使用 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)?

最佳答案

why does the above C code even work?

它“起作用”是偶然的。 C 允许您在不指定其原型(prototype)的情况下调用函数,即不包含其 header 。当您这样做时,它对参数的数量和类型做出假设并尝试调用它。显然,使用错误数量的参数调用函数是未定义的行为。

6.5.2.2-3

If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined.

关于您的第三个问题,我怀疑您看到的垃圾只是堆栈中的剩余物。要确定这是否属实,请在 waitpid 之前放置一个断点,然后进入它并查看通过的内容。

关于c - 在不包含 sys/wait.h 的情况下使用单个参数调用时 waitpid 的参数值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15062509/

相关文章:

linux - 如何避免不适合缓冲区的标准输入被发送到 Linux 64 位 Intel (x86-64) 程序集中的 shell

assembly - 如何仅使用 mov、add、sub、neg 限制 4 条指令中的 x=2a+3b?

c - x86 程序集 : What's the main prologue and epilogue?

c - OpenMP 并行 for 循环

x86 - 用于 x86 (MASM) 汇编的免费 IDE + 汇编器 + 软件模拟器?

C(Linux): warning: assignment discards qualifiers from pointer target type

c - C 程序中使用 Malloc 和 for 循环出现意外结果

assembly - 使用 int 21h, 2Ch 显示系统时间

c - 结构值以意想不到的方式从一个函数更改为另一个函数

c - 如何使用 C 语言的套接字将客户端连接到 IRC 服务器