나는 시스템 호출의 효율성을 테스트하기 위해 여러 번 "getpid()"를 호출했지만 strace를 사용하여 추적을 얻었을 때 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
내가 꽤 조립 코드를 이해하지 않습니다. 누군가가 그것에 대해 자세히 설명 할 수 있다면 도움이 될 것입니다. 내 관찰에 따르면, 첫 번째 getpid() 호출을 제외하고 "getgid : 0x10"(vdso로 점프)은 실행되지 않습니다. 이는 다른 getpid 호출이 캡처되지 않은 이유 일 수 있습니다. 그러나 나는 왜 그런지 모른다.
리눅스 커널 : 2.6.24-29 GCC (GCC) 2.7의 libc 4.2.4 ,
감사합니다!
좋습니다. 그리고 또 다른 질문이 있습니다. 그것은 적절하지 않을 수 있습니다. 나는 첫 getpid() 호출이 gettimeofday처럼 vdso를 활용하여 사용자 커널 모드 전환을 트리거하지 않는지 궁금합니다. – Infinite
또 다른 질문은 gdb를 사용하여 "call * % gs : 0x10"을 어떻게 수행 할 수 있습니까? – Infinite
거기에 단 하나의 대답이 확실하지 않습니다. syscall은 플랫폼에 따라 다르게 처리됩니다 (즉, 32 비트 x86 및 64 비트 x86_64조차 다른 syscall 메커니즘을 가짐). 어쩌면 내가 틀렸을 것입니다. 아마도 그 질문에 대해 별도의 질문을 게시하고, 관심있는 아키텍처가 무엇인지, 특히 관심이있는 아키텍처가 있다면 syscalls를 지정하십시오. (필자는 – Mat