|
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.
|