次の C プログラムを考えてみましょう。
int main()
{
waitpid(1337);
}
予想通り、gcc と clang はどちらも waitpid の暗黙の宣言について警告しますが、結果のバイナリは正常に動作します。するとltrace
、それがわかります
waitpid(1337, 0x7fff86950ec8, -2037051688)
と呼ばれます。ここで 3 つの質問:
- 上記の C コードが機能するのはなぜですか?
sys/wait.h
waitpid を呼び出せるようにするには、インクルードする必要があります。printf
を呼び出して含めない場合も同じことが起こりstdio.h
ます。出力は機能します。 - したがって、gcc はまだ waitpid を呼び出す魔法を行っていますが、引数が 3 つあるにもかかわらず、引数を 1 つしか指定できないのはなぜでしょうか?
ltrace
複数回呼び出すと、他の 2 つの引数がランダムな値であることがわかりますか? Gcc は 1 つの引数の waitpid と 3 つの引数の waitpid の間で何らかの変換を行いますが、どのように? - 最後の 2 つの引数の背後にある値を把握するために gdb を使用するにはどうすればよいですか? 他の 2 つの値はソースコードに表示されません。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
したがって、正確に1つの引数(1337)を取るwaitpid関数が実際にあるように見えるので、何かを行うのはgccではないと思いますか?