From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4651 invoked by alias); 31 Jul 2014 00:24:23 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 4638 invoked by uid 89); 31 Jul 2014 00:24:22 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL,BAYES_00,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 X-HELO: lgeamrelo02.lge.com Received: from lgeamrelo02.lge.com (HELO lgeamrelo02.lge.com) (156.147.1.126) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 31 Jul 2014 00:24:20 +0000 Received: from unknown (HELO ls3.156.147.135.180) (10.186.119.203) by 156.147.1.126 with ESMTP; 31 Jul 2014 09:24:09 +0900 X-Original-SENDERIP: 10.186.119.203 X-Original-MAILFROM: hong.gyu.kim@lge.com From: Honggyu Kim To: systemtap@sourceware.org Cc: Honggyu Kim Subject: [PATCH] dwflpp: insert a kprobe into an alternative line Date: Thu, 31 Jul 2014 00:24:00 -0000 Message-Id: <1406766254-23556-1-git-send-email-hong.gyu.kim@lge.com> X-SW-Source: 2014-q3/txt/msg00090.txt.bz2 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 --- 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 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(char const * srcfile, const vector& linenos, @@ -1850,7 +1916,13 @@ dwflpp::iterate_over_srcfile_lines(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