Bug 372120

Summary: c++ demangler demangles symbols which are not c++
Product: [Developer tools] valgrind Reporter: Philippe Waroquiers <philippe.waroquiers>
Component: generalAssignee: Julian Seward <jseward>
Status: RESOLVED FIXED    
Severity: normal CC: mark
Priority: NOR    
Version First Reported In: 3.12 SVN   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:
Bug Depends on:    
Bug Blocks: 372182    

Description Philippe Waroquiers 2016-11-05 21:41:15 UTC
For the below code, the demanglers demangle a non c++ symbol as if it
would be a mangled c++ name.
This was detected on an Ada program (as gnat mangles Ada names by
replacing . by __) but that equally happens on c symbols having 2 underscores.
To reproduce:
gcc -g -o demang demang.c
./vg-in-place --leak-check=full ./demang
==30660== 90 bytes in 9 blocks are definitely lost in loss record 2 of 2
==30660==    at 0x4C27BB5: malloc (vg_replace_malloc.c:299)
==30660==    by 0x400515: main__calling__some(...)(long long,...)(char) (demang.c:7)
==30660==    by 0x40052C: main (demang.c:12)


#include <stdlib.h>
char *v;
void main__calling__some__exec(void)
{  
   int i;
   for (i = 0; i < 10; i++)
      v = malloc(10);
}

main ()
{
   main__calling__some__exec();
}
Comment 1 Mark Wielaard 2016-11-07 12:27:58 UTC
Yeah, I think it would be a good idea to at least recognize the
default (gnu_v3) style c++ mangling, which always starts with _Z.
Something like the following should work:
 
diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c
index 23c4a02..c8a9ca5 100644
--- a/coregrind/m_demangle/demangle.c
+++ b/coregrind/m_demangle/demangle.c
@@ -141,7 +141,8 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling,
    }
 
    /* Possibly undo (1) */
-   if (do_cxx_demangling && VG_(clo_demangle)) {
+   if (do_cxx_demangling && VG_(clo_demangle)
+       && orig[0] == '_' && orig[1] == 'Z') {
       /* !!! vvv STATIC vvv !!! */
       static HChar* demangled = NULL;
       /* !!! ^^^ STATIC ^^^ !!! */

Then on top of that it might be good to try to detect the language
from the debuginfo CU DW_AT_language. If we have some language detection/guessing we can explicitly set it with cplus_demangle_set_style (enum demangling_styles style) (but beware that this is a global/static, so not thread-safe - which might not be an issue currently in this context).
Comment 2 Julian Seward 2016-11-07 13:02:20 UTC
(In reply to Mark Wielaard from comment #1)
> Yeah, I think it would be a good idea to at least recognize the
> default (gnu_v3) style c++ mangling, which always starts with _Z.
> Something like the following should work:

I would be in favour of this, which is simple and at least makes it
less flaky than it currently is.  With the orig != NULL test added
back in for safety.
Comment 3 Mark Wielaard 2016-11-07 14:26:15 UTC
(In reply to Julian Seward from comment #2) 
> I would be in favour of this, which is simple and at least makes it
> less flaky than it currently is.  With the orig != NULL test added
> back in for safety.

valgrind svn r16118.

I'll open a new bug for supporting other languages/demangling styles.