Discussion:
signed-ness broken for integer values?
Ryan Johnson
2010-07-20 14:31:26 UTC
Permalink
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-08-19 05:32:16 UTC
Permalink
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
Post by Ryan Johnson
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
--
Adam Leventhal, Fishworks http://blogs.sun.com/ahl
Loading...