lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master ff677ea: Show source file and line number in


From: Greg Chicares
Subject: [lmi-commits] [lmi] master ff677ea: Show source file and line number in backtrace
Date: Mon, 8 Feb 2021 18:21:03 -0500 (EST)

branch: master
commit ff677ea486d1b83498b4d4b4d7384e1c3cc11e59
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Show source file and line number in backtrace
    
    Incidentally:
     - s/pc/ip/ to conform to libunwind usage (UNW_REG_IP, e.g.)
     - added "return;" after calls to fail(): exit() would be too severe
     - wrote '"?""?""?"' instead of '"???"' because '??' marks lmi defects
     - commented out code to print byte offset, which seems unuseful
---
 unwind.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/unwind.cpp b/unwind.cpp
index e4a8d8c..6ae91ec 100644
--- a/unwind.cpp
+++ b/unwind.cpp
@@ -31,6 +31,7 @@
 #include <cstdlib>                      // free()
 #include <cxxabi.h>
 #include <dlfcn.h>
+#include <elfutils/libdwfl.h>
 #include <exception>
 #include <execinfo.h>
 #include <libunwind.h>
@@ -118,21 +119,36 @@ void fail(char const* msg)
 
 void print_backtrace()
 {
+    // Initialize libdw.
+    char* debuginfo_path     = 0;
+    Dwfl_Callbacks callbacks = {};
+    callbacks.find_elf       = dwfl_linux_proc_find_elf;
+    callbacks.find_debuginfo = dwfl_standard_find_debuginfo;
+    callbacks.debuginfo_path = &debuginfo_path;
+    Dwfl* dwfl = dwfl_begin(&callbacks);
+    if
+        (dwfl == 0
+        || 0 != dwfl_linux_proc_report(dwfl, getpid())
+        || 0 != dwfl_report_end(dwfl, 0, 0)
+        )
+        {fail("Error initializing DWARF."); return;}
+
+    // Initialize libunwind.
     unw_context_t context;
     if(0 != unw_getcontext(&context))
-        {fail("Failed to get machine state");}
+        {fail("Failed to get machine state"); return;}
 
     unw_cursor_t cursor;
     if(0 != unw_init_local(&cursor, &context))
-        {fail("Failed to initialize cursor");}
+        {fail("Failed to initialize cursor"); return;}
 
     // IP is in this function, so first frame could be skipped.
+    int frame_number = 0;
     while(0 < unw_step(&cursor))
         {
-        unw_word_t pc;
-        if(0 != unw_get_reg(&cursor, UNW_REG_IP, &pc))
-            {fail("Failed to read IP");}
-        std::fprintf(stderr, "0x%lx: ", pc);
+        unw_word_t ip;
+        if(0 != unw_get_reg(&cursor, UNW_REG_IP, &ip))
+            {fail("Failed to read IP register"); return;}
 
         char symbol[4096]; // Should be plenty.
         unw_word_t offset;
@@ -140,14 +156,33 @@ void print_backtrace()
             {
             int status = 0;
             char* demangled_name = abi::__cxa_demangle(symbol, 0, 0, &status);
-            char* name = (0 == status) ? demangled_name : symbol;
-            std::fprintf(stderr, "(%s+0x%lx)\n", name, offset);
+            char* function_name = (0 == status) ? demangled_name : symbol;
+
+            char const* source_file = "?""?""?";
+            int line_number = 0;
+
+            Dwarf_Addr addr = ip - 4;
+            Dwfl_Line* obj_line = dwfl_getsrc(dwfl, addr);
+            if (obj_line != 0)
+                {
+                source_file = dwfl_lineinfo(obj_line, &addr, &line_number, 0, 
0, 0);
+                }
+
+            std::fprintf(stderr, "#%2d"      , frame_number);
+            std::fprintf(stderr, " 0x%lx:"   , ip);
+            std::fprintf(stderr, " %s:%d"    , source_file, line_number);
+// 'offset' doesn't seem very useful
+//          std::fprintf(stderr, " %s +0x%lx", function_name, offset);
+            std::fprintf(stderr, " %s"       , function_name);
+            std::fprintf(stderr, "\n");
+
             std::free(demangled_name);
             }
         else
             {
             std::fprintf(stderr, "Failed to get symbol name.\n");
             }
+        ++frame_number;
         }
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]