public inbox for systemtap@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] dwflpp: insert a kprobe into an alternative line
@ 2014-07-31  0:24 Honggyu Kim
  2014-07-31  5:28 ` BR Chrisman
  0 siblings, 1 reply; 4+ messages in thread
From: Honggyu Kim @ 2014-07-31  0:24 UTC (permalink / raw)
  To: systemtap; +Cc: Honggyu Kim

If a line number is given in 'statement', sometimes the line is not
available in dwarf line number.
Line records in dwarf may not be found for a given line number.
In this case, alternative line numbers were suggested and exited.

Rather than this, this patch makes systemtap insert a kprobe into the
nearest line number that is available in dwarf information.
It is implemented by replacing suggest_alternative_linenos() to
insert_alternative_linenos().

Signed-off-by: Honggyu Kim <hong.gyu.kim@lge.com>
---
 dwflpp.cxx |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dwflpp.h   |    6 +++++
 2 files changed, 78 insertions(+)

diff --git a/dwflpp.cxx b/dwflpp.cxx
index e53d5f2..4808f0b 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1776,6 +1776,72 @@ get_funcs_in_srcfile(base_func_info_map_t& funcs,
   return matching_funcs;
 }
 
+void
+dwflpp::insert_alternative_linenos(char const * srcfile,
+                                    int lineno,
+                                    base_func_info_map_t& funcs,
+                                    void (* callback) (Dwarf_Addr,
+                                                       int, void*),
+                                    void *data)
+{
+  assert(cu);
+  lines_t *cu_lines = get_cu_lines_sorted_by_lineno(srcfile);
+
+  // Look around lineno for linenos with LRs.
+  int lo_try = -1;
+  int hi_try = -1;
+  for (size_t i = 1; i < 6; ++i)
+    {
+      if (lo_try == -1 && functions_have_lineno(funcs, cu_lines, lineno-i))
+        lo_try = lineno - i;
+      if (hi_try == -1 && functions_have_lineno(funcs, cu_lines, lineno+i))
+        hi_try = lineno + i;
+    }
+
+  int new_lineno;
+  if (lo_try > 0 && hi_try > 0)
+    {
+      // pick the nearest line number
+      if (lineno - lo_try < lineno - hi_try)
+        new_lineno = lo_try;
+      else
+        new_lineno = hi_try;
+    }
+  else if (lo_try > 0)
+    {
+      new_lineno = lo_try;
+    }
+  else if (hi_try > 0)
+    {
+      new_lineno = hi_try;
+    }
+  else
+    {
+      stringstream advice;
+      advice << _F("no line records for %s:%d [man error::dwarf]", srcfile, lineno);
+      throw SEMANTIC_ERROR (advice.str());
+    }
+  clog << _F("insert a kprobe at %s:%d (no line record at %s:%d)\n",
+             srcfile, new_lineno, srcfile, lineno);
+
+  // collect lines
+  lines_t matching_lines;
+  collect_lines_for_single_lineno(srcfile, new_lineno, false, /* is_relative */
+                                  funcs, matching_lines);
+  // call back with matching lines
+  assert (!matching_lines.empty());
+  set<Dwarf_Addr> probed_addrs;
+  for (lines_t::iterator line  = matching_lines.begin();
+                         line != matching_lines.end(); ++line)
+    {
+      int near_lineno = DWARF_LINENO(*line);
+      Dwarf_Addr addr = DWARF_LINEADDR(*line);
+      bool is_new_addr = probed_addrs.insert(addr).second;
+      if (is_new_addr)
+        callback(addr, near_lineno, data);
+    }
+}
+
 template<> void
 dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
                                          const vector<int>& linenos,
@@ -1850,7 +1916,13 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
       if (lineno_type == RELATIVE)
         // just pick the first function and make it relative to that
         lineno += current_funcs[0].decl_line;
+#if 0
       suggest_alternative_linenos(srcfile, lineno, current_funcs);
+#else
+      // This function inserts a breakpoint for a near line number
+      // rather than suggesting near line numbers and exiting.
+      insert_alternative_linenos(srcfile, lineno, current_funcs, callback, data);
+#endif
     }
 }
 
diff --git a/dwflpp.h b/dwflpp.h
index 2546acf..dc7dc93 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -559,6 +559,12 @@ private:
   void suggest_alternative_linenos(char const * srcfile,
                                    int lineno,
                                    base_func_info_map_t& funcs);
+  void insert_alternative_linenos(char const * srcfile,
+                                   int lineno,
+                                   base_func_info_map_t& funcs,
+                                   void (* callback) (Dwarf_Addr,
+                                                      int, void*),
+                                   void *data);
 
   static int external_function_cu_callback (Dwarf_Die* cu, external_function_query *efq);
   static int external_function_func_callback (Dwarf_Die* func, external_function_query *efq);
-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] dwflpp: insert a kprobe into an alternative line
  2014-07-31  0:24 [PATCH] dwflpp: insert a kprobe into an alternative line Honggyu Kim
@ 2014-07-31  5:28 ` BR Chrisman
  2014-07-31 12:24   ` Frank Ch. Eigler
  0 siblings, 1 reply; 4+ messages in thread
From: BR Chrisman @ 2014-07-31  5:28 UTC (permalink / raw)
  To: Honggyu Kim; +Cc: systemtap

I don't generally want systemtap to automatically change my requested
probe point.  Maybe implement as an option?

On Wed, Jul 30, 2014 at 5:24 PM, Honggyu Kim <hong.gyu.kim@lge.com> wrote:
> If a line number is given in 'statement', sometimes the line is not
> available in dwarf line number.
> Line records in dwarf may not be found for a given line number.
> In this case, alternative line numbers were suggested and exited.
>
> Rather than this, this patch makes systemtap insert a kprobe into the
> nearest line number that is available in dwarf information.
> It is implemented by replacing suggest_alternative_linenos() to
> insert_alternative_linenos().
>
> Signed-off-by: Honggyu Kim <hong.gyu.kim@lge.com>
> ---
>  dwflpp.cxx |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  dwflpp.h   |    6 +++++
>  2 files changed, 78 insertions(+)
>
> diff --git a/dwflpp.cxx b/dwflpp.cxx
> index e53d5f2..4808f0b 100644
> --- a/dwflpp.cxx
> +++ b/dwflpp.cxx
> @@ -1776,6 +1776,72 @@ get_funcs_in_srcfile(base_func_info_map_t& funcs,
>    return matching_funcs;
>  }
>
> +void
> +dwflpp::insert_alternative_linenos(char const * srcfile,
> +                                    int lineno,
> +                                    base_func_info_map_t& funcs,
> +                                    void (* callback) (Dwarf_Addr,
> +                                                       int, void*),
> +                                    void *data)
> +{
> +  assert(cu);
> +  lines_t *cu_lines = get_cu_lines_sorted_by_lineno(srcfile);
> +
> +  // Look around lineno for linenos with LRs.
> +  int lo_try = -1;
> +  int hi_try = -1;
> +  for (size_t i = 1; i < 6; ++i)
> +    {
> +      if (lo_try == -1 && functions_have_lineno(funcs, cu_lines, lineno-i))
> +        lo_try = lineno - i;
> +      if (hi_try == -1 && functions_have_lineno(funcs, cu_lines, lineno+i))
> +        hi_try = lineno + i;
> +    }
> +
> +  int new_lineno;
> +  if (lo_try > 0 && hi_try > 0)
> +    {
> +      // pick the nearest line number
> +      if (lineno - lo_try < lineno - hi_try)
> +        new_lineno = lo_try;
> +      else
> +        new_lineno = hi_try;
> +    }
> +  else if (lo_try > 0)
> +    {
> +      new_lineno = lo_try;
> +    }
> +  else if (hi_try > 0)
> +    {
> +      new_lineno = hi_try;
> +    }
> +  else
> +    {
> +      stringstream advice;
> +      advice << _F("no line records for %s:%d [man error::dwarf]", srcfile, lineno);
> +      throw SEMANTIC_ERROR (advice.str());
> +    }
> +  clog << _F("insert a kprobe at %s:%d (no line record at %s:%d)\n",
> +             srcfile, new_lineno, srcfile, lineno);
> +
> +  // collect lines
> +  lines_t matching_lines;
> +  collect_lines_for_single_lineno(srcfile, new_lineno, false, /* is_relative */
> +                                  funcs, matching_lines);
> +  // call back with matching lines
> +  assert (!matching_lines.empty());
> +  set<Dwarf_Addr> probed_addrs;
> +  for (lines_t::iterator line  = matching_lines.begin();
> +                         line != matching_lines.end(); ++line)
> +    {
> +      int near_lineno = DWARF_LINENO(*line);
> +      Dwarf_Addr addr = DWARF_LINEADDR(*line);
> +      bool is_new_addr = probed_addrs.insert(addr).second;
> +      if (is_new_addr)
> +        callback(addr, near_lineno, data);
> +    }
> +}
> +
>  template<> void
>  dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
>                                           const vector<int>& linenos,
> @@ -1850,7 +1916,13 @@ dwflpp::iterate_over_srcfile_lines<void>(char const * srcfile,
>        if (lineno_type == RELATIVE)
>          // just pick the first function and make it relative to that
>          lineno += current_funcs[0].decl_line;
> +#if 0
>        suggest_alternative_linenos(srcfile, lineno, current_funcs);
> +#else
> +      // This function inserts a breakpoint for a near line number
> +      // rather than suggesting near line numbers and exiting.
> +      insert_alternative_linenos(srcfile, lineno, current_funcs, callback, data);
> +#endif
>      }
>  }
>
> diff --git a/dwflpp.h b/dwflpp.h
> index 2546acf..dc7dc93 100644
> --- a/dwflpp.h
> +++ b/dwflpp.h
> @@ -559,6 +559,12 @@ private:
>    void suggest_alternative_linenos(char const * srcfile,
>                                     int lineno,
>                                     base_func_info_map_t& funcs);
> +  void insert_alternative_linenos(char const * srcfile,
> +                                   int lineno,
> +                                   base_func_info_map_t& funcs,
> +                                   void (* callback) (Dwarf_Addr,
> +                                                      int, void*),
> +                                   void *data);
>
>    static int external_function_cu_callback (Dwarf_Die* cu, external_function_query *efq);
>    static int external_function_func_callback (Dwarf_Die* func, external_function_query *efq);
> --
> 1.7.9.5
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] dwflpp: insert a kprobe into an alternative line
  2014-07-31  5:28 ` BR Chrisman
@ 2014-07-31 12:24   ` Frank Ch. Eigler
  2014-07-31 13:28     ` Honggyu Kim
  0 siblings, 1 reply; 4+ messages in thread
From: Frank Ch. Eigler @ 2014-07-31 12:24 UTC (permalink / raw)
  To: BR Chrisman; +Cc: Honggyu Kim, systemtap

BR Chrisman <brchrisman@gmail.com> writes:

> I don't generally want systemtap to automatically change my
> requested probe point.  Maybe implement as an option?

It could be enabled by a probe point syntax extension, like
perhaps

        probe FOO.statement(...).nearest { }

or some magic characters jammed into the statement specifier.

- FChE

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: [PATCH] dwflpp: insert a kprobe into an alternative line
  2014-07-31 12:24   ` Frank Ch. Eigler
@ 2014-07-31 13:28     ` Honggyu Kim
  0 siblings, 0 replies; 4+ messages in thread
From: Honggyu Kim @ 2014-07-31 13:28 UTC (permalink / raw)
  To: 'Frank Ch. Eigler', 'BR Chrisman'; +Cc: systemtap

On 07/31/14 9:25 PM, Frank Ch. Eigler wrote:
> BR Chrisman <brchrisman@gmail.com> writes:
> 
> > I don't generally want systemtap to automatically change my requested
> > probe point.  Maybe implement as an option?
> 
> It could be enabled by a probe point syntax extension, like perhaps
> 
>         probe FOO.statement(...).nearest { }
I will implement in this way and submit a new patch again.

> 
> or some magic characters jammed into the statement specifier.
> 
> - FChE

Thanks for the review.

Honggyu

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-31 13:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-31  0:24 [PATCH] dwflpp: insert a kprobe into an alternative line Honggyu Kim
2014-07-31  5:28 ` BR Chrisman
2014-07-31 12:24   ` Frank Ch. Eigler
2014-07-31 13:28     ` Honggyu Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).