From: Nicholas Nethercote Date: Sun, 20 Mar 2005 23:45:36 +0000 (+0000) Subject: This commit partly cleans up and modularises ExeContext usage. It doesn't X-Git-Tag: svn/VALGRIND_3_0_0~924 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f94393fec07da4950bdd52f0422712f55ae4ccb8;p=thirdparty%2Fvalgrind.git This commit partly cleans up and modularises ExeContext usage. It doesn't look like that much, but it's a good first step; there's more to come. - vg_errcontext.c:gen_suppressions() and vg_symtab2.c:VG_(mini_stack_dump)() had very similar stack-trace-traversing loops. I factored these out into the higher-order function VG_(apply_ExeContext)(). I put this into vg_execontext.c, which is the obvious spot. This is good because before this change we had two functions, neither in vg_execontext.c, which were crawling all over ExeContexts -- they shouldn't have to do that. - Removed VG_(mini_stack_dump)(), which was almost identical to VG_(pp_ExeContext)(). - Removed dead function VG_(get_EIP_from_ExeContext)(). - Replaced a call to VG_(get_ExeContext2)() with the simpler VG_(get_ExeContext)() in vg_scheduler.c. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@3394 --- diff --git a/coregrind/core.h b/coregrind/core.h index c70f9b738e..0d23d2735a 100644 --- a/coregrind/core.h +++ b/coregrind/core.h @@ -891,7 +891,6 @@ extern void VG_(print_ExeContext_stats) ( void ); extern ExeContext* VG_(get_ExeContext2) ( Addr ip, Addr fp, Addr fp_min, Addr fp_max ); - /* --------------------------------------------------------------------- Exports of vg_errcontext.c. ------------------------------------------------------------------ */ @@ -932,7 +931,6 @@ typedef struct _Segment Segment; typedef struct _CodeRedirect CodeRedirect; extern Bool VG_(is_object_file) ( const void *hdr ); -extern void VG_(mini_stack_dump) ( Addr ips[], UInt n_ips ); extern SegInfo * VG_(read_seg_symbols) ( Segment *seg ); extern void VG_(symtab_incref) ( SegInfo * ); extern void VG_(symtab_decref) ( SegInfo *, Addr a ); diff --git a/coregrind/vg_errcontext.c b/coregrind/vg_errcontext.c index 339161cbb6..ce555500aa 100644 --- a/coregrind/vg_errcontext.c +++ b/coregrind/vg_errcontext.c @@ -340,11 +340,22 @@ void construct_error ( Error* err, ThreadId tid, ErrorKind ekind, Addr a, vg_assert( tid < VG_N_THREADS ); } -static void gen_suppression(Error* err) +static void printSuppForIp(UInt n, Addr ip) { - Int i; static UChar buf[M_VG_ERRTXT]; - Bool main_done = False; + + if ( VG_(get_fnname_nodemangle) (ip, buf, M_VG_ERRTXT) ) { + VG_(printf)(" fun:%s\n", buf); + } else if ( VG_(get_objname)(ip, buf+7, M_VG_ERRTXT-7) ) { + VG_(printf)(" obj:%s\n", buf); + } else { + VG_(printf)(" ???:??? " + "# unknown, suppression will not work, sorry\n"); + } +} + +static void gen_suppression(Error* err) +{ ExeContext* ec = VG_(get_error_where)(err); Int stop_at = VG_(clo_backtrace_size); @@ -369,30 +380,8 @@ static void gen_suppression(Error* err) TL_(print_extra_suppression_info)(err); } - /* This loop condensed from VG_(mini_stack_dump)() */ - i = 0; - do { - Addr eip = ec->ips[i]; - if (i > 0) - eip -= MIN_INSTR_SIZE; // point to calling line - if ( VG_(get_fnname_nodemangle) (eip, buf, M_VG_ERRTXT) ) { - // Stop after "main"; if main() is recursive, stop after last main(). - - if ( ! VG_(clo_show_below_main)) { - if (VG_STREQ(buf, "main")) - main_done = True; - else if (main_done) - break; - } - VG_(printf)(" fun:%s\n", buf); - } else if ( VG_(get_objname)(eip, buf, M_VG_ERRTXT) ) { - VG_(printf)(" obj:%s\n", buf); - } else { - VG_(printf)(" ???:??? " - "# unknown, suppression will not work, sorry\n"); - } - i++; - } while (i < stop_at && ec->ips[i] != 0); + // Print stack trace elements + VG_(apply_ExeContext)(printSuppForIp, ec, stop_at); VG_(printf)("}\n"); } diff --git a/coregrind/vg_execontext.c b/coregrind/vg_execontext.c index 1ceccf7c07..24f9959310 100644 --- a/coregrind/vg_execontext.c +++ b/coregrind/vg_execontext.c @@ -109,11 +109,19 @@ void VG_(print_ExeContext_stats) ( void ) } +static void printIpDesc(UInt n, Addr ip) +{ + static UChar buf[M_VG_ERRTXT]; + + VG_(describe_eip)(ip, buf, M_VG_ERRTXT); + VG_(message)(Vg_UserMsg, " %s %s", ( n == 0 ? "at" : "by" ), buf); +} + /* Print an ExeContext. */ -void VG_(pp_ExeContext) ( ExeContext* e ) +void VG_(pp_ExeContext) ( ExeContext* ec ) { - init_ExeContext_storage(); - VG_(mini_stack_dump) ( e->ips, VG_(clo_backtrace_size) ); + vg_assert( VG_(clo_backtrace_size) > 0 ); + VG_(apply_ExeContext)( printIpDesc, ec, VG_(clo_backtrace_size) ); } @@ -157,6 +165,40 @@ Bool VG_(eq_ExeContext) ( VgRes res, ExeContext* e1, ExeContext* e2 ) } +void VG_(apply_ExeContext)( void(*action)(UInt n, Addr ip), + ExeContext* ec, UInt n_ips ) +{ + #define MYBUF_LEN 10 // only needs to be long enough for "main" + + Bool main_done = False; + Char mybuf[MYBUF_LEN]; // ok to stack allocate mybuf[] -- it's tiny + Int i = 0; + + vg_assert(n_ips > 0); + do { + Addr ip = ec->ips[i]; + if (i > 0) + ip -= MIN_INSTR_SIZE; // point to calling line + + // Stop after "main"; if main() is recursive, stop after last main(). + if ( ! VG_(clo_show_below_main)) { + VG_(get_fnname_nodemangle)( ip, mybuf, MYBUF_LEN ); + if ( VG_STREQ("main", mybuf) ) + main_done = True; + else if (main_done) + break; + } + + // Act on the ip + action(i, ip); + + i++; + } while (i < n_ips && ec->ips[i] != 0); + + #undef MYBUF_LEN +} + + /* Take a snapshot of the client's stack, putting the up to 'n_ips' IPs into 'ips'. In order to be thread-safe, we pass in the thread's IP and FP. Returns number of IPs put in 'ips'. */ @@ -365,12 +407,6 @@ UInt VG_(stack_snapshot) ( ThreadId tid, Addr* ips, UInt n_ips ) } -Addr VG_(get_EIP_from_ExeContext) ( ExeContext* e, UInt n ) -{ - if (n > VG_(clo_backtrace_size)) return 0; - return e->ips[n]; -} - Addr VG_(get_EIP) ( ThreadId tid ) { return INSTR_PTR(VG_(threads)[ tid ].arch); diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index c26f5139da..e316eb4cc0 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -168,12 +168,7 @@ void VG_(pp_sched_status) ( void ) for (i = 1; i < VG_N_THREADS; i++) { if (VG_(threads)[i].status == VgTs_Empty) continue; VG_(printf)("\nThread %d: status = %s\n", i, name_of_thread_state(VG_(threads)[i].status)); - VG_(pp_ExeContext)( - VG_(get_ExeContext2)( INSTR_PTR(VG_(threads)[i].arch), - FRAME_PTR(VG_(threads)[i].arch), - STACK_PTR(VG_(threads)[i].arch), - VG_(threads)[i].stack_highest_word) - ); + VG_(pp_ExeContext)( VG_(get_ExeContext)( i ) ); } VG_(printf)("\n"); } @@ -1055,7 +1050,7 @@ void do_client_request ( ThreadId tid ) ExeContext *e = VG_(get_ExeContext)( tid ); int count = VG_(vmessage)( Vg_ClientMsg, (char *)arg[1], (void*)arg[2] ); - VG_(mini_stack_dump)(e->ips, VG_(clo_backtrace_size)); + VG_(pp_ExeContext)(e); SET_CLREQ_RETVAL( tid, count ); break; } diff --git a/coregrind/vg_symtab2.c b/coregrind/vg_symtab2.c index 441d91a471..54e9ebdaed 100644 --- a/coregrind/vg_symtab2.c +++ b/coregrind/vg_symtab2.c @@ -2217,40 +2217,6 @@ Char* VG_(describe_eip)(Addr eip, Char* buf, Int n_buf) #undef APPEND } -/* Print a mini stack dump, showing the current location. */ -void VG_(mini_stack_dump) ( Addr eips[], UInt n_eips ) -{ - UInt i; - static UChar buf[M_VG_ERRTXT]; - Bool main_done = False; - - Int stop_at = n_eips; - - vg_assert(stop_at > 0); - - /* This loop is the basis for the one in VG_(gen_suppressions)(); if you - change this, change it too! */ - i = 0; - do { - Addr eip = eips[i]; - if (i > 0) - eip -= MIN_INSTR_SIZE; // point to calling line - VG_(describe_eip)(eip, buf, M_VG_ERRTXT); - - if ( ! VG_(clo_show_below_main)) { - // Stop after "main"; if main() is recursive, stop after last main(). - if (VG_(strstr)(buf, " main (")) - main_done = True; - else if (main_done) - break; - } - VG_(message)(Vg_UserMsg, " %s %s", ( i == 0 ? "at" : "by" ), buf); - i++; - - } while (i < (UInt)stop_at && eips[i] != 0); -} - - /*------------------------------------------------------------*/ /*--- SegInfo accessor functions ---*/ /*------------------------------------------------------------*/ diff --git a/include/tool.h.base b/include/tool.h.base index e3439466cc..ef7779fdff 100644 --- a/include/tool.h.base +++ b/include/tool.h.base @@ -604,10 +604,11 @@ extern void VG_(pp_ExeContext) ( ExeContext* ); */ extern ExeContext* VG_(get_ExeContext) ( ThreadId tid ); -/* Get the nth IP from the ExeContext. 0 is the IP of the top function, 1 - is its caller, etc. Returns 0 if there isn't one, or if n is greater - than VG_(clo_backtrace_size), set by the --num-callers option. */ -extern Addr VG_(get_EIP_from_ExeContext) ( ExeContext* e, UInt n ); +/* Apply a function to every element in the ExeContext. The parameter 'n' + gives the index of the passed ip. Doesn't go below main() unless + --show-below-main=yes is set. */ +extern void VG_(apply_ExeContext)( void(*action)(UInt n, Addr ip), + ExeContext* ec, UInt n_ips ); /* Just grab the client's IP, as a much smaller and cheaper indication of where they are. Use is basically same as for @@ -621,11 +622,6 @@ extern Addr VG_(get_EIP)( ThreadId tid ); caller, etc. */ extern UInt VG_(stack_snapshot) ( ThreadId tid, Addr* ips, UInt n_ips ); -/* Does the same thing as VG_(pp_ExeContext)(), just with slightly - different input. */ -extern void VG_(mini_stack_dump) ( Addr ips[], UInt n_ips ); - - /*====================================================================*/ /*=== Error reporting ===*/ /*====================================================================*/