]> sourceware.org Git - systemtap.git/commitdiff
PR13784 Allow defining a diffent CU source in @var.
authorMark Wielaard <mjw@redhat.com>
Wed, 7 Mar 2012 18:58:12 +0000 (19:58 +0100)
committerMark Wielaard <mjw@redhat.com>
Wed, 7 Mar 2012 19:07:08 +0000 (20:07 +0100)
Add cu_name to struct target_symbol. Set it in parse_target_symbol
to the string after @ in @var("somevar@some/src/file.c"). Make
target_symbol::sym_name() aware of @cu_name postfix (don't return it).
Add dwarf_var_expanding_visitor::getcuscope() which figures out the
CU DIE to use as scope if target_symbol has cu_name part. Extend
global_var.exp test to show new capability.

parse.cxx
staptree.cxx
staptree.h
tapsets.cxx
testsuite/systemtap.base/global_var.exp
testsuite/systemtap.base/global_var.stp

index 745d6133cc3d820c40535d63ec9574f25d704a65..a83b1ce87d8d88758205c77b8bd49cd268c17cc1 100644 (file)
--- a/parse.cxx
+++ b/parse.cxx
@@ -2888,6 +2888,7 @@ target_symbol* parser::parse_target_symbol (const token* t)
       tsym->tok = t;
       tsym->name = t->content;
       tsym->target_name = "";
+      tsym->cu_name = "";
       parse_target_symbol_components(tsym);
       tsym->addressof = addressof;
       return tsym;
@@ -2900,6 +2901,11 @@ target_symbol* parser::parse_target_symbol (const token* t)
       tsym->name = t->content;
       expect_op("(");
       expect_unknown(tok_string, tsym->target_name);
+      size_t found_at = tsym->target_name.find("@");
+      if (found_at != string::npos)
+       tsym->cu_name = tsym->target_name.substr(found_at + 1);
+      else
+       tsym->cu_name = "";
       expect_op(")");
       parse_target_symbol_components(tsym);
       tsym->addressof = addressof;
index 97e49923053ed9402f5d01a3c29ed5fd7713b369..a54f57fa49c03900f36f9beabca4050707d06f13 100644 (file)
@@ -278,7 +278,12 @@ void target_symbol::chain (const semantic_error &er)
 string target_symbol::sym_name ()
 {
   if (name == "@var")
-    return target_name;
+    {
+      if (cu_name == "")
+       return target_name;
+      else
+       return target_name.substr(0, target_name.length() - cu_name.length() - 1);
+    }
   else
     return name.substr(1);
 }
index 959178deffb6153dc503b59784d79e71cfae593a..825979d92cada801552a2df79221f585fca44c31 100644 (file)
@@ -266,6 +266,7 @@ struct target_symbol: public symbol
 
   bool addressof;
   std::string target_name;
+  std::string cu_name;
   std::vector<component> components;
   semantic_error* saved_conversion_error; // hand-made linked list
   target_symbol(): addressof(false), saved_conversion_error (0) {}
index 0e14319ef76adfedca6eecc7e2ee1d68caeb628e..071cdef0a5ec15547aabce18511f75723ec9381c 100644 (file)
@@ -2183,6 +2183,7 @@ struct dwarf_var_expanding_visitor: public var_expanding_visitor
   void visit_cast_op (cast_op* e);
   void visit_entry_op (entry_op* e);
 private:
+  vector<Dwarf_Die>& getcuscope(target_symbol *e);
   vector<Dwarf_Die>& getscopes(target_symbol *e);
 };
 
@@ -3636,10 +3637,47 @@ dwarf_var_expanding_visitor::visit_entry_op (entry_op *e)
   provide (repl);
 }
 
+vector<Dwarf_Die>&
+dwarf_var_expanding_visitor::getcuscope(target_symbol *e)
+{
+  Dwarf_Die *cu = NULL;
+
+  string prefixed_srcfile = string("*/") + e->cu_name;
+
+  Dwarf_Off off = 0;
+  size_t cuhl;
+  Dwarf_Off noff;
+  Dwarf_Off module_bias;
+  Dwarf *dw = dwfl_module_getdwarf(q.dw.module, &module_bias);
+  while (cu == NULL && dwarf_nextcu (dw, off, &noff, &cuhl, NULL, NULL, NULL) == 0)
+    {
+      Dwarf_Die die_mem;
+      Dwarf_Die *die;
+      die = dwarf_offdie (dw, off + cuhl, &die_mem);
+      const char *cu_name = dwarf_diename (die);
+      if (fnmatch(prefixed_srcfile.c_str(), cu_name, 0) == 0)
+       cu = die;
+      off = noff;
+    }
+
+  if (cu == NULL)
+    throw semantic_error ("unable to find CU '" + e->cu_name + "'"
+                         + " while searching for '" + e->target_name + "'",
+                         e->tok);
+
+  vector<Dwarf_Die> *cu_scope = new vector<Dwarf_Die>;
+  Dwarf_Die die_cu = *cu;
+  cu_scope->push_back(die_cu);
+  return *cu_scope;
+}
 
 vector<Dwarf_Die>&
 dwarf_var_expanding_visitor::getscopes(target_symbol *e)
 {
+  // "static globals" can only be found in the top-level CU.
+  if (e->name == "@var" && e->cu_name != "")
+    return this->getcuscope(e);
+
   if (scopes.empty())
     {
       scopes = q.dw.getscopes(scope_die);
index 19d7686622a29111080946f143ddf5b0b93bff33..9785295328ccffc8d92b460efefe299787bef6b3 100644 (file)
@@ -3,9 +3,20 @@ set testpath "$srcdir/$subdir"
 
 # Check each "global" value picks up the right one.
 # See GCC PR51410 and Systemtap PR10622
-set ::result_string {getdistance value: 60
+set ::result_string {main value@main: 42
+getdistance value: 60
+getdistance value@main: 42
+getdistance value@speed: 6
+getdistance value@distance: 60
 getspeed value: 6
-compare value: 42}
+getspeed value@main: 42
+getspeed value@speed: 6
+getspeed value@distance: 60
+compare value: 42
+compare value@main: 42
+compare value@speed: 6
+compare value@distance: 60
+main return value@main: 42}
 
 # Only run on make installcheck and uprobes present.
 if {! [installtest_p]} { untested "$test"; return }
index f650fdcadcc95b74da12fda11090af9e4a347ac1..aca03f585138fe42fced7b5a8bf00c983c5e4abd 100644 (file)
@@ -1,14 +1,34 @@
 probe process.function("getdistance")
 {
   printf("getdistance value: %d\n", $value);
+  printf("getdistance value@main: %d\n", @var("value@global_var_main.c"));
+  printf("getdistance value@speed: %d\n", @var("value@global_var_speed.c"));
+  printf("getdistance value@distance: %d\n", @var("value@global_var_distance.c"));
 }
 
 probe process.function("getspeed")
 {
   printf("getspeed value: %d\n", $value);
+  printf("getspeed value@main: %d\n", @var("value@global_var_main.c"));
+  printf("getspeed value@speed: %d\n", @var("value@global_var_speed.c"));
+  printf("getspeed value@distance: %d\n", @var("value@global_var_distance.c"));
 }
 
 probe process.function("compare_value")
 {
   printf("compare value: %d\n", $value);
-}
\ No newline at end of file
+  printf("compare value@main: %d\n", @var("value@global_var_main.c"));
+  printf("compare value@speed: %d\n", @var("value@global_var_speed.c"));
+  printf("compare value@distance: %d\n", @var("value@global_var_distance.c"));
+}
+
+probe process.function("main")
+{
+  // Global, not local.
+  printf("main value@main: %d\n", @var("value@global_var_main.c"));
+}
+
+probe process.function("main").return
+{
+  printf("main return value@main: %d\n", @var("value@global_var_main.c"));
+}
This page took 0.066514 seconds and 5 git commands to generate.