[dtrace-discuss] ustack() wrong in pid return probes?
Adam Leventhal
ahl at eng.sun.com
Sat Jan 20 21:37:13 PST 2007
You're right that it's going to be tricky to discover the location of the
return address once the stack frame has already been popped. I'm really not
a fan of having ustack() reflect the state of the system ostensibly after
the probe has fired. To me, that's a very confusing metaphor. I may assume
incorrectly, that people are knowledgeable of leaf contexts and would
make the leap that there's actually an intervening function call. You
can end up in a similar situation in the presence of tail-calls -- and
there's no way to account for that.
Adam
On Sat, Jan 20, 2007 at 07:31:03PM -0800, James McIlree wrote:
>
> I looked at trying to implement the same style of hack for return
> probes, but it seems like it may grow a bit more involved. There is no
> way to find the pc for "c()" unless it is squirreled away somewhere
> other than the stack. If it's a "ret" instruction, you could hope that
> the
> data just below $sp was still valid, but if the return probe is firing
> because
> of another control flow mechanism, there may not be any data to
> fetch.
>
> In my mind, a->b->c is a more understandable than a->b->d.
> The former is incomplete, the latter is actually wrong.
>
> Especially when I was first investigating this, I had several
> "but you just can't get to D from B!" moments.
>
> I'll file a RFE :-).
>
> James M
>
> On Jan 20, 2007, at 6:49 PM, Adam Leventhal wrote:
>
> >In a return probe, a user might reasonably expect one of several
> >results
> >from the ustack() action:
> >
> > 1) the full call chain (a->b->c->d)
> > 2) the state of the stack after returning from the function (a->b-
> >>c)
> > 3) the result of naively walking the stack (a->b->d)
> >
> >(2) seems confusing since the function associated with the probe
> >wouldn't
> >be present in the output. While (1) would be ideal, we implement (3)
> >because
> >we can't, in the general case, determine if we're in leaf context or
> >not
> >(that is, if we're in a part of the function where a stack frame has
> >been
> >pushed).
> >
> >Entry probes for the pid provider produce (1) because we implement a
> >hack in
> >which the pid provider adds a hint to the ustack code that we're in
> >leaf
> >context. We could easily do the same for return probes which would
> >solve
> >this problem in that case, but the result for offset probes will vary
> >(compare the output of ustack() in pid123::main:entry and
> >pid123:::main:0)
> >
> >Feel free to file an RFE if you think return probes should use the
> >same
> >hack as entry probes.
> >
> >Adam
> >
> >On Sat, Jan 20, 2007 at 06:32:12PM -0800, James McIlree wrote:
> >> I have a test program which has a call sequence of
> >>a(), b(), c(), d().
> >>
> >> When I place a pid return probe on d(), I get a ustack that
> >>looks like this:
> >>
> >> a.out`d+0x19
> >> a.out`b+0xd
> >> a.out`a+0xd
> >> a.out`main+0x3c
> >> a.out`_start+0x7a
> >>
> >> The c() method appears to be missing.
> >>
> >> I did some poking around and noticed that pid return probes
> >>fire after the instruction being instrumented has executed.
> >>
> >> It seems to me that after a "ret", we're actually in
> >>method c() now, not d(). However, there is this comment and code
> >>in fasttrap_isa.c :
> >>
> >>/*
> >> * Set the program counter to the address of the traced
> >> * instruction so that it looks right in ustack()
> >> * output. We had previously set it to the end of the
> >> * instruction to simplify %rip-relative addressing.
> >> */
> >>rp->r_pc = pc;
> >>
> >> Is this correct? It seems like the correct ustack()
> >>output would be if the pc was set to "new_pc". Does that break
> >>invariants elsewhere in the code?
> >>
> >> I've included a ustackTest.c & ustack.d that demonstrates
> >>what I'm seeing.
> >>
> >> James M
> >>
> >>--------------------- ustackTest.c --------------------------
> >>
> >>#include <stdio.h>
> >>#include <unistd.h>
> >>
> >>void d(int arg) {
> >> printf("Got arg of %d\n", arg);
> >>}
> >>
> >>void c(int arg) {
> >> d(arg+1);
> >>}
> >>
> >>void b(int arg) {
> >> c(arg+1);
> >>}
> >>
> >>void a(int arg) {
> >> b(arg+1);
> >>}
> >>
> >>int main(void)
> >>{
> >> int value = 0;
> >>
> >> printf("PID is %u\n", getpid());
> >>
> >> while(1) {
> >> a(value++);
> >> sleep(1);
> >> }
> >>}
> >>
> >>------------------------- ustack.d -----------------------
> >>
> >>pid$target::d:entry
> >>{
> >> printf("entry stack...\n");
> >> ustack();
> >>}
> >>
> >>pid$target::d:return
> >>{
> >> printf("return stack...\n");
> >> ustack();
> >>}
> >>
> >>
> >>_______________________________________________
> >>dtrace-discuss mailing list
> >>dtrace-discuss at opensolaris.org
> >
> >--
> >Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
--
Adam Leventhal, Solaris Kernel Development http://blogs.sun.com/ahl
More information about the dtrace-discuss
mailing list