I have a simple test program (test.c) to reproduce this problem:
#include <stdio.h>
#include <sys/time.h>
void g() {
struct timeval tv;
gettimeofday(&tv, NULL);
}
void f() { g(); }
int main() {
f();
}
If I compile this program with `gcc -O0 -o test_O0 test.c`, and do backtrace by running `libunwind/tests/test-ptrace -s -v ./test_O0`, I get the expected results when gettimeofday() is intercepted, see below:
00007ffed67fee89 +0x432 (sp=00007ffed67fb000)
00000000004005be g+0x28 (sp=00007ffed67fb010)
00000000004005e3 f+0xe (sp=00007ffed67fb070)
00000000004005f4 main+0xe (sp=00007ffed67fb080)
00007fbda5924830 __libc_start_main+0xf0 (sp=00007ffed67fb090)
00000000004004c9 _start+0x29 (sp=00007ffed67fb150)
================
I slightly modified the output format of test-ptrace.c so the output is more succinct. But this shows that when gettimeofday is invoked, the backtrace is main() -> f() -> g() -> somewhere in libc -> gettimeofday(), which is expected.
However, when I compile the same program with `gcc -O2 -o test_O2 test.c`, and do backtrace by running `libunwind/tests/test-ptrace -s -v ./test_O2`, I get the following:
00007ffda5dc4e89 +0x432 (sp=00007ffda5ca3560)
00000000004004be main+0x1e (sp=00007ffda5ca3570)
00000000004004be main+0x1e (sp=00007ffda5ca35a0)
00007fec46b15830 __libc_start_main+0xf0 (sp=00007ffda5ca35d0)
0000000000400509 _start+0x29 (sp=00007ffda5ca3690)
================
Well, since f() and g() don't do anything other than eventually calling gettimeofday(), I can understand the compiler got rid of these unnecessary function calls and just put the invocation of gettimeofday() inside of main. I confirmed this by dissembling the compiled binary. However, what I don't understand is why `main+0x1e` appears twice in the backtrace.
I'm on a Linux x86_64 Ubuntu 16.04 machine. Any help is appreciated!
Thanks!
-
Hai