Я много раз вызывал getpid() в программе (для проверки эффективности системных вызовов), однако, когда я использую strace
для получения трассировки, только один getpid() звонок перехвачен.
Код прост:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
void print_usage(){
printf("Usage: program count\n");
exit(-1);
}
int main(int argc, char** argv){
if(argc != 2)
print_usage();
int cnt = atoi(argv[1]);
int i = 0;
while(i++<cnt)
getpid();
return 0;
}
Я использовал gdb
и получил это:
(gdb) disasse
Dump of assembler code for function getpid:
0xb76faac0 <getpid+0>: mov %gs:0x4c,%edx
0xb76faac7 <getpid+7>: cmp $0x0,%edx
0xb76faaca <getpid+10>: mov %edx,%eax
0xb76faacc <getpid+12>: jle 0xb76faad0 <getpid+16>
0xb76faace <getpid+14>: repz ret
0xb76faad0 <getpid+16>: jne 0xb76faadc <getpid+28>
0xb76faad2 <getpid+18>: mov %gs:0x48,%eax
0xb76faad8 <getpid+24>: test %eax,%eax
0xb76faada <getpid+26>: jne 0xb76faace <getpid+14>
0xb76faadc <getpid+28>: mov $0x14,%eax
0xb76faae1 <getpid+33>: call *%gs:0x10
0xb76faae8 <getpid+40>: test %edx,%edx
0xb76faaea <getpid+42>: mov %eax,%ecx
0xb76faaec <getpid+44>: jne 0xb76faace <getpid+14>
0xb76faaee <getpid+46>: mov %ecx,%gs:0x48
0xb76faaf5 <getpid+53>: ret
Я не совсем понимаю ассемблерный код. Также было бы полезно, если бы кто-нибудь мог дать подробное объяснение по этому поводу. По моим наблюдениям, вызов *%gs:0x10 (, который переходит в vdso) не выполняется, за исключением первого вызова getpid(), что может быть причиной того, что последующие getpid( ) вызовы не перехватываются. Но я не знаю почему.
Ядро Linux: 2.6.24-29 gcc (GCC) 4.2.4 libc 2.7,
Спасибо!