From 4b0af6b6d0d9744068d37f7033f0dd236abcd4ba Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Mon, 11 Sep 2023 23:58:00 -0400 Subject: [PATCH] Refactor of some dwarf handling and debug improvements --- src/symbols/symbols_with_libdwarf.cpp | 69 ++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/src/symbols/symbols_with_libdwarf.cpp b/src/symbols/symbols_with_libdwarf.cpp index d2d567b..783a4af 100644 --- a/src/symbols/symbols_with_libdwarf.cpp +++ b/src/symbols/symbols_with_libdwarf.cpp @@ -185,6 +185,7 @@ namespace cpptrace { namespace libdwarf { // printbugging as we go constexpr bool dump_dwarf = false; + constexpr bool trace_dwarf = false; static void err_handler(Dwarf_Error err, Dwarf_Ptr errarg) { printf("libdwarf error reading %s: %lu %s\n", "xx", (unsigned long)dwarf_errno(err), dwarf_errmsg(err)); @@ -262,23 +263,30 @@ namespace cpptrace { struct die_object { Dwarf_Debug dbg = nullptr; Dwarf_Die die = nullptr; + die_object(Dwarf_Debug dbg, Dwarf_Die die) : dbg(dbg), die(die) {} + ~die_object() { if(die) { dwarf_dealloc(dbg, die, DW_DLA_DIE); } } + die_object(const die_object&) = delete; + die_object& operator=(const die_object&) = delete; + die_object(die_object&& other) : dbg(other.dbg), die(other.die) { other.die = nullptr; } + die_object& operator=(die_object&& other) { dbg = other.dbg; die = other.die; other.die = nullptr; return *this; } + die_object get_child() const { Dwarf_Die child = nullptr; int ret = dwarf_child( @@ -295,6 +303,7 @@ namespace cpptrace { exit(1); } } + die_object get_sibling() const { Dwarf_Die sibling = 0; int ret = dwarf_siblingof_b(dbg, die, true, &sibling, nullptr); @@ -307,12 +316,15 @@ namespace cpptrace { exit(1); } } + operator bool() const { return die != nullptr; } + Dwarf_Die get() const { return die; } + std::string get_name() const { char* name; int ret = dwarf_diename(die, &name, nullptr); @@ -323,11 +335,25 @@ namespace cpptrace { } return name; } + Dwarf_Half get_tag() const { Dwarf_Half tag = 0; dwarf_tag(die, &tag, nullptr); return tag; } + + const char* get_tag_name() const { + const char* tag_name; + dwarf_get_TAG_name(get_tag(), &tag_name); + return tag_name; + } + + Dwarf_Off get_global_offset() const { + Dwarf_Off off; + int ret = dwarf_dieoffset(die, &off, nullptr); + assert(ret == DW_DLV_OK); + return off; + } }; void walk_die_list( @@ -486,9 +512,7 @@ namespace cpptrace { extents += "[" + std::to_string(val + 1) + "]"; dwarf_dealloc_attribute(attr); } else { - const char* tag_name = nullptr; - dwarf_get_TAG_name(subrange.get_tag(), &tag_name); - fprintf(stderr, "unknown tag %s\n", tag_name); + fprintf(stderr, "unknown tag %s\n", subrange.get_tag_name()); } }); return extents; @@ -602,9 +626,7 @@ namespace cpptrace { } default: { - const char* tag_name = nullptr; - dwarf_get_TAG_name(die.get_tag(), &tag_name); - fprintf(stderr, "unknown tag %s\n", tag_name); + fprintf(stderr, "unknown tag %s\n", die.get_tag_name()); exit(1); } } @@ -696,13 +718,11 @@ namespace cpptrace { [pc, dwversion, &frame] (Dwarf_Debug dbg, const die_object& die) { int ret; if(dump_dwarf) { - const char* tag_name; - dwarf_get_TAG_name(die.get_tag(), &tag_name); fprintf( stderr, "-------------> %d %s %s\n", dwversion, - tag_name, + die.get_tag_name(), die.get_name().c_str() ); } @@ -712,6 +732,9 @@ namespace cpptrace { fprintf(stderr, "pc not in die\n"); } } else { + if(trace_dwarf) { + fprintf(stderr, "pc in die %08llx %s\n", die.get_global_offset(), die.get_tag_name()); + } if(dump_dwarf) { fprintf(stderr, "pc in die <-----------------------------------\n"); } @@ -819,6 +842,9 @@ namespace cpptrace { Dwarf_Half offset_size = 0; Dwarf_Half dwversion = 0; dwarf_get_version_of_die(cu_die.get(), &dwversion, &offset_size); + if(trace_dwarf) { + fprintf(stderr, "CU: %d %s\n", dwversion, cu_die.get_name().c_str()); + } /*auto child = cu_die.get_child(); if(child) { walk_die_list_recursive( @@ -872,7 +898,7 @@ namespace cpptrace { } } - void lookup_pc2( + void lookup_pc( const char* object, Dwarf_Addr pc, stacktrace_frame& frame @@ -883,8 +909,16 @@ namespace cpptrace { } Dwarf_Debug dbg; Dwarf_Ptr errarg = 0; - auto ret = dwarf_init_path(object, nullptr, 0, - DW_GROUPNUMBER_ANY, err_handler, errarg, &dbg, nullptr); + auto ret = dwarf_init_path( + object, + nullptr, + 0, + DW_GROUPNUMBER_ANY, + err_handler, + errarg, + &dbg, + nullptr + ); if(ret == DW_DLV_NO_ENTRY) { // fail, no debug info } else if(ret != DW_DLV_OK) { @@ -900,7 +934,16 @@ namespace cpptrace { frame.filename = frame_info.obj_path; frame.symbol = frame_info.symbol; frame.address = frame_info.raw_address; - lookup_pc2( + if(trace_dwarf) { + fprintf( + stderr, + "%s %08lx %s\n", + frame_info.obj_path.c_str(), + frame_info.obj_address, + frame_info.symbol.c_str() + ); + } + lookup_pc( frame_info.obj_path.c_str(), frame_info.obj_address, frame