From: Florian Krohm Date: Sat, 25 Oct 2014 19:20:38 +0000 (+0000) Subject: Merge r14202 from the BUF_REMOVAL branch to trunk. X-Git-Tag: svn/VALGRIND_3_11_0~884 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=665280aeafb6eea1739f899a604454cdb250e0da;p=thirdparty%2Fvalgrind.git Merge r14202 from the BUF_REMOVAL branch to trunk. This patch changes the interface and behaviour of VG_(demangle) and VG_(maybe_Z_demangle). Instead of copying the demangled name into a fixed sized buffer that is passed in from the caller (HChar *buf, Int n_buf), the demangling functions will now return a pointer to the full-length demangled name (HChar **result). It is the caller's responsiblilty to make a copy if needed. This change in function parameters ripples upward - first: to get_sym_name - then to the convenience wrappers - VG_(get_fnname) - VG_(get_fnname_w_offset) - VG_(get_fnname_if_entry) - VG_(get_fnname_raw) - VG_(get_fnname_no_cxx_demangle) - VG_(get_datasym_and_offset) The changes in foComplete then forces the arguments of - VG_(get_objname) to be changed as well There are some issues regarding the ownership and persistence of character strings to consider. In general, the returned character string is owned by "somebody else" which means the caller must not free it. Also, the caller must not modify the returned string as it possibly points to read only memory. Additionally, the returned string is not necessarily persistent. Here are the scenarios: - the returned string is a demangled function name in which case the memory holding the string will be freed when the demangler is called again. - the returned string hangs off of a DebugInfo structure in which case it will be freed when the DebugInfo is discarded - the returned string hangs off of a segment in the address space manager in which case it may be overwritten when the segment is merged with another segment So the rule of thunb here is: if in doubt strdup the string. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14664 --- diff --git a/cachegrind/cg_main.c b/cachegrind/cg_main.c index 5ba33388b5..71efdea26b 100644 --- a/cachegrind/cg_main.c +++ b/cachegrind/cg_main.c @@ -58,7 +58,6 @@ #define DEBUG_CG 0 #define FILE_LEN VKI_PATH_MAX -#define FN_LEN 256 /*------------------------------------------------------------*/ /*--- Options ---*/ @@ -102,7 +101,7 @@ typedef typedef struct { HChar* file; - HChar* fn; + const HChar* fn; Int line; } CodeLoc; @@ -195,7 +194,7 @@ static Word stringCmp( const void* key, const void* elem ) // Get a permanent string; either pull it out of the string table if it's // been encountered before, or dup it and put it into the string table. -static HChar* get_perm_string(HChar* s) +static HChar* get_perm_string(const HChar* s) { HChar** s_ptr = VG_(OSetGen_Lookup)(stringTable, &s); if (s_ptr) { @@ -213,7 +212,7 @@ static HChar* get_perm_string(HChar* s) /*------------------------------------------------------------*/ static void get_debug_info(Addr instr_addr, HChar file[FILE_LEN], - HChar fn[FN_LEN], UInt* line) + const HChar **fn, UInt* line) { HChar dir[FILE_LEN]; Bool found_dirname; @@ -223,14 +222,14 @@ static void get_debug_info(Addr instr_addr, HChar file[FILE_LEN], dir, FILE_LEN, &found_dirname, line ); - Bool found_fn = VG_(get_fnname)(instr_addr, fn, FN_LEN); + Bool found_fn = VG_(get_fnname)(instr_addr, fn); if (!found_file_line) { VG_(strcpy)(file, "???"); *line = 0; } if (!found_fn) { - VG_(strcpy)(fn, "???"); + *fn = "???"; } if (found_dirname) { @@ -254,12 +253,13 @@ static void get_debug_info(Addr instr_addr, HChar file[FILE_LEN], // Returns a pointer to the line CC, creates a new one if necessary. static LineCC* get_lineCC(Addr origAddr) { - HChar file[FILE_LEN], fn[FN_LEN]; + HChar file[FILE_LEN]; + const HChar *fn; UInt line; CodeLoc loc; LineCC* lineCC; - get_debug_info(origAddr, file, fn, &line); + get_debug_info(origAddr, file, &fn, &line); loc.file = file; loc.fn = fn; @@ -1383,7 +1383,8 @@ static void fprint_CC_table_and_calc_totals(void) Int i, fd; SysRes sres; HChar buf[512]; - HChar *currFile = NULL, *currFn = NULL; + HChar *currFile = NULL; + const HChar *currFn = NULL; LineCC* lineCC; // Setup output filename. Nb: it's important to do this now, ie. as late diff --git a/callgrind/debug.c b/callgrind/debug.c index 8876636103..53dd7fa005 100644 --- a/callgrind/debug.c +++ b/callgrind/debug.c @@ -374,7 +374,7 @@ void CLG_(print_bbcc_cost)(int s, BBCC* bbcc) void CLG_(print_addr)(Addr addr) { HChar fl_buf[FILENAME_LEN]; - HChar fn_buf[FN_NAME_LEN]; + const HChar *fn_buf; const HChar* obj_name; DebugInfo* di; UInt ln, i=0, opos=0; @@ -384,7 +384,7 @@ void CLG_(print_addr)(Addr addr) return; } - CLG_(get_debug_info)(addr, fl_buf, fn_buf, &ln, &di); + CLG_(get_debug_info)(addr, fl_buf, &fn_buf, &ln, &di); if (VG_(strcmp)(fn_buf,"???")==0) VG_(printf)("%#lx", addr); diff --git a/callgrind/fn.c b/callgrind/fn.c index d602ac0e4c..3102b526b5 100644 --- a/callgrind/fn.c +++ b/callgrind/fn.c @@ -330,7 +330,7 @@ file_node* CLG_(get_file_node)(obj_node* curr_obj_node, static void resize_fn_array(void); static __inline__ -fn_node* new_fn_node(HChar fnname[FILENAME_LEN], +fn_node* new_fn_node(const HChar *fnname, file_node* file, fn_node* next) { fn_node* fn = (fn_node*) CLG_MALLOC("cl.fn.nfnnd.1", @@ -374,7 +374,7 @@ fn_node* new_fn_node(HChar fnname[FILENAME_LEN], */ static fn_node* get_fn_node_infile(file_node* curr_file_node, - HChar fnname[FN_NAME_LEN]) + const HChar *fnname) { fn_node* curr_fn_node; UInt fnname_hash; @@ -404,7 +404,7 @@ fn_node* get_fn_node_infile(file_node* curr_file_node, static __inline__ fn_node* get_fn_node_inseg(DebugInfo* di, HChar filename[FILENAME_LEN], - HChar fnname[FN_NAME_LEN]) + const HChar *fnname) { obj_node *obj = CLG_(get_obj_node)(di); file_node *file = CLG_(get_file_node)(obj, filename); @@ -416,7 +416,7 @@ fn_node* get_fn_node_inseg(DebugInfo* di, Bool CLG_(get_debug_info)(Addr instr_addr, HChar file[FILENAME_LEN], - HChar fn_name[FN_NAME_LEN], UInt* line_num, + const HChar **fn_name, UInt* line_num, DebugInfo** pDebugInfo) { Bool found_file_line, found_fn, found_dirname, result = True; @@ -436,8 +436,7 @@ Bool CLG_(get_debug_info)(Addr instr_addr, dir, FILENAME_LEN, &found_dirname, &line); - found_fn = VG_(get_fnname)(instr_addr, - fn_name, FN_NAME_LEN); + found_fn = VG_(get_fnname)(instr_addr, fn_name); if (found_dirname) { // +1 for the '/'. @@ -450,7 +449,7 @@ Bool CLG_(get_debug_info)(Addr instr_addr, if (!found_file_line && !found_fn) { CLG_(stat).no_debug_BBs++; VG_(strcpy)(file, "???"); - VG_(strcpy)(fn_name, "???"); + *fn_name = "???"; if (line_num) *line_num=0; result = False; @@ -460,7 +459,7 @@ Bool CLG_(get_debug_info)(Addr instr_addr, } else if ( found_file_line && !found_fn) { CLG_(stat).file_line_debug_BBs++; - VG_(strcpy)(fn_name, "???"); + *fn_name = "???"; if (line_num) *line_num=line; } else /*(!found_file_line && found_fn)*/ { @@ -474,7 +473,7 @@ Bool CLG_(get_debug_info)(Addr instr_addr, !pDebugInfo ? "-" : (*pDebugInfo) ? VG_(DebugInfo_get_filename)(*pDebugInfo) : "(None)", - fn_name); + *fn_name); return result; } @@ -488,7 +487,8 @@ static BB* exit_bb = 0; */ fn_node* CLG_(get_fn_node)(BB* bb) { - HChar filename[FILENAME_LEN], fnname[FN_NAME_LEN]; + HChar filename[FILENAME_LEN]; + const HChar *fnname; DebugInfo* di; UInt line_num; fn_node* fn; @@ -502,26 +502,27 @@ fn_node* CLG_(get_fn_node)(BB* bb) * the BB according to debug information */ CLG_(get_debug_info)(bb_addr(bb), - filename, fnname, &line_num, &di); + filename, &fnname, &line_num, &di); if (0 == VG_(strcmp)(fnname, "???")) { int p; - + static HChar buf[32]; // for sure large enough /* Use address as found in library */ if (sizeof(Addr) == 4) - p = VG_(sprintf)(fnname, "%#08lx", bb->offset); + p = VG_(sprintf)(buf, "%#08lx", bb->offset); else // 64bit address - p = VG_(sprintf)(fnname, "%#016lx", bb->offset); + p = VG_(sprintf)(buf, "%#016lx", bb->offset); - VG_(sprintf)(fnname+p, "%s", + VG_(sprintf)(buf + p, "%s", (bb->sect_kind == Vg_SectData) ? " [Data]" : (bb->sect_kind == Vg_SectBSS) ? " [BSS]" : (bb->sect_kind == Vg_SectGOT) ? " [GOT]" : (bb->sect_kind == Vg_SectPLT) ? " [PLT]" : ""); + fnname = buf; } else { - if (VG_(get_fnname_if_entry)(bb_addr(bb), fnname, FN_NAME_LEN)) + if (VG_(get_fnname_if_entry)(bb_addr(bb), &fnname)) bb->is_entry = 1; } @@ -532,7 +533,7 @@ fn_node* CLG_(get_fn_node)(BB* bb) if (0 == VG_(strcmp)(fnname, "vgPlain___libc_freeres_wrapper") && exit_bb) { CLG_(get_debug_info)(bb_addr(exit_bb), - filename, fnname, &line_num, &di); + filename, &fnname, &line_num, &di); CLG_DEBUG(1, "__libc_freeres_wrapper renamed to _exit\n"); } @@ -543,7 +544,7 @@ fn_node* CLG_(get_fn_node)(BB* bb) (bb_addr(bb) >= runtime_resolve_addr) && (bb_addr(bb) < runtime_resolve_addr + runtime_resolve_length)) { /* BB in runtime_resolve found by code check; use this name */ - VG_(sprintf)(fnname, "_dl_runtime_resolve"); + fnname = "_dl_runtime_resolve"; } /* get fn_node struct for this function */ diff --git a/callgrind/global.h b/callgrind/global.h index ff423b4bc5..a32ba55748 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -691,7 +691,7 @@ void CLG_(init_eventsets)(void); /* from main.c */ Bool CLG_(get_debug_info)(Addr, HChar filename[FILENAME_LEN], - HChar fn_name[FN_NAME_LEN], UInt*, DebugInfo**); + const HChar **fn_name, UInt*, DebugInfo**); void CLG_(collectBlockInfo)(IRSB* bbIn, UInt*, UInt*, Bool*); void CLG_(set_instrument_state)(const HChar*,Bool); void CLG_(dump_profile)(const HChar* trigger,Bool only_current_thread); diff --git a/coregrind/m_addrinfo.c b/coregrind/m_addrinfo.c index 95ec0fe608..803bb3a9d4 100644 --- a/coregrind/m_addrinfo.c +++ b/coregrind/m_addrinfo.c @@ -124,15 +124,12 @@ void VG_(describe_addr) ( Addr a, /*OUT*/AddrInfo* ai ) } /* -- Have a look at the low level data symbols - perhaps it's in there. -- */ - VG_(memset)( &ai->Addr.DataSym.name, - 0, sizeof(ai->Addr.DataSym.name)); + const HChar *name; if (VG_(get_datasym_and_offset)( - a, &ai->Addr.DataSym.name[0], - sizeof(ai->Addr.DataSym.name)-1, + a, &name, &ai->Addr.DataSym.offset )) { + ai->Addr.DataSym.name = VG_(strdup)("mc.da.dsname", name); ai->tag = Addr_DataSym; - vg_assert( ai->Addr.DataSym.name - [ sizeof(ai->Addr.DataSym.name)-1 ] == 0); return; } /* -- Perhaps it's on a thread's stack? -- */ @@ -293,6 +290,7 @@ void VG_(clear_addrinfo) ( AddrInfo* ai) break; case Addr_DataSym: + VG_(free)(ai->Addr.DataSym.name); break; case Addr_Variable: @@ -384,7 +382,7 @@ static void pp_addrinfo_WRK ( Addr a, const AddrInfo* ai, Bool mc, xpost ); if (ai->Addr.Stack.frameNo != -1 && ai->Addr.Stack.IP != 0) { #define FLEN 256 - HChar fn[FLEN]; + const HChar *fn; Bool hasfn; HChar file[FLEN]; Bool hasfile; @@ -392,7 +390,6 @@ static void pp_addrinfo_WRK ( Addr a, const AddrInfo* ai, Bool mc, Bool haslinenum; PtrdiffT offset; - hasfn = VG_(get_fnname)(ai->Addr.Stack.IP, fn, FLEN); if (VG_(get_inst_offset_in_function)( ai->Addr.Stack.IP, &offset)) haslinenum = VG_(get_linenum) (ai->Addr.Stack.IP - offset, @@ -408,6 +405,8 @@ static void pp_addrinfo_WRK ( Addr a, const AddrInfo* ai, Bool mc, FLEN - VG_(strlen)(file) - 1); } + hasfn = VG_(get_fnname)(ai->Addr.Stack.IP, &fn); + if (hasfn || hasfile) VG_(emit)( "%sin frame #%d, created by %s (%s)%s\n", xpre, diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index 33bfe924e0..dbcee080ed 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1729,11 +1729,18 @@ static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, C++ demangling, regardless of VG_(clo_demangle) -- probably because the call has come from VG_(get_fnname_raw)(). findText indicates whether we're looking for a text symbol or a data symbol - -- caller must choose one kind or the other. */ + -- caller must choose one kind or the other. + Note: the string returned in *BUF is persistent as long as + (1) the DebugInfo it belongs to is not discarded + (2) the segment containing the address is not merged with another segment + (3) the demangler is not invoked again + In other words: if in doubt, save it away. + Also, the returned string is owned by "somebody else". Callers must + not free it or modify it. */ static Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, Bool do_below_main_renaming, - Addr a, HChar* buf, Int nbuf, + Addr a, const HChar** buf, Bool match_anywhere_in_sym, Bool show_offset, Bool findText, /*OUT*/PtrdiffT* offsetP ) { @@ -1742,12 +1749,14 @@ Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, PtrdiffT offset; search_all_symtabs ( a, &di, &sno, match_anywhere_in_sym, findText ); - if (di == NULL) + if (di == NULL) { + *buf = ""; return False; + } vg_assert(di->symtab[sno].pri_name); VG_(demangle) ( do_cxx_demangling, do_z_demangling, - di->symtab[sno].pri_name, buf, nbuf ); + di->symtab[sno].pri_name, buf ); /* Do the below-main hack */ // To reduce the endless nuisance of multiple different names @@ -1755,31 +1764,31 @@ Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, // known incarnations of said into a single name, "(below main)", if // --show-below-main=yes. if ( do_below_main_renaming && ! VG_(clo_show_below_main) && - Vg_FnNameBelowMain == VG_(get_fnname_kind)(buf) ) + Vg_FnNameBelowMain == VG_(get_fnname_kind)(*buf) ) { - VG_(strncpy_safely)(buf, "(below main)", nbuf); + *buf = "(below main)"; } offset = a - di->symtab[sno].avmas.main; if (offsetP) *offsetP = offset; if (show_offset && offset != 0) { - HChar buf2[12]; - HChar* symend = buf + VG_(strlen)(buf); - HChar* end = buf + nbuf; - Int len; - - len = VG_(sprintf)(buf2, "%c%ld", - offset < 0 ? '-' : '+', - offset < 0 ? -offset : offset); - vg_assert(len < (Int)sizeof(buf2)); - - if (len < (end - symend)) { - HChar *cp = buf2; - VG_(memcpy)(symend, cp, len+1); + static HChar *bufwo; // buf with offset + static SizeT bufwo_szB; + SizeT need, len; + + len = VG_(strlen)(*buf); + need = len + 1 + 19 + 1; + if (need > bufwo_szB) { + bufwo = ML_(dinfo_realloc)("get_sym_size", bufwo, need); + bufwo_szB = need; } - } - buf[nbuf-1] = 0; /* paranoia */ + VG_(strcpy)(bufwo, *buf); + VG_(sprintf)(bufwo + len, "%c%ld", + offset < 0 ? '-' : '+', + offset < 0 ? -offset : offset); + *buf = bufwo; + } return True; } @@ -1806,12 +1815,14 @@ Addr VG_(get_tocptr) ( Addr guest_code_addr ) } /* This is available to tools... always demangle C++ names, - match anywhere in function, but don't show offsets. */ -Bool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf ) + match anywhere in function, but don't show offsets. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ +Bool VG_(get_fnname) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, - a, buf, nbuf, + a, buf, /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text syms only*/True, @@ -1819,12 +1830,14 @@ Bool VG_(get_fnname) ( Addr a, HChar* buf, Int nbuf ) } /* This is available to tools... always demangle C++ names, - match anywhere in function, and show offset if nonzero. */ -Bool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf ) + match anywhere in function, and show offset if nonzero. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ +Bool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, - a, buf, nbuf, + a, buf, /*match_anywhere_in_fun*/True, /*show offset?*/True, /*text syms only*/True, @@ -1833,12 +1846,14 @@ Bool VG_(get_fnname_w_offset) ( Addr a, HChar* buf, Int nbuf ) /* This is available to tools... always demangle C++ names, only succeed if 'a' matches first instruction of function, - and don't show offsets. */ -Bool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf ) + and don't show offsets. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ +Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, /*below-main-renaming*/True, - a, buf, nbuf, + a, buf, /*match_anywhere_in_fun*/False, /*show offset?*/False, /*text syms only*/True, @@ -1847,12 +1862,14 @@ Bool VG_(get_fnname_if_entry) ( Addr a, HChar* buf, Int nbuf ) /* This is only available to core... don't C++-demangle, don't Z-demangle, don't rename below-main, match anywhere in function, and don't show - offsets. */ -Bool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf ) + offsets. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ +Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, - a, buf, nbuf, + a, buf, /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text syms only*/True, @@ -1861,15 +1878,17 @@ Bool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf ) /* This is only available to core... don't demangle C++ names, but do do Z-demangling and below-main-renaming, match anywhere in function, and - don't show offsets. */ -Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, - InlIPCursor* iipc ) + don't show offsets. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ +Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf, + const InlIPCursor* iipc ) { if (is_bottom(iipc)) { // At the bottom (towards main), we describe the fn at eip. return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/True, /*below-main-renaming*/True, - a, buf, nbuf, + a, buf, /*match_anywhere_in_fun*/True, /*show offset?*/False, /*text syms only*/True, @@ -1880,7 +1899,7 @@ Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, : NULL; vg_assert (next_inl); // The function we are in is called by next_inl. - VG_(snprintf)(buf, nbuf, "%s", next_inl->inlinedfn); + *buf = next_inl->inlinedfn; return True; } } @@ -1891,17 +1910,17 @@ Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, Bool VG_(get_inst_offset_in_function)( Addr a, /*OUT*/PtrdiffT* offset ) { - HChar fnname[64]; + const HChar *fnname; return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, - a, fnname, 64, + a, &fnname, /*match_anywhere_in_sym*/True, /*show offset?*/False, /*text syms only*/True, offset ); } -Vg_FnNameKind VG_(get_fnname_kind) ( HChar* name ) +Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name ) { if (VG_STREQ("main", name)) { return Vg_FnNameMain; @@ -1926,14 +1945,12 @@ Vg_FnNameKind VG_(get_fnname_kind) ( HChar* name ) Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) { - // We don't need a big buffer; all the special names are small. - #define BUFLEN 50 - HChar buf[50]; + const HChar *buf; // We don't demangle, because it's faster not to, and the special names // we're looking for won't be mangled. - if (VG_(get_fnname_raw) ( ip, buf, BUFLEN )) { - buf[BUFLEN-1] = '\0'; // paranoia + if (VG_(get_fnname_raw) ( ip, &buf )) { + return VG_(get_fnname_kind)(buf); } else { return Vg_FnNameNormal; // Don't know the name, treat it as normal. @@ -1941,37 +1958,35 @@ Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) } /* Looks up data_addr in the collection of data symbols, and if found - puts its name (or as much as will fit) into dname[0 .. n_dname-1], - which is guaranteed to be zero terminated. Also data_addr's offset - from the symbol start is put into *offset. */ + puts a pointer to its name into dname. The name is zero terminated. + Also data_addr's offset from the symbol start is put into *offset. + NOTE: See important comment about the persistence and memory ownership + of the return string at function get_sym_name */ Bool VG_(get_datasym_and_offset)( Addr data_addr, - /*OUT*/HChar* dname, Int n_dname, + /*OUT*/const HChar** dname, /*OUT*/PtrdiffT* offset ) { - Bool ok; - vg_assert(n_dname > 1); - ok = get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, + return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, /*below-main-renaming*/False, - data_addr, dname, n_dname, + data_addr, dname, /*match_anywhere_in_sym*/True, /*show offset?*/False, /*data syms only please*/False, offset ); - if (!ok) - return False; - dname[n_dname-1] = 0; - return True; } /* Map a code address to the name of a shared object file or the - executable. Returns False if no idea; otherwise True. Doesn't - require debug info. Caller supplies buf and nbuf. */ -Bool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf ) + executable. Returns False if no idea; otherwise True. + Note: the string returned in *BUF is persistent as long as + (1) the DebugInfo it belongs to is not discarded + (2) the segment containing the address is not merged with another segment +*/ +Bool VG_(get_objname) ( Addr a, const HChar** buf ) { DebugInfo* di; const NSegment *seg; const HChar* filename; - vg_assert(nbuf > 0); + /* Look in the debugInfo_list to find the name. In most cases we expect this to produce a result. */ for (di = debugInfo_list; di != NULL; di = di->next) { @@ -1979,8 +1994,7 @@ Bool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf ) && di->text_size > 0 && di->text_avma <= a && a < di->text_avma + di->text_size) { - VG_(strncpy_safely)(buf, di->fsm.filename, nbuf); - buf[nbuf-1] = 0; + *buf = di->fsm.filename; return True; } } @@ -1991,7 +2005,7 @@ Bool VG_(get_objname) ( Addr a, HChar* buf, Int nbuf ) when running programs under wine. */ if ( (seg = VG_(am_find_nsegment(a))) != NULL && (filename = VG_(am_get_filename)(seg)) != NULL ) { - VG_(strncpy_safely)(buf, filename, nbuf); + *buf = filename; return True; } return False; @@ -2220,11 +2234,11 @@ HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) vg_assert (!iipc || iipc->eip == eip); - static HChar buf_fn[BUF_LEN]; - static HChar buf_obj[BUF_LEN]; + static const HChar *buf_fn; + static const HChar *buf_obj; static HChar buf_srcloc[BUF_LEN]; static HChar buf_dirname[BUF_LEN]; - buf_fn[0] = buf_obj[0] = buf_srcloc[0] = buf_dirname[0] = 0; + buf_srcloc[0] = buf_dirname[0] = 0; Bool know_dirinfo = False; Bool know_fnname; @@ -2234,15 +2248,15 @@ HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) if (is_bottom(iipc)) { // At the bottom (towards main), we describe the fn at eip. know_fnname = VG_(clo_sym_offsets) - ? VG_(get_fnname_w_offset) (eip, buf_fn, BUF_LEN) - : VG_(get_fnname) (eip, buf_fn, BUF_LEN); + ? VG_(get_fnname_w_offset) (eip, &buf_fn) + : VG_(get_fnname) (eip, &buf_fn); } else { const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0 ? & iipc->di->inltab[iipc->next_inltab] : NULL; vg_assert (next_inl); // The function we are in is called by next_inl. - VG_(snprintf)(buf_fn, BUF_LEN, "%s", next_inl->inlinedfn); + buf_fn = next_inl->inlinedfn; // FIXME: IS THIS SAFE ?? know_fnname = True; // INLINED???? @@ -2253,7 +2267,7 @@ HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) // ??? Currently never showing an offset. } - know_objname = VG_(get_objname)(eip, buf_obj, BUF_LEN); + know_objname = VG_(get_objname)(eip, &buf_obj); if (is_top(iipc)) { // The source for the highest level is in the loctab entry. @@ -2285,10 +2299,7 @@ HChar* VG_(describe_IP)(Addr eip, HChar* buf, Int n_buf, InlIPCursor *iipc) lineno = cur_inl->lineno; know_srcloc = True; } - - buf_fn [ sizeof(buf_fn)-1 ] = 0; - buf_obj [ sizeof(buf_obj)-1 ] = 0; buf_srcloc [ sizeof(buf_srcloc)-1 ] = 0; buf_dirname[ sizeof(buf_dirname)-1 ] = 0; diff --git a/coregrind/m_debuginfo/misc.c b/coregrind/m_debuginfo/misc.c index 25ea58ea8d..57c91c6dd6 100644 --- a/coregrind/m_debuginfo/misc.c +++ b/coregrind/m_debuginfo/misc.c @@ -68,6 +68,12 @@ void* ML_(dinfo_memdup) ( const HChar* cc, const void* str, SizeT nStr ) { return dst; } +void* ML_(dinfo_realloc) ( const HChar* cc, void* ptr, SizeT new_size ) { + void* dst = VG_(arena_realloc)( VG_AR_DINFO, cc, ptr, new_size ); + vg_assert(dst); + return dst; +} + static inline Bool host_is_little_endian ( void ) { UInt x = 0x76543210; UChar* p = (UChar*)(&x); diff --git a/coregrind/m_debuginfo/priv_misc.h b/coregrind/m_debuginfo/priv_misc.h index 0828290c14..7ca7614a46 100644 --- a/coregrind/m_debuginfo/priv_misc.h +++ b/coregrind/m_debuginfo/priv_misc.h @@ -44,6 +44,7 @@ void* ML_(dinfo_zalloc)( const HChar* cc, SizeT szB ); void ML_(dinfo_free)( void* v ); HChar* ML_(dinfo_strdup)( const HChar* cc, const HChar* str ); void* ML_(dinfo_memdup)( const HChar* cc, const void* str, SizeT nStr ); +void* ML_(dinfo_realloc) ( const HChar* cc, void* ptr, SizeT new_size ); void ML_(dinfo_shrink_block)( void* ptr, SizeT szB ); /* Extract (possibly unaligned) data of various sizes from a buffer. */ diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c index 8a22ca253f..5ae2a5df1e 100644 --- a/coregrind/m_debuglog.c +++ b/coregrind/m_debuglog.c @@ -890,20 +890,18 @@ VG_(debugLog_vprintf) ( } // case 'y': { /* %y - print symbol */ -// HChar buf[100]; -// HChar *cp = buf; // Addr a = va_arg(vargs, Addr); // -// if (flags & VG_MSG_PAREN) -// *cp++ = '('; -// if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { -// if (flags & VG_MSG_PAREN) { -// cp += VG_(strlen)(cp); -// *cp++ = ')'; -// *cp = '\0'; +// HChar *name; +// if (VG_(get_fnname_w_offset)(a, &name)) { +// HChar buf[1 + VG_strlen(name) + 1 + 1]; +// if (flags & VG_MSG_PAREN) { +// VG_(sprintf)(str, "(%s)", name): +// } else { +// VG_(sprintf)(str, "%s", name): // } -// ret += myvprintf_str(send, send_arg2, flags, width, buf, 0); -// } +// ret += myvprintf_str(send, flags, width, buf, 0); +// } // break; // } default: diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c index 385ee8dd79..1054c147bd 100644 --- a/coregrind/m_demangle/demangle.c +++ b/coregrind/m_demangle/demangle.c @@ -83,36 +83,45 @@ /* This is the main, standard demangler entry point. */ +/* Upon return, *RESULT will point to the demangled name. + The memory buffer that holds the demangled name is allocated on the + heap and will be deallocated in the next invocation. Conceptually, + that buffer is owned by VG_(demangle). That means two things: + (1) Users of VG_(demangle) must not free that buffer. + (2) If the demangled name needs to be stashed away for later use, + the contents of the buffer needs to be copied. It is not sufficient + to just store the pointer as it will point to deallocated memory + after the next VG_(demangle) invocation. */ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, - const HChar* orig, HChar* result, Int result_size ) + /* IN */ const HChar *orig, + /* OUT */ const HChar **result ) { -# define N_ZBUF 4096 - HChar* demangled = NULL; - HChar z_demangled[N_ZBUF]; - /* Possibly undo (2) */ /* Z-Demangling was requested. The fastest way to see if it's a Z-mangled name is just to attempt to Z-demangle it (with NULL for the soname buffer, since we're not interested in that). */ if (do_z_demangling) { - if (VG_(maybe_Z_demangle)( orig, NULL,0,/*soname*/ - z_demangled, N_ZBUF, NULL, NULL, NULL )) { + const HChar *z_demangled; + + if (VG_(maybe_Z_demangle)( orig, NULL, /*soname*/ + &z_demangled, NULL, NULL, NULL )) { orig = z_demangled; } } /* Possibly undo (1) */ if (do_cxx_demangling && VG_(clo_demangle)) { + static HChar* demangled = NULL; + + /* Free up previously demangled name */ + if (demangled) VG_(arena_free) (VG_AR_DEMANGLE, demangled); + demangled = ML_(cplus_demangle) ( orig, DMGL_ANSI | DMGL_PARAMS ); + + *result = (demangled == NULL) ? orig : demangled; } else { - demangled = NULL; - } - if (demangled) { - VG_(strncpy_safely)(result, demangled, result_size); - VG_(arena_free) (VG_AR_DEMANGLE, demangled); - } else { - VG_(strncpy_safely)(result, orig, result_size); + *result = orig; } // 13 Mar 2005: We used to check here that the demangler wasn't leaking @@ -120,7 +129,6 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, // very rarely (ie. I've heard of it twice in 3 years), the demangler // does leak. But, we can't do much about it, and it's not a disaster, // so we just let it slide without aborting or telling the user. -# undef N_ZBUF } @@ -141,38 +149,48 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, function name part. */ Bool VG_(maybe_Z_demangle) ( const HChar* sym, - /*OUT*/HChar* so, Int soLen, - /*OUT*/HChar* fn, Int fnLen, + /*OUT*/const HChar** so, + /*OUT*/const HChar** fn, /*OUT*/Bool* isWrap, /*OUT*/Int* eclassTag, /*OUT*/Int* eclassPrio ) { + static HChar *sobuf; + static HChar *fnbuf; + static SizeT buf_len = 0; + + /* The length of the name after undoing Z-encoding is always smaller + than the mangled name. Making the soname and fnname buffers as large + as the demangled name is therefore always safe and overflow can never + occur. */ + SizeT len = VG_(strlen)(sym) + 1; + + if (buf_len < len) { + sobuf = VG_(arena_realloc)(VG_AR_DEMANGLE, "Z-demangle", sobuf, len); + fnbuf = VG_(arena_realloc)(VG_AR_DEMANGLE, "Z-demangle", fnbuf, len); + buf_len = len; + } + sobuf[0] = fnbuf[0] = '\0'; + + if (so) + *so = sobuf; + *fn = fnbuf; + # define EMITSO(ch) \ do { \ if (so) { \ - if (soi >= soLen) { \ - so[soLen-1] = 0; oflow = True; \ - } else { \ - so[soi++] = ch; so[soi] = 0; \ - } \ + sobuf[soi++] = ch; sobuf[soi] = 0; \ } \ } while (0) # define EMITFN(ch) \ do { \ - if (fni >= fnLen) { \ - fn[fnLen-1] = 0; oflow = True; \ - } else { \ - fn[fni++] = ch; fn[fni] = 0; \ - } \ + fnbuf[fni++] = ch; fnbuf[fni] = 0; \ } while (0) - Bool error, oflow, valid, fn_is_encoded, is_VG_Z_prefixed; + Bool error, valid, fn_is_encoded, is_VG_Z_prefixed; Int soi, fni, i; - vg_assert(soLen > 0 || (soLen == 0 && so == NULL)); - vg_assert(fnLen > 0); error = False; - oflow = False; soi = 0; fni = 0; @@ -329,12 +347,6 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym, "m_demangle: error Z-demangling: %s\n", sym); return False; } - if (oflow) { - /* It didn't fit. Give up. */ - VG_(message)(Vg_UserMsg, - "m_demangle: oflow Z-demangling: %s\n", sym); - return False; - } return True; } diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c index 2f02c8145a..7a801f59bd 100644 --- a/coregrind/m_errormgr.c +++ b/coregrind/m_errormgr.c @@ -325,13 +325,13 @@ static Bool eq_Error ( VgRes res, const Error* e1, const Error* e2 ) static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque) { - static HChar buf[ERRTXT_LEN]; + const HChar *buf; InlIPCursor* iipc = VG_(new_IIPC)(ip); do { - if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN, iipc) ) { + if ( VG_(get_fnname_no_cxx_demangle) (ip, &buf, iipc) ) { VG_(printf_xml)(" %pS \n", buf); } else - if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) { + if ( VG_(get_objname)(ip, &buf) ) { VG_(printf_xml)(" %pS \n", buf); } else { VG_(printf_xml)(" * \n"); @@ -342,14 +342,14 @@ static void printSuppForIp_XML(UInt n, Addr ip, void* uu_opaque) static void printSuppForIp_nonXML(UInt n, Addr ip, void* textV) { - static HChar buf[ERRTXT_LEN]; + const HChar *buf; XArray* /* of HChar */ text = (XArray*)textV; InlIPCursor* iipc = VG_(new_IIPC)(ip); do { - if ( VG_(get_fnname_no_cxx_demangle) (ip, buf, ERRTXT_LEN, iipc) ) { + if ( VG_(get_fnname_no_cxx_demangle) (ip, &buf, iipc) ) { VG_(xaprintf)(text, " fun:%s\n", buf); } else - if ( VG_(get_objname)(ip, buf, ERRTXT_LEN) ) { + if ( VG_(get_objname)(ip, &buf) ) { VG_(xaprintf)(text, " obj:%s\n", buf); } else { VG_(xaprintf)(text, " obj:*\n"); @@ -1619,17 +1619,19 @@ static void clearIPtoFunOrObjCompleter ( const Supp *su, if (ip2fo->names) VG_(free)(ip2fo->names); } -/* Grow ip2fo->names to ensure we have ERRTXT_LEN characters available +/* Grow ip2fo->names to ensure we have NEEDED characters available in ip2fo->names and returns a pointer to the first free char. */ -static HChar* grow_names(IPtoFunOrObjCompleter* ip2fo) +static HChar* grow_names(IPtoFunOrObjCompleter* ip2fo, SizeT needed) { if (ip2fo->names_szB - < ip2fo->names_free + ERRTXT_LEN) { + < ip2fo->names_free + needed) { + if (needed < ERRTXT_LEN) needed = ERRTXT_LEN; + ip2fo->names = VG_(realloc)("foc_names", ip2fo->names, - ip2fo->names_szB + ERRTXT_LEN); - ip2fo->names_szB += ERRTXT_LEN; + ip2fo->names_szB + needed); + ip2fo->names_szB += needed; } return ip2fo->names + ip2fo->names_free; } @@ -1655,7 +1657,8 @@ static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo, // Complete Fun name or Obj name for IP if not yet done. if ((*offsets)[ixInput] == -1) { - HChar* caller_name = grow_names(ip2fo); + const HChar* caller; + (*offsets)[ixInput] = ip2fo->names_free; if (DEBUG_ERRORMGR) VG_(printf)("marking %s ixInput %d offset %d\n", needFun ? "fun" : "obj", @@ -1671,9 +1674,9 @@ static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo, // "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the // two of them need to be made to match. if (!VG_(get_fnname_no_cxx_demangle)(ip2fo->ips[ixInput], - caller_name, ERRTXT_LEN, + &caller, NULL)) - VG_(strcpy)(caller_name, "???"); + caller = "???"; } else { /* Get the object name into 'caller_name', or "???" if unknown. */ @@ -1691,8 +1694,8 @@ static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo, last_expand_pos_ips is the last offset in fun/obj where ips[pos_ips] has been expanded. */ - if (!VG_(get_objname)(ip2fo->ips[pos_ips], caller_name, ERRTXT_LEN)) - VG_(strcpy)(caller_name, "???"); + if (!VG_(get_objname)(ip2fo->ips[pos_ips], &caller)) + caller = "???"; // Have all inlined calls pointing at this object name for (i = last_expand_pos_ips - ip2fo->n_offsets_per_ip[pos_ips] + 1; @@ -1704,7 +1707,10 @@ static HChar* foComplete(IPtoFunOrObjCompleter* ip2fo, i, ip2fo->names_free); } } - ip2fo->names_free += VG_(strlen)(caller_name) + 1; + SizeT caller_len = VG_(strlen)(caller); + HChar* caller_name = grow_names(ip2fo, caller_len + 1); + VG_(strcpy)(caller_name, caller); + ip2fo->names_free += caller_len + 1; if (DEBUG_ERRORMGR) pp_ip2fo(ip2fo); } @@ -1764,14 +1770,17 @@ static void expandInput (IPtoFunOrObjCompleter* ip2fo, UWord ixInput ) // However, computing this is mostly the same as finding // the function name. So, let's directly complete the function name. do { - HChar* caller_name = grow_names(ip2fo); + const HChar *caller; grow_offsets(ip2fo, ip2fo->n_expanded+1); ip2fo->fun_offsets[ip2fo->n_expanded] = ip2fo->names_free; if (!VG_(get_fnname_no_cxx_demangle)(IP, - caller_name, ERRTXT_LEN, + &caller, iipc)) - VG_(strcpy)(caller_name, "???"); - ip2fo->names_free += VG_(strlen)(caller_name) + 1; + caller = "???"; + SizeT caller_len = VG_(strlen)(caller); + HChar* caller_name = grow_names(ip2fo, caller_len + 1); + VG_(strcpy)(caller_name, caller); + ip2fo->names_free += caller_len + 1; ip2fo->n_expanded++; ip2fo->n_offsets_per_ip[ip2fo->n_ips_expanded]++; } while (VG_(next_IIPC)(iipc)); diff --git a/coregrind/m_gdbserver/m_gdbserver.c b/coregrind/m_gdbserver/m_gdbserver.c index 6e10593fbf..04aadbf83e 100644 --- a/coregrind/m_gdbserver/m_gdbserver.c +++ b/coregrind/m_gdbserver/m_gdbserver.c @@ -140,15 +140,21 @@ static void call_gdbserver ( ThreadId tid , CallReason reason); oldest result. */ static HChar* sym (Addr addr, Bool is_code) { - static HChar buf[2][200]; + static HChar *buf[2]; static int w = 0; PtrdiffT offset; if (w == 2) w = 0; - buf[w][0] = '\0'; + if (is_code) { - VG_(describe_IP) (addr, buf[w], 200, NULL); + HChar name[200]; + VG_(describe_IP) (addr, name, 200, NULL); // FIXME: get rid of name + if (buf[w]) VG_(free)(buf[w]); + buf[w] = VG_(strdup)("gdbserver sym", name); } else { - VG_(get_datasym_and_offset) (addr, buf[w], 200, &offset); + const HChar *name; + VG_(get_datasym_and_offset) (addr, &name, &offset); + if (buf[w]) VG_(free)(buf[w]); + buf[w] = VG_(strdup)("gdbserver sym", name); } return buf[w++]; } diff --git a/coregrind/m_gdbserver/valgrind-low-arm.c b/coregrind/m_gdbserver/valgrind-low-arm.c index 68a5baa89a..be2be8a453 100644 --- a/coregrind/m_gdbserver/valgrind-low-arm.c +++ b/coregrind/m_gdbserver/valgrind-low-arm.c @@ -144,13 +144,13 @@ Addr thumb_pc (Addr pc) // pc aligned on 4 bytes. We need to use debug info. { - HChar fnname[200]; // ??? max size + const HChar *fnname; SymAVMAs avmas; // If this is a thumb instruction, we need to ask // the debug info with the bit0 set // (why can't debug info do that for us ???) // (why if this is a 4 bytes thumb instruction ???) - if (VG_(get_fnname_raw) (pc | 1, fnname, 200)) { + if (VG_(get_fnname_raw) (pc | 1, &fnname)) { if (VG_(lookup_symbol_SLOW)( "*", fnname, &avmas )) { dlog (1, "fnname %s lookupsym %p => %p %s.\n", fnname, C2v(avmas.main), C2v(pc), diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c index 07122db283..2d403ce8d1 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -386,8 +386,6 @@ static HChar const* advance_to_comma ( HChar const* c ) { topspecs list, and (2) figure out what new binding are now active, and, as a result, add them to the actives mapping. */ -#define N_DEMANGLED 256 - void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) { Bool ok, isWrap; @@ -399,8 +397,8 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) const HChar* sym_name_pri; const HChar** sym_names_sec; SymAVMAs sym_avmas; - HChar demangled_sopatt[N_DEMANGLED]; - HChar demangled_fnpatt[N_DEMANGLED]; + const HChar* demangled_sopatt; + const HChar* demangled_fnpatt; Bool check_ppcTOCs = False; Bool isText; const HChar* newdi_soname; @@ -518,8 +516,8 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) const HChar** names; for (names = names_init; *names; names++) { ok = VG_(maybe_Z_demangle)( *names, - demangled_sopatt, N_DEMANGLED, - demangled_fnpatt, N_DEMANGLED, + &demangled_sopatt, + &demangled_fnpatt, &isWrap, &becTag, &becPrio ); /* ignore data symbols */ if (!isText) { @@ -552,6 +550,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) continue; } + HChar *replaced_sopatt = NULL; if (0 == VG_(strncmp) (demangled_sopatt, VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) { /* This is a redirection for handling lib so synonyms. If we @@ -577,8 +576,11 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) // Found the demangle_sopatt synonym => replace it first = last + 1; last = advance_to_comma(first); - VG_(strncpy)(demangled_sopatt, first, last - first); - demangled_sopatt[last - first] = '\0'; + replaced_sopatt = dinfo_zalloc("redir.rnnD.5", + last - first + 1); + VG_(strncpy)(replaced_sopatt, first, last - first); + replaced_sopatt[last - first] = '\0'; + demangled_sopatt = replaced_sopatt; break; } @@ -588,8 +590,7 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) } // If we have not replaced the sopatt, then skip the redir. - if (0 == VG_(strncmp) (demangled_sopatt, - VG_SO_SYN_PREFIX, VG_SO_SYN_PREFIX_LEN)) + if (replaced_sopatt == NULL) continue; } @@ -629,8 +630,8 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) for (names = names_init; *names; names++) { ok = isText && VG_(maybe_Z_demangle)( - *names, demangled_sopatt, N_DEMANGLED, - demangled_fnpatt, N_DEMANGLED, &isWrap, NULL, NULL ); + *names, &demangled_sopatt, + &demangled_fnpatt, &isWrap, NULL, NULL ); if (!ok) /* not a redirect. Ignore. */ continue; @@ -711,8 +712,6 @@ void VG_(redir_notify_new_DebugInfo)( const DebugInfo* newdi ) handle_require_text_symbols(newdi); } -#undef N_DEMANGLED - /* Add a new target for an indirect function. Adds a new redirection for the indirection function with address old_from that redirects the ordinary function with address new_from to the target address @@ -1704,13 +1703,17 @@ static void show_spec ( const HChar* left, const Spec* spec ) static void show_active ( const HChar* left, const Active* act ) { Bool ok; - HChar name1[64] = ""; - HChar name2[64] = ""; - name1[0] = name2[0] = 0; - ok = VG_(get_fnname_w_offset)(act->from_addr, name1, 64); - if (!ok) VG_(strcpy)(name1, "???"); - ok = VG_(get_fnname_w_offset)(act->to_addr, name2, 64); - if (!ok) VG_(strcpy)(name2, "???"); + const HChar *buf; + + ok = VG_(get_fnname_w_offset)(act->from_addr, &buf); + if (!ok) buf = "???"; + // Stash away name1 + HChar name1[VG_(strlen)(buf) + 1]; + VG_(strcpy)(name1, buf); + + const HChar *name2; + ok = VG_(get_fnname_w_offset)(act->to_addr, &name2); + if (!ok) name2 = "???"; VG_(message)(Vg_DebugMsg, "%s0x%08llx (%20s) %s-> (%04d.%d) 0x%08llx %s\n", left, diff --git a/coregrind/m_sbprofile.c b/coregrind/m_sbprofile.c index 197fff51c8..0be07dd9cf 100644 --- a/coregrind/m_sbprofile.c +++ b/coregrind/m_sbprofile.c @@ -51,7 +51,6 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, { ULong score_cumul, score_cumul_saved, score_here; HChar buf_cumul[10], buf_here[10]; - HChar name[64]; Int r; /* must be signed */ HChar ecs_txt[50]; @@ -84,9 +83,10 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, continue; if (tops[r].score == 0) continue; - name[0] = 0; - VG_(get_fnname_w_offset)(tops[r].addr, name, 64); - name[63] = 0; + + const HChar *name; + VG_(get_fnname_w_offset)(tops[r].addr, &name); + score_here = tops[r].score; score_cumul += score_here; VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); @@ -116,9 +116,10 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, continue; if (tops[r].score == 0) continue; - name[0] = 0; - VG_(get_fnname_w_offset)(tops[r].addr, name, 64); - name[63] = 0; + + const HChar *name; + VG_(get_fnname_w_offset)(tops[r].addr, &name); + score_here = tops[r].score; score_cumul += score_here; VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); @@ -145,9 +146,10 @@ void show_SB_profile ( const SBProfEntry tops[], UInt n_tops, continue; if (tops[r].score == 0) continue; - name[0] = 0; - VG_(get_fnname_w_offset)(tops[r].addr, name, 64); - name[63] = 0; + + const HChar *name; + VG_(get_fnname_w_offset)(tops[r].addr, &name); + score_here = tops[r].score; VG_(percentify)(score_cumul, score_total, 2, 6, buf_cumul); VG_(percentify)(score_here, score_total, 2, 6, buf_here); diff --git a/coregrind/m_stacktrace.c b/coregrind/m_stacktrace.c index b4fb86da74..cdecc15661 100644 --- a/coregrind/m_stacktrace.c +++ b/coregrind/m_stacktrace.c @@ -717,15 +717,16 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, frame. */ lr_is_first_RA = False; { -# define M_VG_ERRTXT 1000 - HChar buf_lr[M_VG_ERRTXT], buf_ip[M_VG_ERRTXT]; + const HChar *buf_lr, *buf_ip; /* The following conditional looks grossly inefficient and surely could be majorly improved, with not much effort. */ - if (VG_(get_fnname_raw) (lr, buf_lr, M_VG_ERRTXT)) - if (VG_(get_fnname_raw) (ip, buf_ip, M_VG_ERRTXT)) - if (VG_(strncmp)(buf_lr, buf_ip, M_VG_ERRTXT)) + if (VG_(get_fnname_raw) (lr, &buf_lr)) { + HChar buf_lr_copy[VG_(strlen)(buf_lr) + 1]; + VG_(strcpy)(buf_lr_copy, buf_lr); + if (VG_(get_fnname_raw) (ip, &buf_ip)) + if (VG_(strcmp)(buf_lr_copy, buf_ip)) lr_is_first_RA = True; -# undef M_VG_ERRTXT + } } if (sps) sps[0] = fp; /* NB. not sp */ @@ -816,15 +817,16 @@ UInt VG_(get_StackTrace_wrk) ( ThreadId tid_if_known, static Bool in_same_fn ( Addr a1, Addr a2 ) { -# define M_VG_ERRTXT 500 - HChar buf_a1[M_VG_ERRTXT], buf_a2[M_VG_ERRTXT]; + const HChar *buf_a1, *buf_a2; /* The following conditional looks grossly inefficient and surely could be majorly improved, with not much effort. */ - if (VG_(get_fnname_raw) (a1, buf_a1, M_VG_ERRTXT)) - if (VG_(get_fnname_raw) (a2, buf_a2, M_VG_ERRTXT)) - if (VG_(strncmp)(buf_a1, buf_a2, M_VG_ERRTXT)) + if (VG_(get_fnname_raw) (a1, &buf_a1)) { + HChar buf_a1_copy[VG_(strlen)(buf_a1) + 1]; + VG_(strcpy)(buf_a1_copy, buf_a1); + if (VG_(get_fnname_raw) (a2, &buf_a2)) + if (VG_(strcmp)(buf_a1_copy1, buf_a2)) return True; -# undef M_VG_ERRTXT + } return False; } diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index 8469e7eafc..b5d10fbb22 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -1448,13 +1448,9 @@ Bool VG_(translate) ( ThreadId tid, if ((kind == T_Redir_Wrap || kind == T_Redir_Replace) && (VG_(clo_verbosity) >= 2 || VG_(clo_trace_redir))) { Bool ok; - HChar name1[512] = ""; - HChar name2[512] = ""; - name1[0] = name2[0] = 0; - ok = VG_(get_fnname_w_offset)(nraddr, name1, sizeof(name1)); - if (!ok) VG_(strcpy)(name1, "???"); - ok = VG_(get_fnname_w_offset)(addr, name2, sizeof(name2)); - if (!ok) VG_(strcpy)(name2, "???"); + const HChar *buf; + const HChar *name2; + /* Try also to get the soname (not the filename) of the "from" object. This makes it much easier to debug redirection problems. */ @@ -1465,6 +1461,15 @@ Bool VG_(translate) ( ThreadId tid, if (t) nraddr_soname = t; } + + ok = VG_(get_fnname_w_offset)(nraddr, &buf); + if (!ok) buf = "???"; + // Stash away name1 + HChar name1[VG_(strlen)(buf) + 1]; + VG_(strcpy)(name1, buf); + ok = VG_(get_fnname_w_offset)(addr, &name2); + if (!ok) name2 = "???"; + VG_(message)(Vg_DebugMsg, "REDIR: 0x%llx (%s:%s) redirected to 0x%llx (%s)\n", nraddr, nraddr_soname, name1, @@ -1477,8 +1482,6 @@ Bool VG_(translate) ( ThreadId tid, /* If doing any code printing, print a basic block start marker */ if (VG_(clo_trace_flags) || debugging_translation) { - HChar fnname[512] = "UNKNOWN_FUNCTION"; - VG_(get_fnname_w_offset)(addr, fnname, 512); const HChar* objname = "UNKNOWN_OBJECT"; OffT objoff = 0; DebugInfo* di = VG_(find_DebugInfo)( addr ); @@ -1487,6 +1490,10 @@ Bool VG_(translate) ( ThreadId tid, objoff = addr - VG_(DebugInfo_get_text_bias)(di); } vg_assert(objname); + + const HChar *fnname; + Bool ok = VG_(get_fnname_w_offset)(addr, &fnname); + if (!ok) fnname = "UNKNOWN_FUNCTION"; VG_(printf)( "==== SB %d (evchecks %lld) [tid %d] 0x%llx %s %s+0x%llx\n", VG_(get_bbs_translated)(), bbs_done, (Int)tid, addr, diff --git a/coregrind/pub_core_debuginfo.h b/coregrind/pub_core_debuginfo.h index 23075b853f..7618191537 100644 --- a/coregrind/pub_core_debuginfo.h +++ b/coregrind/pub_core_debuginfo.h @@ -86,14 +86,14 @@ extern void VG_(di_discard_ALL_debuginfo)( void ); * It should only be used in cases where the names of interest will have * particular (ie. non-mangled) forms, or the mangled form is acceptable. */ extern -Bool VG_(get_fnname_raw) ( Addr a, HChar* buf, Int nbuf ); +Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf ); /* Like VG_(get_fnname), but without C++ demangling. (But it does Z-demangling and below-main renaming.) iipc argument: same usage as in VG_(describe_IP) in pub_tool_debuginfo.h. */ extern -Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, HChar* buf, Int nbuf, - InlIPCursor* iipc ); +Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf, + const InlIPCursor* iipc ); /* mips-linux only: find the offset of current address. This is needed for stack unwinding for MIPS. diff --git a/coregrind/pub_core_demangle.h b/coregrind/pub_core_demangle.h index bf6c667ee1..b7e1a8fecc 100644 --- a/coregrind/pub_core_demangle.h +++ b/coregrind/pub_core_demangle.h @@ -43,7 +43,7 @@ * (2) undoes C++ demangling, if 'do_cxx_demangle' is True. */ extern void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, - const HChar* orig, HChar* result, Int result_size ); + const HChar* orig, const HChar** result ); /* Demangle a Z-encoded name as described in pub_tool_redir.h. Z-encoded names are used by Valgrind for doing function @@ -59,11 +59,11 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, extern Bool VG_(maybe_Z_demangle) ( const HChar* sym, - /*OUT*/HChar* so, Int soLen, - /*OUT*/HChar* fn, Int fnLen, - /*OUT*/Bool* isWrap, - /*OUT*/Int* eclassTag, - /*OUT*/Int* eclassPrio ); + /*OUT*/const HChar** so, // may be NULL + /*OUT*/const HChar** fn, + /*OUT*/Bool* isWrap, // may be NULL + /*OUT*/Int* eclassTag, // may be NULL + /*OUT*/Int* eclassPrio ); // may be NULL #endif // __PUB_CORE_DEMANGLE_H diff --git a/exp-bbv/bbv_main.c b/exp-bbv/bbv_main.c index 8926af46b4..c8759ae6d8 100644 --- a/exp-bbv/bbv_main.c +++ b/exp-bbv/bbv_main.c @@ -87,15 +87,13 @@ struct thread_info { Int bbtrace_fd; /* file descriptor */ }; -#define FUNCTION_NAME_LENGTH 20 - struct BB_info { Addr BB_addr; /* used as key, must be first */ Int n_instrs; /* instructions in the basic block */ Int block_num; /* unique block identifier */ Int *inst_counter; /* times entered * num_instructions */ Bool is_entry; /* is this block a function entry point */ - HChar fn_name[FUNCTION_NAME_LENGTH]; /* Function block is in */ + const HChar *fn_name; /* Function block is in */ }; @@ -403,8 +401,9 @@ static IRSB* bbv_instrument ( VgCallbackClosure* closure, bbInfo->block_num=block_num; block_num++; /* get function name and entry point information */ - bbInfo->is_entry=VG_(get_fnname_if_entry)(origAddr, bbInfo->fn_name, - FUNCTION_NAME_LENGTH); + const HChar *fn_name; + bbInfo->is_entry=VG_(get_fnname_if_entry)(origAddr, &fn_name); + bbInfo->fn_name =VG_(strdup)("bbv_strings", fn_name); /* insert structure into table */ VG_(OSetGen_Insert)( instr_info_table, bbInfo ); } diff --git a/exp-sgcheck/pc_common.c b/exp-sgcheck/pc_common.c index 042a860771..de6bb16ce1 100644 --- a/exp-sgcheck/pc_common.c +++ b/exp-sgcheck/pc_common.c @@ -134,7 +134,7 @@ typedef Seg* vseg; XArray* descr1; /* XArray* of HChar */ XArray* descr2; /* XArray* of HChar */ - HChar datasym[96]; + const HChar* datasym; PtrdiffT datasymoff; } Heap; struct { @@ -657,9 +657,8 @@ UInt pc_update_Error_extra ( const Error* err ) case XE_Heap: { Bool have_descr; - tl_assert(sizeof(xe->XE.Heap.datasym) > 0); xe->XE.Heap.datasymoff = 0; - xe->XE.Heap.datasym[0] = 0; + xe->XE.Heap.datasym = NULL; tl_assert(!xe->XE.Heap.descr1); tl_assert(!xe->XE.Heap.descr2); @@ -671,7 +670,6 @@ UInt pc_update_Error_extra ( const Error* err ) = VG_(newXA)( VG_(malloc), "pc.update_extra.Heap.descr1", VG_(free), sizeof(HChar) ); - VG_(memset)(&xe->XE.Heap.datasym, 0, sizeof(xe->XE.Heap.datasym)); xe->XE.Heap.datasymoff = 0; have_descr @@ -699,13 +697,13 @@ UInt pc_update_Error_extra ( const Error* err ) /* If Dwarf3 info produced nothing useful, see at least if we can fish something useful out of the ELF symbol info. */ if (!have_descr) { + const HChar *name; if (VG_(get_datasym_and_offset)( - xe->XE.Heap.addr, &xe->XE.Heap.datasym[0], - sizeof(xe->XE.Heap.datasym)-1, + xe->XE.Heap.addr, &name, &xe->XE.Heap.datasymoff ) ) { - tl_assert(xe->XE.Heap.datasym[sizeof(xe->XE.Heap.datasym)-1] - == 0); + xe->XE.Heap.datasym = + VG_(strdup)("pc.update_extra.Heap.datasym", name); } } break; diff --git a/exp-sgcheck/sg_main.c b/exp-sgcheck/sg_main.c index f4ae81bf72..f6f5fc418d 100644 --- a/exp-sgcheck/sg_main.c +++ b/exp-sgcheck/sg_main.c @@ -1926,10 +1926,10 @@ void shadowStack_new_frame ( ThreadId tid, if (0) { Word d = callee->depth; - HChar fnname[80]; + const HChar *fnname; Bool ok; Addr ip = ip_post_call_insn; - ok = VG_(get_fnname_w_offset)( ip, fnname, sizeof(fnname) ); + ok = VG_(get_fnname_w_offset)( ip, &fnname ); while (d > 0) { VG_(printf)(" "); d--; diff --git a/exp-sgcheck/tests/bad_percentify.c b/exp-sgcheck/tests/bad_percentify.c index 3fb73eee39..360cd0dfe9 100644 --- a/exp-sgcheck/tests/bad_percentify.c +++ b/exp-sgcheck/tests/bad_percentify.c @@ -493,20 +493,20 @@ VG_(debugLog_vprintf) ( } // case 'y': { /* %y - print symbol */ -// Char buf[100]; -// Char *cp = buf; // Addr a = va_arg(vargs, Addr); // -// if (flags & VG_MSG_PAREN) -// *cp++ = '('; -// if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { -// if (flags & VG_MSG_PAREN) { -// cp += local_strlen(cp); -// *cp++ = ')'; -// *cp = '\0'; +// +// +// HChar *name; +// if (VG_(get_fnname_w_offset)(a, &name)) { +// HChar buf[1 + VG_strlen(name) + 1 + 1]; +// if (flags & VG_MSG_PAREN) { +// VG_(sprintf)(str, "(%s)", name): +// } else { +// VG_(sprintf)(str, "%s", name): // } -// ret += myvprintf_str(send, send_arg2, flags, width, buf, 0); -// } +// ret += myvprintf_str(send, flags, width, buf, 0); +// } // break; // } default: diff --git a/exp-sgcheck/tests/hackedbz2.c b/exp-sgcheck/tests/hackedbz2.c index 2f327690c1..f012d7a4ce 100644 --- a/exp-sgcheck/tests/hackedbz2.c +++ b/exp-sgcheck/tests/hackedbz2.c @@ -1244,18 +1244,18 @@ UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs ) } # if 0 case 'y': { /* %y - print symbol */ - Char buf[100]; - Char *cp = buf; Addr a = va_arg(vargs, Addr); - if (flags & VG_MSG_PAREN) - *cp++ = '('; - if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { + + + HChar *name; + if (VG_(get_fnname_w_offset)(a, &name)) { + HChar buf[1 + VG_strlen(name) + 1 + 1]; if (flags & VG_MSG_PAREN) { - cp += VG_(strlen)(cp); - *cp++ = ')'; - *cp = '\0'; - } + VG_(sprintf)(str, "(%s)", name): + } else { + VG_(sprintf)(str, "%s", name): + } ret += myvprintf_str(send, flags, width, buf, 0); } break; diff --git a/include/pub_tool_addrinfo.h b/include/pub_tool_addrinfo.h index ce2c232d32..84afdde696 100644 --- a/include/pub_tool_addrinfo.h +++ b/include/pub_tool_addrinfo.h @@ -153,10 +153,10 @@ struct _AddrInfo { ExeContext* freed_at; // might be null_ExeContext. } Block; - // In a global .data symbol. This holds the first 127 chars of + // In a global .data symbol. This holds // the variable's name (zero terminated), plus a (memory) offset. struct { - HChar name[128]; + HChar *name; PtrdiffT offset; } DataSym; diff --git a/include/pub_tool_debuginfo.h b/include/pub_tool_debuginfo.h index f47669e6c1..0940b3dc35 100644 --- a/include/pub_tool_debuginfo.h +++ b/include/pub_tool_debuginfo.h @@ -40,14 +40,14 @@ /* Get the file/function/line number of the instruction at address 'a'. For these four, if debug info for the address is found, it copies the info into the buffer/UInt and returns True. If not, it - returns False and nothing is copied. VG_(get_fnname) always + returns False. VG_(get_fnname) always demangles C++ function names. VG_(get_fnname_w_offset) is the same, except it appends "+N" to symbol names to indicate offsets. */ extern Bool VG_(get_filename) ( Addr a, HChar* filename, Int n_filename ); -extern Bool VG_(get_fnname) ( Addr a, HChar* fnname, Int n_fnname ); +extern Bool VG_(get_fnname) ( Addr a, const HChar** fnname ); extern Bool VG_(get_linenum) ( Addr a, UInt* linenum ); extern Bool VG_(get_fnname_w_offset) - ( Addr a, HChar* fnname, Int n_fnname ); + ( Addr a, const HChar** fnname ); /* This one is the most general. It gives filename, line number and optionally directory name. filename and linenum may not be NULL. @@ -74,7 +74,7 @@ extern Bool VG_(get_filename_linenum) a particular function. Nb: if an executable/shared object is stripped of its symbols, this function will not be able to recognise function entry points within it. */ -extern Bool VG_(get_fnname_if_entry) ( Addr a, HChar* fnname, Int n_fnname ); +extern Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** fnname ); typedef enum { @@ -84,7 +84,7 @@ typedef } Vg_FnNameKind; // Such names are often filtered. /* Indicates what kind of fnname it is. */ -extern Vg_FnNameKind VG_(get_fnname_kind) ( HChar* name ); +extern Vg_FnNameKind VG_(get_fnname_kind) ( const HChar* name ); /* Like VG_(get_fnname_kind), but takes a code address. */ extern Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ); @@ -94,7 +94,7 @@ extern Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ); which is guaranteed to be zero terminated. Also data_addr's offset from the symbol start is put into *offset. */ extern Bool VG_(get_datasym_and_offset)( Addr data_addr, - /*OUT*/HChar* dname, Int n_dname, + /*OUT*/const HChar** dname, /*OUT*/PtrdiffT* offset ); /* Try to form some description of DATA_ADDR by looking at the DWARF3 @@ -118,7 +118,7 @@ Bool VG_(get_data_description)( /* Succeeds if the address is within a shared object or the main executable. It doesn't matter if debug info is present or not. */ -extern Bool VG_(get_objname) ( Addr a, HChar* objname, Int n_objname ); +extern Bool VG_(get_objname) ( Addr a, const HChar** objname ); /* Cursor allowing to describe inlined function calls at an IP, diff --git a/lackey/lk_main.c b/lackey/lk_main.c index f76998f8e9..485707c4ff 100644 --- a/lackey/lk_main.c +++ b/lackey/lk_main.c @@ -660,7 +660,6 @@ IRSB* lk_instrument ( VgCallbackClosure* closure, IRDirty* di; Int i; IRSB* sbOut; - HChar fnname[100]; IRTypeEnv* tyenv = sbIn->tyenv; Addr iaddr = 0, dst; UInt ilen = 0; @@ -750,8 +749,9 @@ IRSB* lk_instrument ( VgCallbackClosure* closure, */ tl_assert(clo_fnname); tl_assert(clo_fnname[0]); + const HChar *fnname; if (VG_(get_fnname_if_entry)(st->Ist.IMark.addr, - fnname, sizeof(fnname)) + &fnname) && 0 == VG_(strcmp)(fnname, clo_fnname)) { di = unsafeIRDirty_0_N( 0, "add_one_func_call", diff --git a/massif/ms_main.c b/massif/ms_main.c index da58bb665c..cdd73b498e 100644 --- a/massif/ms_main.c +++ b/massif/ms_main.c @@ -355,7 +355,7 @@ static void init_ignore_fns(void) } // Determines if the named function is a member of the XArray. -static Bool is_member_fn(XArray* fns, const HChar* fnname) +static Bool is_member_fn(const XArray* fns, const HChar* fnname) { HChar** fn_ptr; Int i; @@ -817,9 +817,9 @@ static void sanity_check_SXTree(SXPt* sxpt) // Determine if the given IP belongs to a function that should be ignored. static Bool fn_should_be_ignored(Addr ip) { - static HChar buf[BUF_LEN]; + const HChar *buf; return - ( VG_(get_fnname)(ip, buf, BUF_LEN) && is_member_fn(ignore_fns, buf) + ( VG_(get_fnname)(ip, &buf) && is_member_fn(ignore_fns, buf) ? True : False ); } @@ -832,7 +832,6 @@ static Bool fn_should_be_ignored(Addr ip) static Int get_IPs( ThreadId tid, Bool exclude_first_entry, Addr ips[]) { - static HChar buf[BUF_LEN]; Int n_ips, i, n_alloc_fns_removed; Int overestimate; Bool redo; @@ -871,7 +870,8 @@ Int get_IPs( ThreadId tid, Bool exclude_first_entry, Addr ips[]) // because VG_(get_fnname) is expensive. n_alloc_fns_removed = ( exclude_first_entry ? 1 : 0 ); for (i = n_alloc_fns_removed; i < n_ips; i++) { - if (VG_(get_fnname)(ips[i], buf, BUF_LEN)) { + const HChar *buf; + if (VG_(get_fnname)(ips[i], &buf)) { if (is_member_fn(alloc_fns, buf)) { n_alloc_fns_removed++; } else { diff --git a/memcheck/tests/origin5-bz2.c b/memcheck/tests/origin5-bz2.c index 26fe161753..b4b238fe8e 100644 --- a/memcheck/tests/origin5-bz2.c +++ b/memcheck/tests/origin5-bz2.c @@ -1237,18 +1237,18 @@ UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs ) } # if 0 case 'y': { /* %y - print symbol */ - Char buf[100]; - Char *cp = buf; Addr a = va_arg(vargs, Addr); - if (flags & VG_MSG_PAREN) - *cp++ = '('; - if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { + + + HChar *name; + if (VG_(get_fnname_w_offset)(a, &name)) { + HChar buf[1 + VG_strlen(name) + 1 + 1]; if (flags & VG_MSG_PAREN) { - cp += VG_(strlen)(cp); - *cp++ = ')'; - *cp = '\0'; - } + VG_(sprintf)(str, "(%s)", name): + } else { + VG_(sprintf)(str, "%s", name): + } ret += myvprintf_str(send, flags, width, buf, 0); } break; diff --git a/memcheck/tests/varinfo6.c b/memcheck/tests/varinfo6.c index 7d835e0f89..c04f68446b 100644 --- a/memcheck/tests/varinfo6.c +++ b/memcheck/tests/varinfo6.c @@ -1275,18 +1275,18 @@ UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs ) } # if 0 case 'y': { /* %y - print symbol */ - Char buf[100]; - Char *cp = buf; Addr a = va_arg(vargs, Addr); - if (flags & VG_MSG_PAREN) - *cp++ = '('; - if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { + + + HChar *name; + if (VG_(get_fnname_w_offset)(a, &name)) { + HChar buf[1 + VG_strlen(name) + 1 + 1]; if (flags & VG_MSG_PAREN) { - cp += VG_(strlen)(cp); - *cp++ = ')'; - *cp = '\0'; - } + VG_(sprintf)(str, "(%s)", name): + } else { + VG_(sprintf)(str, "%s", name): + } ret += myvprintf_str(send, flags, width, buf, 0); } break; diff --git a/perf/bz2.c b/perf/bz2.c index 739e68f93d..79cb933256 100644 --- a/perf/bz2.c +++ b/perf/bz2.c @@ -1237,18 +1237,16 @@ UInt vprintf_wrk ( void(*send)(HChar), const HChar *format, va_list vargs ) } # if 0 case 'y': { /* %y - print symbol */ - Char buf[100]; - Char *cp = buf; Addr a = va_arg(vargs, Addr); - if (flags & VG_MSG_PAREN) - *cp++ = '('; - if (VG_(get_fnname_w_offset)(a, cp, sizeof(buf)-4)) { + HChar *name; + if (VG_(get_fnname_w_offset)(a, &name)) { + HChar buf[1 + VG_strlen(name) + 1 + 1]; if (flags & VG_MSG_PAREN) { - cp += VG_(strlen)(cp); - *cp++ = ')'; - *cp = '\0'; - } + VG_(sprintf)(str, "(%s)", name): + } else { + VG_(sprintf)(str, "%s", name): + } ret += myvprintf_str(send, flags, width, buf, 0); } break;