]> sourceware.org Git - systemtap.git/commitdiff
2005-09-26 Frank Ch. Eigler <fche@elastic.org>
authorfche <fche>
Tue, 27 Sep 2005 01:06:13 +0000 (01:06 +0000)
committerfche <fche>
Tue, 27 Sep 2005 01:06:13 +0000 (01:06 +0000)
PR 1295.
* tapsets.cxx (resolve_prologue_endings2): Try another heuristic
for end-of-prologue.

2005-09-26  Frank Ch. Eigler  <fche@elastic.org>

PR 1295.
* systemtap.samples/sysopen.*: New test.

ChangeLog
tapsets.cxx

index 6650e1961cc93453950af48e3ff2b5c295c6b05c..f846151c3102d97b3088a6a04c824e400de2c96a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-26  Frank Ch. Eigler  <fche@elastic.org>
+
+       PR 1295.
+       * tapsets.cxx (resolve_prologue_endings2): Try another heuristic
+       for end-of-prologue.
+
 2005-09-22  Graydon Hoare  <graydon@redhat.com>,
        Frank Ch. Eigler  <fche@elastic.org>
 
index dbdef76d8625fa0d825e6deced6d303cbf9d43c3..320be8c80f2bd3eef8d9e13b5b9684e51b34a1ab 100644 (file)
@@ -722,6 +722,77 @@ dwflpp
          choose_next_line = true;
        previous_addr = addr;
       }
+
+    // XXX: free lines[] ?
+  }
+
+
+  void resolve_prologue_endings2 (map<Dwarf_Addr, func_info> & funcs)
+  {
+    // This heuristic attempts to pick the first address that has a
+    // source line distinct from the function declaration's (entrypc's).
+    // This should be the first statement *past* the prologue.
+    assert(module);
+    assert(cu);
+
+    size_t nlines;
+    Dwarf_Lines *lines;
+    Dwarf_Addr last_function_entrypc;
+    int choose_next_line_otherthan = -1;
+
+    // XXX: ideally, there would be a dwarf_getfile(line) routine,
+    // so that we compare not just a line number mismatch, but a
+    // file name mismatch too.
+    //
+    // If the first statement of a function is into some inline
+    // function, we'll be scanning over Dwarf_Line objects that have,
+    // chances are, wildly different lineno's.  If luck turns against
+    // us, and that inline function body happens to be defined in a
+    // different file but at the same line number as its caller, then
+    // we will get slightly messed up.
+
+    dwarf_assert ("dwarf_getsrclines", 
+                 dwarf_getsrclines(cu, &lines, &nlines));    
+
+    for (size_t i = 0; i < nlines; ++i)
+      {
+       Dwarf_Addr addr;
+       Dwarf_Line * line_rec = dwarf_onesrcline(lines, i);
+       dwarf_lineaddr (line_rec, &addr);
+        int this_lineno;
+
+        dwfl_assert ("dwarf_lineno",
+                     dwarf_lineno(line_rec, &this_lineno));
+
+       if (choose_next_line_otherthan >= 0 &&
+            this_lineno != choose_next_line_otherthan)
+         {
+           map<Dwarf_Addr, func_info>::iterator i = 
+              funcs.find (last_function_entrypc);
+           assert (i != funcs.end());
+            Dwarf_Addr addr0 = i->second.prologue_end;
+            if (addr0 != addr)
+              {
+                i->second.prologue_end = addr;
+               if (sess.verbose)
+                 clog << "prologue disagreement: " << i->second.name
+                      << " heur0=" << hex << addr0
+                      << " heur1=" << addr << dec
+                      << endl;
+              }
+           choose_next_line_otherthan = -1;
+         }
+       
+       map<Dwarf_Addr, func_info>::const_iterator i = funcs.find (addr);
+       if (i != funcs.end())
+          {
+            dwfl_assert ("dwarf_lineno",
+                         dwarf_lineno(line_rec, &choose_next_line_otherthan));
+            last_function_entrypc = addr;
+          }
+      }
+
+    // XXX: free lines[] ?
   }
 
 
@@ -1842,6 +1913,7 @@ query_cu (Dwarf_Die * cudie, void * arg)
          // all in a single pass.
          q->dw.iterate_over_functions (query_dwarf_func, q);
          q->dw.resolve_prologue_endings (q->filtered_functions);
+         q->dw.resolve_prologue_endings2 (q->filtered_functions);
 
          if ((q->has_statement_str || q->has_function_str)
              && (q->spec_type == function_file_and_line))
This page took 0.04491 seconds and 5 git commands to generate.