Back Home
The dwarves presentation at OLS went pretty well, people even seem to have liked it. The paper is now available, use it as the documentation.
Implemented –expand_pointers, that unfolds the pointer types in the same way that –expand_types expand non-pointer types. Should be useful in getting a bigger picture of a project data structure maze of relationships.
It should be a good first step on helping with checking ABI breakage, just use it in the old and new binary and use plain old diff to see what changed, perhaps something down three pointer levels. abichk will probably be a combination of this and what codiff does.
Here is an example:
Lets look at struct request_list in the Linux kernel:
$ pahole -C request_list fs/super.o
struct request_list {
int count[2]; /* 0 8 */
int starved[2]; /* 8 8 */
int elvpriv; /* 16 4 */
/* XXX 4 bytes hole, try to pack */
mempool_t * rq_pool; /* 24 8 */
wait_queue_head_t wait[2]; /* 32 48 */
/* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
/* size: 80, cachelines: 2 */
/* sum members: 76, holes: 1, sum holes: 4 */
/* last cacheline: 16 bytes */
};
Now lets expand its pointers, just one, mempool_t, and one that doesn’t have lots of pointers, to fit into this blog entry:
$ pahole --expand_pointers -C request_list fs/super.o
struct request_list {
int count[2]; /* 0 8 */
int starved[2]; /* 8 8 */
int elvpriv; /* 16 4 */
/* XXX 4 bytes hole, try to pack */
/* typedef mempool_t */ struct mempool_s {
spinlock_t lock;
int min_nr;
int curr_nr;
void * *elements;
void * pool_data;
/* typedef mempool_alloc_t */ void * (*alloc)(gfp_t, void *);
/* typedef mempool_free_t */ void (*free)(void *, void *);
wait_queue_head_t wait;
/* --- cacheline 1 boundary (64 bytes) was 8 bytes ago --- */
} *rq_pool; /* 24 8 */
wait_queue_head_t wait[2]; /* 32 48 */
/* --- cacheline 1 boundary (64 bytes) was 16 bytes ago --- */
/* size: 80, cachelines: 2 */
/* sum members: 76, holes: 1, sum holes: 4 */
/* last cacheline: 16 bytes */
};
It even seems to naturally avoid expanding opaque types, i.e. struct forward declarations, etc, so if header file with structs in the ABI is well written it just doesn’t goes down the non-ABI type rabbit hole, which seems the right thing to do.
Use it with –expand_types and the complete picture can be seen. And in the Linux kernel it is, humm, big:
acme@mica build]$ pahole --quiet --expand_pointers -C inode fs/super.o | wc -l
1345
[acme@mica build]$ pahole --quiet --expand_pointers --expand_types -C inode fs/super.o | wc -l
121922
[acme@mica build]$
One explanation for this last example is needed tho: –expand_types expands a type possibly many times, as many as there are members of its type, –expand_pointers, on the other hand, only expands any given type once, for the first member that is a pointer to this type.
This is because –expand_types was implemented to help in finding what was the field at some offset from complex data structures with a deep hierarchy, –expand_pointers, on the other hand, used most of the –expand_types code, but was implemented to help in finding ABI breakage deep inside the type.
I’ll eventually implement a config option to tell that only the first type should be expanded in the –expand_types case, make that a shell script that takes as parameters two files, call pahole for the two, do a diff and show where the ABI stopped being a virgin
Syndicated 2007-07-07 18:38:03 from Arnaldo's Ramblings