This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
perl script for struct offsets etc
- To: gdb at sources dot redhat dot com
- Subject: perl script for struct offsets etc
- From: RDBrown at mira dot net
- Date: Thu, 25 Jan 2001 20:38:52 +1100 (EST)
- Reply-To: RDBrown at mira dot net,RodneyBrown at mynd dot com
The enclosed perl script generates a gdb command script from ptype output
that shows the byte offset, length in bytes and cumulative fill byte count
for each field of the class or structure.
Where class/structure ordering isn't imposed, the output could be used
to argue for an ordering that pushes alignment fill to the end or
brings frequently referenced fields together for `better' cache usage.
Any scripting support added to gdb should be able to do something like this
directly.
501 /devel/spanopen/700 % gdb libff/librds.so
GNU gdb 19990928
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) ptype sql_proccolinfo_t
type = class sql_proccolinfo_t {
private:
dh_i16_t dtor_flag;
hm_hdl_t *hm_curhdl;
public:
slink sl;
dh_u16_t pci_proccolid;
procid_t pci_procid;
tpe_rssid_t pci_rssid;
char pci_col[36];
char pci_datatype[36];
typeid_t pci_typeid;
sql_proccoltype_t pci_coltype;
dh_i32_t pci_width;
dh_i32_t pci_scale;
dh_boolean pci_nonull;
sql_dflt_t pci_dflttp;
dh_char_t *pci_default;
sql_proccolinfo_t & operator=(sql_proccolinfo_t const &);
sql_proccolinfo_t(sql_proccolinfo_t const &);
static void * operator new(unsigned int);
static void * operator new(unsigned int, hm_hdl_t *);
static void operator delete(void *);
sql_proccolinfo_t(alloctype_t);
sql_proccolinfo_t(hm_hdl_t *, alloctype_t);
~sql_proccolinfo_t(void);
}
(gdb) shell # xterm cut & paste
501 /devel/spanopen/700 % perl gdboff.pl > gdb.proccolinfo_t <<EOF
> type = class sql_proccolinfo_t {
> private:
> dh_i16_t dtor_flag;
> hm_hdl_t *hm_curhdl;
> public:
> slink sl;
> dh_u16_t pci_proccolid;
> procid_t pci_procid;
> tpe_rssid_t pci_rssid;
> char pci_col[36];
> char pci_datatype[36];
> typeid_t pci_typeid;
> sql_proccoltype_t pci_coltype;
> dh_i32_t pci_width;
> dh_i32_t pci_scale;
> dh_boolean pci_nonull;
> sql_dflt_t pci_dflttp;
> dh_char_t *pci_default;
>
> sql_proccolinfo_t & operator=(sql_proccolinfo_t const &);
> sql_proccolinfo_t(sql_proccolinfo_t const &);
> static void * operator new(unsigned int);
> static void * operator new(unsigned int, hm_hdl_t *);
> static void operator delete(void *);
> sql_proccolinfo_t(alloctype_t);
> sql_proccolinfo_t(hm_hdl_t *, alloctype_t);
> ~sql_proccolinfo_t(void);
> }
> EOF
502 /devel/spanopen/700 % exit # Leading `>'-s from bash.
exit
(gdb) source gdb.proccolinfo_t
sizeof(sql_proccolinfo_t) 128
sql_proccolinfo_t.dtor_flag 0 2 0
sql_proccolinfo_t.hm_curhdl 4 4 2
sql_proccolinfo_t.sl 8 8 2
sql_proccolinfo_t.pci_proccolid 16 2 2
sql_proccolinfo_t.pci_procid 20 4 4
sql_proccolinfo_t.pci_rssid 24 4 4
sql_proccolinfo_t.pci_col 28 36 4
sql_proccolinfo_t.pci_datatype 64 36 4
sql_proccolinfo_t.pci_typeid 100 4 4
sql_proccolinfo_t.pci_coltype 104 4 4
sql_proccolinfo_t.pci_width 108 4 4
sql_proccolinfo_t.pci_scale 112 4 4
sql_proccolinfo_t.pci_nonull 116 1 4
sql_proccolinfo_t.pci_dflttp 120 4 7
sql_proccolinfo_t.pci_default 124 4 7
(gdb) q
502 /devel/spanopen/700 % exit
# Generate a gdb script to display offset, length and cumulative fill bytes
# for each field of a class or struct,
# from the gdb ptype output of the class or struct.
# eg
#sizeof(xyz) 128
#xyz.dtor_flag 0 2 0
#xyz.hm_curhdl 4 4 2
# ...
while (<>) {
if (/^type = (?:class|struct) (\w+) {\s*$/) {
$the_type = $1;
printf "printf \"sizeof(%s)\\t%%d\\n\", sizeof(%s)\n",
$the_type, $the_type;
printf "set variable \$cumlen = 0\n";
}
if (defined($the_type)) {
if (/^}\s*$/) {
undef $the_type;
}
elsif (/^(?:| p(?:rivate|public):)\s*$/) {
}
elsif (/ \**(\w+)(?:|\[\d+\]);\s*$/) {
my($the_field) = $1;
printf "set variable \$offset = (int)(&(((%s *)0)->%s))\nset variable \$fieldlen = sizeof(((%s *)0)->%s)\nprintf \"%s.%s\\t%%d\\t%%d\\t%%d\\n\", \$offset, \$fieldlen, \$offset - \$cumlen\nset variable \$cumlen += \$fieldlen\n",
$the_type, $the_field, $the_type, $the_field,
$the_type, $the_field;
}
elsif (/(?:[^; ]|\);)\s*$/) {
}
}
}