From: Philippe Waroquiers Date: Tue, 25 Oct 2016 20:46:00 +0000 (+0000) Subject: Add some more comments in pub_tool_debuginfo.h about memory persistence/ownership X-Git-Tag: svn/VALGRIND_3_13_0~315 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3553ac9aad70c67587d2a118e5c96547427c6e71;p=thirdparty%2Fvalgrind.git Add some more comments in pub_tool_debuginfo.h about memory persistence/ownership and have m_debuginfo.c referencing these comments. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16106 --- diff --git a/coregrind/m_debuginfo/debuginfo.c b/coregrind/m_debuginfo/debuginfo.c index b9c74a7219..447cd6964d 100644 --- a/coregrind/m_debuginfo/debuginfo.c +++ b/coregrind/m_debuginfo/debuginfo.c @@ -1736,13 +1736,15 @@ static void search_all_loctabs ( Addr ptr, /*OUT*/DebugInfo** pdi, 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. - Note: the string returned in *BUF is persistent as long as + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h + get_sym_name and the fact it calls the demangler is the main reason + for non persistence of the information returned by m_debuginfo.c + functions : 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. + (2) the demangler is not invoked again Also, the returned string is owned by "somebody else". Callers must - not free it or modify it. */ + not free it or modify it.*/ static Bool get_sym_name ( Bool do_cxx_demangling, Bool do_z_demangling, Bool do_below_main_renaming, @@ -1822,8 +1824,8 @@ 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. - NOTE: See important comment about the persistence and memory ownership - of the return string at function get_sym_name */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_fnname) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, @@ -1837,8 +1839,8 @@ Bool VG_(get_fnname) ( Addr a, const HChar** buf ) /* This is available to tools... always demangle C++ names, 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 */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True, @@ -1853,8 +1855,8 @@ Bool VG_(get_fnname_w_offset) ( Addr a, const HChar** buf ) /* This is available to tools... always demangle C++ names, only succeed if 'a' matches first instruction of function, and don't show offsets. - NOTE: See important comment about the persistence and memory ownership - of the return string at function get_sym_name */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf ) { const HChar *tmp; @@ -1875,8 +1877,8 @@ Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** buf ) /* 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. - NOTE: See important comment about the persistence and memory ownership - of the return string at function get_sym_name */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf ) { return get_sym_name ( /*C++-demangle*/False, /*Z-demangle*/False, @@ -1891,8 +1893,8 @@ Bool VG_(get_fnname_raw) ( Addr a, const HChar** buf ) /* 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. - NOTE: See important comment about the persistence and memory ownership - of the return string at function get_sym_name */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_fnname_no_cxx_demangle) ( Addr a, const HChar** buf, const InlIPCursor* iipc ) { @@ -1974,8 +1976,8 @@ Vg_FnNameKind VG_(get_fnname_kind_from_IP) ( Addr ip ) /* Looks up data_addr in the collection of data symbols, and if found 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 */ + NOTE: See IMPORTANT COMMENT above about persistence and ownership + in pub_tool_debuginfo.h */ Bool VG_(get_datasym_and_offset)( Addr data_addr, /*OUT*/const HChar** dname, /*OUT*/PtrdiffT* offset ) @@ -1995,7 +1997,7 @@ Bool VG_(get_datasym_and_offset)( Addr data_addr, (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 ) +Bool VG_(get_objname) ( Addr a, const HChar** objname ) { DebugInfo* di; const NSegment *seg; @@ -2008,7 +2010,7 @@ Bool VG_(get_objname) ( Addr a, const HChar** buf ) && di->text_size > 0 && di->text_avma <= a && a < di->text_avma + di->text_size) { - *buf = di->fsm.filename; + *objname = di->fsm.filename; return True; } } @@ -2019,7 +2021,7 @@ Bool VG_(get_objname) ( Addr a, const HChar** buf ) when running programs under wine. */ if ( (seg = VG_(am_find_nsegment)(a)) != NULL && (filename = VG_(am_get_filename)(seg)) != NULL ) { - *buf = filename; + *objname = filename; return True; } return False; @@ -4349,7 +4351,7 @@ const HChar* VG_(pp_SectKind)( VgSectKind kind ) in *name. The returned name, if any, should be saved away, if there is a chance that a debug-info will be discarded and the name is being used later on. */ -VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a) +VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** objname, Addr a) { DebugInfo* di; VgSectKind res = Vg_SectUnknown; @@ -4426,11 +4428,11 @@ VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a) vg_assert( (di == NULL && res == Vg_SectUnknown) || (di != NULL && res != Vg_SectUnknown) ); - if (name) { + if (objname) { if (di && di->fsm.filename) { - *name = di->fsm.filename; + *objname = di->fsm.filename; } else { - *name = "???"; + *objname = "???"; } } diff --git a/include/pub_tool_debuginfo.h b/include/pub_tool_debuginfo.h index 49ceffbdfe..1fe4ab335e 100644 --- a/include/pub_tool_debuginfo.h +++ b/include/pub_tool_debuginfo.h @@ -38,12 +38,44 @@ /*=== Obtaining debug information ===*/ /*====================================================================*/ +/* IMPORTANT COMMENT about memory persistence and ownership. + + Many functions below are returning a string in a HChar** argument. + This memory must not be freed by the caller : it belongs to the debuginfo + module. The returned string is *not* guaranteed to be persistent. + The exact persistence depends on the kind of information returned, + and of the internal implementation of the debuginfo module. + In other words: use the memory directly after the call, and if in doubt, + save it away. + + In general, all returned strings will be invalidated when the + DebugInfo they correspond to is discarded. This is the case for + the filename, dirname, fnname and objname. + An objname might also be invalidated by changes to the address + space manager segments, e.g. if a segment is merged with another + segment. + + Retrieving a fnname might imply a call to the c++ demangler. + A returned fnname is invalidated if any other call to the demangler + is done. In particular, this means that the memory returned by one of + the VG_(get_fnname...) functions is invalidated by : + * another call to any of the functions VG_(get_fnname...). + * any other call that will directly or indirectly invoke the + c++ demangler. Such an indirect call to the demangler can a.o. be + done by calls to pub_tool_errormgr.h functions. + So, among others, the following is WRONG: + VG_(get_fnname)(a1, &fnname1); + VG_(get_fnname)(a2, &fnname2); + ... it is WRONG to use fnname1 here .... +*/ + /* 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. 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. */ + same, except it appends "+N" to symbol names to indicate offsets. + NOTE: See IMPORTANT COMMENT above about persistence and ownership. */ extern Bool VG_(get_filename) ( Addr a, const HChar** filename ); extern Bool VG_(get_fnname) ( Addr a, const HChar** fnname ); extern Bool VG_(get_linenum) ( Addr a, UInt* linenum ); @@ -58,9 +90,7 @@ extern Bool VG_(get_fnname_w_offset) it is available; if not available, '\0' is written to the first byte. - The character strings returned in *filename and *dirname are not - persistent. They will be freed when the DebugInfo they belong to - is discarded. + NOTE: See IMPORTANT COMMENT above about persistence and ownership. Returned value indicates whether any filename/line info could be found. */ @@ -76,7 +106,8 @@ extern Bool VG_(get_filename_linenum) instruction in a function. Use this to instrument the start of 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. */ + entry points within it. + NOTE: See IMPORTANT COMMENT above about persistence and ownership. */ extern Bool VG_(get_fnname_if_entry) ( Addr a, const HChar** fnname ); typedef @@ -120,7 +151,9 @@ 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. */ + It first searches if Addr a belongs to the text segment of debug info. + If not found, it asks the address space manager whether it + knows the name of the file associated with this mapping. */ extern Bool VG_(get_objname) ( Addr a, const HChar** objname ); @@ -261,10 +294,10 @@ typedef const HChar* VG_(pp_SectKind)( VgSectKind kind ); /* Given an address 'a', make a guess of which section of which object - it comes from. If name is non-NULL, then the object's name is put - into *name. The returned name is persistent as long as the debuginfo - it belongs to isn't discarded. */ -VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** name, Addr a); + it comes from. If objname is non-NULL, then the object's name is put + into *objname. This only looks in debug info, it does not examine + the address space manager mapped files. */ +VgSectKind VG_(DebugInfo_sect_kind)( /*OUT*/const HChar** objname, Addr a); #endif // __PUB_TOOL_DEBUGINFO_H