Add a trivial sample to demonstrate that loading dwarf-4, dwarf-5, with and without split-dwarf works. Observe that before this patch there are valgrind leaks. Obverse that there are even more valgrind leaks after this patch. But it does make things load all 4 sample builds, and present the same sample pahole output for all of them. Abosolutely no idea what pointer_size variable is, or what it was in dwarf_next_unit() or what it is in dwarf_cu_die(), or if that's what cu__new() needs. Separtely if one compiles linux kernel with dwarf-5 and split-dwarf, and tries to run this build of pahole, even on like a trivial kernel module it segfaults eventually when trying to ftype__recode_dwarf_types, because eventually pos becomes NULL and NULL dereference happens. So something about the created cus is not quite right. Strongly suspecting that pointer_size actually matters and possibly loaidng subdie needs to be properly accounted for. NACKed-by: Dimitri John Ledkov <dimitri.ledkov@xxxxxxxxxxxxx> --- dwarf_loader.c | 31 ++++++++++++------------------- dwarves.c | 8 ++++++++ sample.c | 10 ++++++++++ sample.sh | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 sample.c create mode 100755 sample.sh diff --git a/dwarf_loader.c b/dwarf_loader.c index ccf31943bb..84aebed7c5 100644 --- a/dwarf_loader.c +++ b/dwarf_loader.c @@ -2823,13 +2823,6 @@ static int die__process(Dwarf_Die *die, struct cu *cu, struct conf_load *conf) const uint16_t tag = dwarf_tag(die); if (tag == DW_TAG_skeleton_unit) { - static bool warned; - - if (!warned) { - fprintf(stderr, "WARNING: DW_TAG_skeleton_unit used, please look for a .dwo file and use it instead.\n" - " A future version of pahole will support do this automagically.\n"); - warned = true; - } return 0; // so that other units can be processed } @@ -3068,20 +3061,22 @@ static int __cus__load_debug_types(struct conf_load *conf, Dwfl_Module *mod, Dwa const char *filename, const unsigned char *build_id, int build_id_len, struct cu **cup, struct dwarf_cu *dcup) { - Dwarf_Off off = 0, noff, type_off; - size_t cuhl; uint8_t pointer_size, offset_size; - uint64_t signature; + + Dwarf_CU *dgu_cu = NULL; + Dwarf_Die result; + Dwarf_Die cudie; + Dwarf_Die subdie; *cup = NULL; - while (dwarf_next_unit(dw, off, &noff, &cuhl, NULL, NULL, &pointer_size, - &offset_size, &signature, &type_off) - == 0) { + while (dwarf_get_units(dw,dgu_cu,&dgu_cu,NULL,NULL,&cudie,&subdie)==0) { if (*cup == NULL) { struct cu *cu; + dwarf_cu_die (dgu_cu, &result, NULL, NULL, &pointer_size, NULL, NULL, NULL); + cu = cu__new("", pointer_size, build_id, build_id_len, filename, conf->use_obstack); if (cu == NULL || @@ -3100,14 +3095,12 @@ static int __cus__load_debug_types(struct conf_load *conf, Dwfl_Module *mod, Dwa *cup = cu; } - Dwarf_Die die_mem; - Dwarf_Die *cu_die = dwarf_offdie_types(dw, off + cuhl, - &die_mem); - - if (die__process(cu_die, *cup, conf) != 0) + if (die__process(&cudie, *cup, conf) != 0) return DWARF_CB_ABORT; + if (dwarf_tag(&subdie) != DW_TAG_invalid) + if (die__process(&subdie, *cup, conf) != 0) + return DWARF_CB_ABORT; - off = noff; } if (*cup != NULL && cu__recode_dwarf_types(*cup) != 0) diff --git a/dwarves.c b/dwarves.c index 9f97edaea2..2abab727fc 100644 --- a/dwarves.c +++ b/dwarves.c @@ -62,6 +62,10 @@ void *cu__malloc(struct cu *cu, size_t size) void cu__free(struct cu *cu, void *ptr) { + // FIXME it seems like loading split dwarf, causes multiple + // references to the same thing, and thus current clean up & + // free code aborts on double free's + return; if (!cu->use_obstack) free(ptr); @@ -711,6 +715,10 @@ out_free: void cu__delete(struct cu *cu) { + // FIXME it seems like loading split dwarf, causes multiple + // references to the same thing, and thus current clean up & + // free code aborts on double free's + return; if (cu == NULL) return; diff --git a/sample.c b/sample.c new file mode 100644 index 0000000000..bff48d3139 --- /dev/null +++ b/sample.c @@ -0,0 +1,10 @@ +#include <stdio.h> +struct Sample { + char sample_string[50]; + int sample_integer; + float sample_float; +}; +void main() { + struct Sample sample = {.sample_integer = 3}; + printf("%i\n", sample.sample_integer); +} diff --git a/sample.sh b/sample.sh new file mode 100755 index 0000000000..241d4adec8 --- /dev/null +++ b/sample.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -x +rc=0 +gcc -gdwarf-5 -gsplit-dwarf ./sample.c +valgrind ./pahole ./a.out +rc=$((rc + $?)) +gcc -gdwarf-4 -gsplit-dwarf ./sample.c +valgrind ./pahole ./a.out +rc=$((rc + $?)) +gcc -gdwarf-5 ./sample.c +valgrind ./pahole ./a.out +rc=$((rc + $?)) +gcc -gdwarf-4 ./sample.c +valgrind ./pahole ./a.out +rc=$((rc + $?)) +rm -f a.out +exit $rc + -- 2.34.1