Ryan Johnson
2010-Jul-20 14:31 UTC
[dtrace-discuss] signed-ness broken for integer values?
Hi all, I would have expected that x < 0, below, but it isn''t (even though it theoretically has only 32 bits, as confirmed by the second probe) self signed int x; self signed long y; self signed int z; BEGIN {self->x = 0xffffffff; self->y = 0xffffffffffffffffl; self->z = 0xffffffffffffffffl; } BEGIN/self->x & 0xffffffff00000000/ { printf("x has 33+ bits"); } BEGIN/self->x < 0/ {printf("x < 0"); } BEGIN/self->y < 0/ {printf("y < 0"); } BEGIN/self->z < 0/ {printf("z < 0"); } BEGIN {exit(0); } I''m using Solaris 10, so maybe I''ve got an old-n-buggy version of dtrace, but google didn''t turn up anything obvious when I searched. Ideas? Ryan
Adam Leventhal
2010-Aug-19 05:32 UTC
[dtrace-discuss] signed-ness broken for integer values?
Hey Ryan, Sorry for the slow response. The bug here is that DTrace isn''t appropriately sign extending the variable. Here''s what we generate: DIFO 0x831740 returns D type (integer) (size 4) OFF OPCODE INSTRUCTION 00: 2c050001 ldts DT_VAR(1280), %r1 ! DT_VAR(1280) = "x" 01: 25000002 setx DT_INTEGER[0], %r2 ! 0x0 02: 0f010200 cmp %r1, %r2 03: 18000006 bl 6 04: 0e000001 mov %r0, %r1 05: 11000007 ba 7 06: 25000101 setx DT_INTEGER[1], %r1 ! 0x1 07: 23000001 ret %r1 If we don''t specify the type for self->x, but instead cast it to an int we get the right thing: DIFO 0x8317d0 returns D type (integer) (size 4) OFF OPCODE INSTRUCTION 00: 2c050001 ldts DT_VAR(1280), %r1 ! DT_VAR(1280) = "x" 01: 25000002 setx DT_INTEGER[0], %r2 ! 0x20 02: 04010201 sll %r1, %r2, %r1 03: 2e010201 sra %r1, %r2, %r1 04: 25000102 setx DT_INTEGER[1], %r2 ! 0x0 05: 0f010200 cmp %r1, %r2 06: 18000009 bl 9 07: 0e000001 mov %r0, %r1 08: 1100000a ba 10 09: 25000201 setx DT_INTEGER[2], %r1 ! 0x1 10: 23000001 ret %r1 Note that after we do the ldts we sign extend the result (%r1). It looks like we need an implicit call to dt_cg_typecast() in the case where the type of the variable is not a uintptr_t. I''ve filed this bug: 6978322 libdtrace compiler fails to sign extend certain variables Adam On Jul 20, 2010, at 7:31 AM, Ryan Johnson wrote:> Hi all, > > I would have expected that x < 0, below, but it isn''t (even though it theoretically has only 32 bits, as confirmed by the second probe) > > self signed int x; > self signed long y; > self signed int z; > BEGIN {self->x = 0xffffffff; self->y = 0xffffffffffffffffl; self->z = 0xffffffffffffffffl; } > BEGIN/self->x & 0xffffffff00000000/ { printf("x has 33+ bits"); } > BEGIN/self->x < 0/ {printf("x < 0"); } > BEGIN/self->y < 0/ {printf("y < 0"); } > BEGIN/self->z < 0/ {printf("z < 0"); } > BEGIN {exit(0); } > > I''m using Solaris 10, so maybe I''ve got an old-n-buggy version of dtrace, but google didn''t turn up anything obvious when I searched. > > Ideas? > Ryan > _______________________________________________ > dtrace-discuss mailing list > dtrace-discuss at opensolaris.org-- Adam Leventhal, Fishworks http://blogs.sun.com/ahl