Sometimes you may want to get offsets
of a structure fields. This will be useful when you are doing manual
debugging of memory dump.
So, there should be a way to
calculate the offsets of a particular fields. Debugging information in
an object file contains offsets of a data structure as well. For this,
you need to build your program with debugging information enabled, that
means with -g option. Then the compiler embeds the structure fields
offsets into the object file in the debugging information section. Once
you have the object file generated using -g option, you can use any
object file analysis tool to find out the offsets.
But, manually going through the
debugging information and finding offsets will be some what difficult.
If there is a program which will use the debugging information and print
the offsets of a structure fields it will be very useful.
pahole
Such kind of program is ‘pahole’.
Though purpose of this program is not only for offsets printing, this
can be used for our purpose. You need to install ‘dwarves’ package on
your machine to use this command. On ubuntu machine, you can try like
this:
1
sudo apt-get install dwarves
Basic syntax of ‘pahole’ is:
Syntax: pahole [-C ]
For example, let’s take this small program.
vim test_pahole.c
01
#include
02
03
struct emp {
04
05
int id;
06
short salary;
07
char name[20];
08
int doj;
09
};
10
11
int main(void)
12
{
13
14
struct emp obj;
15
}
Here I defined a structure named
struct emp and in the main() I just create an object for emp. Let’s
compile this program with -g option and see how pahole is used.
1
$gcc -g test_pahole.c -o test_pahole
Let’ now use pahole to list the offsets of fields of struct emp;
1
$pahole -C emp test_pahole
Here in the ouput, the first field,
‘id’ is at ’0′th offset and is of 4 bytes size. And The second field
‘salary’ is at offset 4 and is of size 2 bytes. And next the name field
is at offset 6 and is of 20 bytes size, And next it says that there is a
2 bytes of hole to make the structure fields aligned. And then you have
the ‘doj’ field at offset 28 which is of 4 bytes size. And next few
line of output says that the whole size of the structure is 32 bytes,
size of the members is 30 and there is a one hole which is of size 2
bytes.
Take another example here:
vim test_pahole2.c
01
#include
02
03
struct addr {
04
05
int houseno;
06
07
char street[10];
08
09
char city[20];
10
11
char country[20];
12
13
};
14
15
struct emp {
16
17
int id;
18
19
short salary;
20
21
char name[20];
22
23
int doj;
24
25
struct addr adr;
26
27
};
28
29
int main(void)
30
31
{
32
33
struct emp obj;
34
35
}
Here I defined two data structures name emp and addr. Let’s compile this program and see how pahole prints the offsets.
1
$gcc -g test_pahole2.c -o test_pahole2
If you don’t give any options along with the object file name, you will be printed all data structures fields. Like this:
You can see that both the structures fields are printed.
If I just ask to print the struct emp offsets, it will print like this:
1
$ pahole -C emp test_pahole1
Here you can observe that it prints
the offset of ‘addr’ field and it’s size. The struct addr is not
expanded here. If you ever want that to be expanded, you can use ‘-E’
option along with the pahole command. Like this:
1
$ pahole -E -C emp test_pahole1
You can see, struct addr fields are also expanded here.
Take this another example:
vim test_pahole3.c
01
#include
02
03
struct addr {
04
05
int houseno;
06
char street[10];
07
char city[20];
08
char country[20];
09
};
10
11
struct emp {
12
int id;
13
short salary;
14
char name[20];
15
int doj;
16
struct addr adr;
17
FILE *fp;
18
};
19
20
int main(void)
21
22
{
23
struct emp obj;
24
}
Here I have added one more field ‘fp’
of type FILE in the struct emp. As I am using the FILE struct here, you
can also print the offsets of this FILE structure. Actuall FILE is a
typedef to _IO_FILE .
Let’s compile this program and print the FILE data structure fields.
1
$ gcc -g test_pahole1.c -o test_pahole1
1
$ pahole -E -C _IO_FILE test_pahole1
I printed the FILE data structure
fields as well. So, with this you can understand that, if we use any
data structure in our object file, you will get the offsets of the
structure fields in the debugging information.
Note that the above fields are
printed after resolving the #ifdefs if there are any, so we need not to
worry about the #ifdefs and need not to worry about the platform(32 bit
or 64 bit).