Discussion:
struct padding on x64
Mark Phalan
2010-05-12 16:53:47 UTC
Permalink
Are the padding rules supposed to be consistent between the compiler and
dtrace on x64?


# cat /tmp/s.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;

typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;

BEGIN {
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
exit(0);
}

# cat /tmp/s.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;

typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;

BEGIN {
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
exit(0);
}

$ cc -m64 /tmp/x.c -o /tmp/x
$ /tmp/x
my_data: 16
more_data: 24
offset: 8

# dtrace -qs /tmp/s.d
my_data: 16
more_data: 20
offset: 4


Bug?
Nicolas Williams
2010-05-12 17:08:55 UTC
Permalink
Post by Mark Phalan
Are the padding rules supposed to be consistent between the compiler and
dtrace on x64?
# cat /tmp/s.d
...
# cat /tmp/s.d
...
Did you mean to catn /tmp/x.c and /tmp/s.d?
Post by Mark Phalan
$ cc -m64 /tmp/x.c -o /tmp/x
Dunno what x.c contains... I'm assuming something very similar to what
s.d contains.
Post by Mark Phalan
$ /tmp/x
my_data: 16
more_data: 24
offset: 8
# dtrace -qs /tmp/s.d
my_data: 16
more_data: 20
offset: 4
Bug?
Probably, I think. The code here is all 64-bit, so differences in
alignment in ILP32 vs. LP64 cannot be the problem.

Nico
--
Mark Phalan
2010-05-12 17:14:24 UTC
Permalink
Post by Nicolas Williams
Post by Mark Phalan
Are the padding rules supposed to be consistent between the compiler and
dtrace on x64?
# cat /tmp/s.d
...
# cat /tmp/s.d
...
Did you mean to catn /tmp/x.c and /tmp/s.d?
Sorry...

$ cat /tmp/x.c
#include <stdio.h>
#include <sys/types.h>
#include <stddef.h>

typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;

typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;

int main() {
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
}
Post by Nicolas Williams
Post by Mark Phalan
$ cc -m64 /tmp/x.c -o /tmp/x
Dunno what x.c contains... I'm assuming something very similar to what
s.d contains.
Yup, pretty much identical. See above.

-M
Pavan Chandrashekar
2010-05-12 17:50:56 UTC
Permalink
Post by Mark Phalan
Are the padding rules supposed to be consistent between the compiler and
dtrace on x64?
Looks like structure "declarations" within dtrace are not enforced to
follow C alignment.
But when you try to populate the structure, it complains. Here is a
small experiment that I did:

bash-3.2# cat s.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;

typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;

more_data a;

BEGIN {
a.x = 10;
a.y.a = 20;
a.y.b = 30;
a.y.c = 40;
printf("\n");
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
printf("%u %u %u %lu", a.x, a.y.a, a.y.b, a.y.c);
exit(0);
}

Running it gives me the following error:
bash-3.2# dtrace -s s.d
dtrace: script 's.d' matched 1 probe
dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): invalid
alignment (0x3000cc5eb24) in action #4 at DIF offset 24
^C

Now, changing the structure definition to make it 8 byte aligned
resolves the error:

bash-3.2# cat s1.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;

typedef struct _more_data {
uint32_t x;
uint32_t z;
my_data y;
} more_data;

more_data a;

BEGIN {
a.x = 10;
a.y.a = 20;
a.y.b = 30;
a.y.c = 40;
printf("\n");
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
printf("%u %u %u %lu", a.x, a.y.a, a.y.b, a.y.c);
exit(0);
}
bash-3.2# dtrace -s
s1.d

dtrace: script 's1.d' matched 1 probe
CPU ID FUNCTION:NAME
1 1 :BEGIN
my_data: 16
more_data: 24
offset: 8
10 20 30 40

The only different between s.d and s1.d is :
bash-3.2# diff s.d s1.d
8a9
Post by Mark Phalan
uint32_t z;
bash-3.2#

So, there does seem to be some assumption about the alignment of the
structures,
and the D compiler itself does not seem to be enforcing it.

Pavan
Post by Mark Phalan
# cat /tmp/s.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;
typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;
BEGIN {
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
exit(0);
}
# cat /tmp/s.d
typedef struct _my_data {
uint32_t a;
uint32_t b;
uint64_t c;
} my_data;
typedef struct _more_data {
uint32_t x;
my_data y;
} more_data;
BEGIN {
printf("my_data: %d\n", sizeof(my_data));
printf("more_data: %d\n", sizeof(more_data));
printf("offset: %d\n", offsetof(more_data, y));
exit(0);
}
$ cc -m64 /tmp/x.c -o /tmp/x
$ /tmp/x
my_data: 16
more_data: 24
offset: 8
# dtrace -qs /tmp/s.d
my_data: 16
more_data: 20
offset: 4
Bug?
_______________________________________________
dtrace-discuss mailing list
Mark Phalan
2010-05-12 17:53:24 UTC
Permalink
Post by Pavan Chandrashekar
Post by Mark Phalan
Are the padding rules supposed to be consistent between the compiler and
dtrace on x64?
Looks like structure "declarations" within dtrace are not enforced to
follow C alignment.
But when you try to populate the structure, it complains.
I hit this when working on my USDT provider where the structures are
copyin()ed so instead of complaints I got weird data :(

Anyway it looks like a bug to me. I'll file one.

-M
Katsunori FUJIWARA
2010-05-13 04:46:59 UTC
Permalink
Post by Mark Phalan
Are the padding rules supposed to be consistent
between the compiler and
dtrace on x64?
....
Post by Mark Phalan
Bug?
I think so.

Please refer my posts about this problem to dtrace-discuss and bugzilla, too !

http://www.opensolaris.org/jive/thread.jspa?threadID=127996
https://defect.opensolaris.org/bz/show_bug.cgi?id=15766
--
This message posted from opensolaris.org
Loading...