OpenSolaris

Printable Version Enter a New Search
Bug ID 6576371
Synopsis Tail-call USDT probes can use wrong argument values
State 10-Fix Delivered (Fix available in build)
Category:Subcategory kernel:dtrace
Keywords
Responsible Engineer Adam Leventhal
Reported Against snv_67
Duplicate Of
Introduced In
Commit to Fix snv_70
Fixed In snv_70
Release Fixed solaris_nevada(snv_70)
Related Bugs
Submit Date 2-July-2007
Last Update Date 8-August-2007
Description
I tried using the pytrace.d D script found on John's blog:

    http://blogs.sun.com/levon/entry/python_and_dtrace_in_build

on my box, but got lots of output like the following:

    dtrace: error on enabled probe ID 7 (ID 50344: python981:libpython2.4.so.1.0:dtrace_entry:function-entry): invalid address (0xffffe000) in predicate at DIF offset 28
    dtrace: error on enabled probe ID 7 (ID 50344: python981:libpython2.4.so.1.0:dtrace_entry:function-entry): invalid address (0xffffe000) in predicate at DIF offset 28
    dtrace: error on enabled probe ID 7 (ID 50344: python981:libpython2.4.so.1.0:dtrace_entry:function-entry): invalid address (0xffffe000) in predicate at DIF offset 28
    dtrace: error on enabled probe ID 7 (ID 50344: python981:libpython2.4.so.1.0:dtrace_entry:function-entry): invalid address (0xffffe000) in predicate at DIF offset 28
    dtrace: error on enabled probe ID 9 (ID 50346: python981:libpython2.4.so.1.0:dtrace_return:function-return): invalid address (0x0) in predicate at DIF offset 28
    dtrace: error on enabled probe ID 9 (ID 50346: python981:libpython2.4.so.1.0:dtrace_return:function-return): invalid address (0x0) in predicate at DIF offset 28

John's code is in the build I'm running, and I've got appropriate privs.  John suggested it might be
a sparc/x86 issue, though I haven't tried it on x86.
This works on x86 (e.g. baggs.sfbay). At some point between testing
and it arriving from JDS (a long time) this has broken, but it's
not at all clear how. the arg0 and arg1 values appear to be junk.
Some further testing indicates that this never worked in the current
form of the patch.

When the initial static probe is compiled it's doing a tail call optimization
on the fake dtrace 'call':

    dtrace_entry+0x2c:      40 00 00 00  call      +0x0          <dtrace_entry+0x2c>
    dtrace_entry+0x30:      d2 07 20 3c  ld        [%i4 + 0x3c], %o1
    dtrace_entry+0x34:      b4 10 00 08  mov       %o0, %i2
    dtrace_entry+0x38:      40 00 00 00  call      +0x0          <dtrace_entry+0x38>
    dtrace_entry+0x3c:      81 e8 00 00  restore

Thus we populate %i0-2 with the USDT arguments. When we link, as the code says
in dt_link.c:

 822         } else {
 823                 /*
 824                  * If the call is followed by a restore, it's a tail call so
 825                  * change the call to a ret.

giving:

libpython2.4.so.1.0`dtrace_entry+0x34:  mov       %o0, %i2
libpython2.4.so.1.0`dtrace_entry+0x38:  ret
libpython2.4.so.1.0`dtrace_entry+0x3c:  restore

Finally, when we actually instrument the site, we end up with:

libpython2.4.so.1.0`dtrace_entry+0x30:  ld        [%i4 + 0x3c], %o1
libpython2.4.so.1.0`dtrace_entry+0x34:  mov       %o0, %i2
libpython2.4.so.1.0`dtrace_entry+0x38:  ta        %icc, %g0 + 0x38
libpython2.4.so.1.0`dtrace_entry+0x3c:  restore

but traps don't take delay slots, so we end up populating %i0-2 but using %o0-2.

I'm not at all sure about how to fix this, since we could easily just be doing
a dynamic probe on the a normal ret/restore combination, so we don't want to
futz with the registers like we do with return probes and fake_restore. I'm
sure Adam has a marvellous idea.

(This hoping that my SPARC hasn't completely collapsed into uselessness.)
I've attached a new version of the Python dtrace patch which implements
a workaround for this. I'm leaving this bug for the generic fix, and
will do the workaround separately.
Work Around
N/A
Comments
N/A