summaryrefslogtreecommitdiffstats
path: root/dwflpp.cxx
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2009-08-20 16:31:55 +0200
committerMark Wielaard <mjw@redhat.com>2009-08-20 16:31:55 +0200
commit30868aad20865f5a949c22ad0a20d1ebe2fd669a (patch)
treebcf328c8a25f40d7991da4015428847ae2be834f /dwflpp.cxx
parentb313f94ed30b4342eb02def7d8e895f5d2af8008 (diff)
downloadsystemtap-steved-30868aad20865f5a949c22ad0a20d1ebe2fd669a.tar.gz
systemtap-steved-30868aad20865f5a949c22ad0a20d1ebe2fd669a.tar.xz
systemtap-steved-30868aad20865f5a949c22ad0a20d1ebe2fd669a.zip
PR10537 process().function().label() should select multiple inlined instances.
This is less useful than one would hope. gcc will often emit a label with a DW_AT_low_pc that is not really in the neighbourhood of where one would expect it when the label is inlined and gcc can proof the label isn't really used in the optimized code. dwflpp::iterate_over_labels will now really iterate recursively through the die, even for dies without a name (like lexical blocks). This means we should now always find the concrete inlined label instances that have a real DW_AT_low_pc and so we don't need the trick to use the line table to get at the actual address. * dwflpp.cxx (iterate_over_labels): Accept dies without a name. Don't handle labels without a name or without a lowpc attribute. * testsuite/systemtap.base/inlinedvars.c (m): Trick gcc into thinking label is always used. (call, call2): Activate. (main): Call call and call2. * testsuite/systemtap.base/inlinedvars.exp: New result_string. Test both unoptimized and optimized (inlined) builds.
Diffstat (limited to 'dwflpp.cxx')
-rw-r--r--dwflpp.cxx29
1 files changed, 9 insertions, 20 deletions
diff --git a/dwflpp.cxx b/dwflpp.cxx
index 6593e5a7..1eada2b7 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -939,17 +939,22 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
{
int tag = dwarf_tag(&die);
const char *name = dwarf_diename (&die);
- if (name == 0)
- continue;
switch (tag)
{
case DW_TAG_label:
+ if (name)
+ break;
+ else
+ continue; // Cannot handle unnamed label.
break;
case DW_TAG_subprogram:
- if (!dwarf_hasattr(&die, DW_AT_declaration))
+ if (!dwarf_hasattr(&die, DW_AT_declaration) && name)
function_name = name;
else
continue;
+ case DW_TAG_inlined_subroutine:
+ if (name)
+ function_name = name;
default:
if (dwarf_haschildren (&die))
iterate_over_labels (&die, sym, symfunction, q, callback);
@@ -975,23 +980,7 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die,
Dwarf_Addr stmt_addr;
if (dwarf_lowpc (&die, &stmt_addr) != 0)
- {
- // There is no lowpc so figure out the address
- // Get the real die for this cu
- Dwarf_Die cudie;
- dwarf_diecu (cu, &cudie, NULL, NULL);
- size_t nlines = 0;
- // Get the line for this label
- Dwarf_Line **aline;
- dwarf_getsrc_file (module_dwarf, file, dline, 0, &aline, &nlines);
- // Get the address
- for (size_t i = 0; i < nlines; i++)
- {
- dwarf_lineaddr (*aline, &stmt_addr);
- if ((dwarf_haspc (&die, stmt_addr)))
- break;
- }
- }
+ continue; // Don't try to be smart. Just drop no addr labels.
Dwarf_Die *scopes;
int nscopes = 0;