Ryan Johnson
2010-07-14 10:05:38 UTC
Hi all,
There was a discussion about this a while back, but now some new
information has come to light:
Consider the situation where a thread calls a leaf function which does
not create a stack frame (such as atomic_*). The following toy program
demonstrates this scenario:
--- begin backtrace.c ------------
#include <atomic.h>
unsigned int x;
int foo() {
int y = 1;
while(y != 100) {
y = atomic_swap_32(&x, y);
}
return x;
}
int main() {
return 10 + foo();
}
--- end backtrace.c ------------
If we grab stack frames by instrumenting the function directly --
"pid$target::atomic_swap_32:entry {@counts[ustack()]=count();}" -- then
we get:
libc.so.1`atomic_swap_32
a.out`foo+0x2c
a.out`main+0x4
a.out`_start+0x108
1054138
If, on the other hand, we profile the process --
"profile-7777us/pid==$target/ {@counts[ustack()]=count(); }" -- and grab
stack frames again, we get (among other far rarer variants):
libc.so.1`atomic_swap_32
a.out`main+0x4
a.out`_start+0x108
1167
Note that this is *not* related to tail calls (there are none here).
Since in both cases $pc is the same, the problem must be due to either
the profile probe's way of saving process context or else the stack
walking code doing something wrong under profiling...
Ideas?
Ryan
There was a discussion about this a while back, but now some new
information has come to light:
Consider the situation where a thread calls a leaf function which does
not create a stack frame (such as atomic_*). The following toy program
demonstrates this scenario:
--- begin backtrace.c ------------
#include <atomic.h>
unsigned int x;
int foo() {
int y = 1;
while(y != 100) {
y = atomic_swap_32(&x, y);
}
return x;
}
int main() {
return 10 + foo();
}
--- end backtrace.c ------------
If we grab stack frames by instrumenting the function directly --
"pid$target::atomic_swap_32:entry {@counts[ustack()]=count();}" -- then
we get:
libc.so.1`atomic_swap_32
a.out`foo+0x2c
a.out`main+0x4
a.out`_start+0x108
1054138
If, on the other hand, we profile the process --
"profile-7777us/pid==$target/ {@counts[ustack()]=count(); }" -- and grab
stack frames again, we get (among other far rarer variants):
libc.so.1`atomic_swap_32
a.out`main+0x4
a.out`_start+0x108
1167
Note that this is *not* related to tail calls (there are none here).
Since in both cases $pc is the same, the problem must be due to either
the profile probe's way of saving process context or else the stack
walking code doing something wrong under profiling...
Ideas?
Ryan