]> sourceware.org Git - systemtap.git/commitdiff
PR12276: dump debug_line data to generated header
authorAbegail Jakop <ajakop@redhat.com>
Fri, 5 Dec 2014 15:15:37 +0000 (10:15 -0500)
committerAbegail Jakop <ajakop@redhat.com>
Fri, 5 Dec 2014 15:38:12 +0000 (10:38 -0500)
elaborate.cxx: set a flag to indicate debug_line data is needed if
pragma:lines was found in embedded code
translate.cxx: gather debug_line data if it is needed and can be accessed.
if the data was gathered, output it to the generated header file

elaborate.cxx
runtime/sym.h
session.cxx
session.h
translate.cxx

index 35109ab45b99ba265188588123ff860175b66bab..98260913d024a1ba67bd6a03f08025c02580925b 100644 (file)
@@ -1550,6 +1550,15 @@ public:
                    current_function->name.c_str()) << endl;
        session.need_symbols = true;
       }
+
+    if (! session.need_lines
+        && c->code.find("/* pragma:lines */") != string::npos)
+      {
+        if (session.verbose > 2)
+         clog << _F("Turning on debug line data collecting, pragma:lines found in %s",
+                   current_function->name.c_str()) << endl;
+       session.need_symbols = true;
+      }
   }
 };
 
index 7c6d017e2671c94fe64e43a256929755bf0fbfb0..6a03d3ff75669bc7f0ee4b4bfa46ee00fc03bf3d 100644 (file)
 #define _STP_SYM_NEWLINE    256
 /* Adds only module " [`basename name`]" if found, use with _STP_SYM_MODULE. */
 #define _STP_SYM_MODULE_BASENAME 512
+/* Adds the line number */
+#define _STP_SYM_LINENUMBER 1024
+/* Adds the filename the symbol is from when  _STP_SYM_LINENUMBER is used. */
+#define _STP_SYM_FILENAME 2048
 
 /* Used for backtraces in hex string form. */
 #define _STP_SYM_NONE  (_STP_SYM_HEXSTR | _STP_SYM_POST_SPACE)
@@ -82,9 +86,11 @@ struct _stp_module {
        void *debug_frame;
        void *eh_frame;
        void *unwind_hdr;       
+  void *debug_line;
        uint32_t debug_frame_len;
        uint32_t eh_frame_len;
        uint32_t unwind_hdr_len;
+  uint32_t debug_line_len;
        unsigned long eh_frame_addr; /* Orig load address (offset) .eh_frame */
        unsigned long unwind_hdr_addr; /* same for .eh_frame_hdr */
 
index 5f2465a23eb45b80dba842f71159831cc325063b..79a23dea92dbb2308cd5163f1db71416b4d6a81c 100644 (file)
@@ -145,6 +145,7 @@ systemtap_session::systemtap_session ():
   need_uprobes = false;
   need_unwind = false;
   need_symbols = false;
+  need_lines = false;
   uprobes_path = "";
   load_only = false;
   skip_badvars = false;
@@ -326,6 +327,7 @@ systemtap_session::systemtap_session (const systemtap_session& other,
   need_uprobes = false;
   need_unwind = false;
   need_symbols = false;
+  need_lines = false;
   uprobes_path = "";
   load_only = other.load_only;
   skip_badvars = other.skip_badvars;
index 63cacc99763276294073eded807fabd6359ae580..ddb82c572cc67bfc5ce6c0d8ebc26cd3cb3164d4 100644 (file)
--- a/session.h
+++ b/session.h
@@ -209,6 +209,7 @@ public:
   bool need_uprobes;
   bool need_unwind;
   bool need_symbols;
+  bool need_lines;
   std::string uprobes_path;
   std::string uprobes_hash;
   bool load_only; // flight recorder mode
index db08fdf5ef9f98b14add5c2a327c7a059a816582..748b84d181b67ce39ea56f73ecb37f4925f8e485 100644 (file)
@@ -6214,6 +6214,8 @@ struct unwindsym_dump_context
   size_t eh_frame_hdr_len;
   Dwarf_Addr eh_addr;
   Dwarf_Addr eh_frame_hdr_addr;
+  void *debug_line;
+  size_t debug_line_len;
 
   set<string> undone_unwindsym_modules;
 };
@@ -6547,6 +6549,41 @@ dump_section_list (Dwfl_Module *m,
   return DWARF_CB_ABORT;
 }
 
+static void
+dump_line_tables (Dwfl_Module *m, unwindsym_dump_context *c,
+                  const char *modname, Dwarf_Addr base)
+{
+  Elf* elf;
+  Elf_Scn* scn = NULL;
+  Elf_Data* data;
+  GElf_Ehdr *ehdr, ehdr_mem;
+  GElf_Shdr* shdr, shdr_mem;
+  Dwarf_Addr bias, start;
+
+  dwfl_module_info (m, NULL, &start, NULL, NULL, NULL, NULL, NULL);
+
+  elf = dwfl_module_getelf (m, &bias);
+  if (elf == NULL)
+    return;
+
+  // we do not have the index for debug_line, so we can't use elf_getscn()
+  // instead, we need to seach through the sections for the correct one as in
+  // get_unwind_data()
+  ehdr = gelf_getehdr(elf, &ehdr_mem);
+  while ((scn = elf_nextscn(elf, scn)))
+    {
+      shdr = gelf_getshdr(scn, &shdr_mem);
+      if (strcmp(elf_strptr(elf, ehdr->e_shstrndx, shdr->sh_name),
+                 ".debug_line") == 0)
+        {
+          data = elf_rawdata(scn, NULL);
+          c->debug_line = data->d_buf;
+          c->debug_line_len = data->d_size;
+          break;
+        }
+    }
+}
+
 /* Some architectures create special local symbols that are not
    interesting. */
 static int
@@ -6826,7 +6863,11 @@ dump_unwindsym_cxt_table(systemtap_session& session, ostream& output,
       return;
     }
 
-  output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
+  // if it is the debug_line data, do not need the unwind flags to be defined
+  if(table == "debug_line")
+    output << "#if defined(STP_NEED_LINE_DATA)\n";
+  else
+    output << "#if defined(STP_USE_DWARF_UNWINDER) && defined(STP_NEED_UNWIND_DATA)\n";
   output << "static uint8_t _stp_module_" << modindex << "_" << table;
   if (!secname.empty())
     output << "_" << secindex;
@@ -6840,7 +6881,10 @@ dump_unwindsym_cxt_table(systemtap_session& session, ostream& output,
        output << "\n" << "   ";
     }
   output << "};\n";
-  output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n";
+  if (table == "debug_line")
+    output << "#endif /* STP_NEED_LINE_DATA */\n";
+  else
+    output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA */\n";
 }
 
 static int
@@ -6861,6 +6905,8 @@ dump_unwindsym_cxt (Dwfl_Module *m,
   size_t eh_frame_hdr_len = c->eh_frame_hdr_len;
   Dwarf_Addr eh_addr = c->eh_addr;
   Dwarf_Addr eh_frame_hdr_addr = c->eh_frame_hdr_addr;
+  void *debug_line = c->debug_line;
+  size_t debug_line_len = c->debug_line_len;
 
   dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
                           "debug_frame", debug_frame, debug_len);
@@ -6871,6 +6917,9 @@ dump_unwindsym_cxt (Dwfl_Module *m,
   dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
                           "eh_frame_hdr", eh_frame_hdr, eh_frame_hdr_len);
 
+  dump_unwindsym_cxt_table(c->session, c->output, modname, stpmod_idx, "", 0,
+                          "debug_line", debug_line, debug_line_len);
+
   if (c->session.need_unwind && debug_frame == NULL && eh_frame == NULL)
     {
       // There would be only a small benefit to warning.  A user
@@ -6882,6 +6931,13 @@ dump_unwindsym_cxt (Dwfl_Module *m,
                                  + ", " + dwfl_errmsg (-1));
     }
 
+  if (c->session.need_lines && debug_line == NULL)
+    {
+      if (c->session.verbose > 2)
+        c->session.print_warning ("No debug line data for " + modname + ", " +
+                                  dwfl_errmsg (-1));
+    }
+
   for (unsigned secidx = 0; secidx < c->seclist.size(); secidx++)
     {
       c->output << "static struct _stp_symbol "
@@ -7044,6 +7100,19 @@ dump_unwindsym_cxt (Dwfl_Module *m,
   c->output << ".unwind_hdr_len = 0,\n";
   if (eh_frame != NULL)
     c->output << "#endif /* STP_USE_DWARF_UNWINDER && STP_NEED_UNWIND_DATA*/\n";
+
+  if (debug_line != NULL)
+    {
+      c->output << ".debug_line = "
+               << "_stp_module_" << stpmod_idx << "_debug_line, \n";
+      c->output << ".debug_line_len = " << debug_line_len << ", \n";
+    }
+  else
+    {
+      c->output << ".debug_line = NULL,\n";
+      c->output << ".debug_line_len = 0,\n";
+    }
+
   c->output << ".sections = _stp_module_" << stpmod_idx << "_sections" << ",\n";
   c->output << ".num_sections = sizeof(_stp_module_" << stpmod_idx << "_sections)/"
             << "sizeof(struct _stp_section),\n";
@@ -7160,6 +7229,13 @@ dump_unwindsyms (Dwfl_Module *m,
   if (res == DWARF_CB_OK && c->session.need_unwind)
     res = dump_unwind_tables (m, c, name, base);
 
+  c->debug_line = NULL;
+  c->debug_line_len = 0;
+  if (res == DWARF_CB_OK && c->session.need_lines)
+    // we dont set res = dump_line_tables() because unwindsym stuff should still
+    // get dumped to the output even if gathering debug_line data fails
+    (void) dump_line_tables (m, c, name, base);
+
   /* And finally dump everything collected in the output. */
   if (res == DWARF_CB_OK)
     res = dump_unwindsym_cxt (m, c, name, base);
@@ -7315,6 +7391,8 @@ emit_symbol_data (systemtap_session& s)
                                 0, /* eh_frame_hdr_len */
                                 0, /* eh_addr */
                                 0, /* eh_frame_hdr_addr */
+                                NULL, /* debug_line */
+                                0, /* debug_line_len */
                                 s.unwindsym_modules };
 
   // Micro optimization, mainly to speed up tiny regression tests
@@ -7404,6 +7482,8 @@ self_unwind_declarations(unwindsym_dump_context *ctx)
   ctx->output << ".unwind_hdr_len = 0,\n";
   ctx->output << ".debug_frame = NULL,\n";
   ctx->output << ".debug_frame_len = 0,\n";
+  ctx->output << ".debug_line = NULL,\n";
+  ctx->output << ".debug_line_len = 0,\n";
   ctx->output << "};\n";
 }
 
@@ -7614,6 +7694,9 @@ translate_pass (systemtap_session& s)
       if (s.need_unwind)
        s.op->newline() << "#define STP_NEED_UNWIND_DATA 1";
 
+      if (s.need_lines)
+        s.op->newline() << "#define STP_NEED_LINE_DATA 1";
+
       // Emit the total number of probes (not regarding merged probe handlers)
       s.op->newline() << "#define STP_PROBE_COUNT " << s.probes.size();
 
This page took 0.060916 seconds and 5 git commands to generate.