Bug 217615

Summary: memcheck does not detect new/new[]/malloc-delete/delete[]/free mismatches in win32 apps
Product: [Developer tools] valgrind Reporter: Dan Kegel <dank>
Component: generalAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: wishlist    
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Compiled Sources   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:
Attachments: Patch to add soname definitions for Visual C++ 2005 and 2008

Description Dan Kegel 2009-12-06 18:25:16 UTC
Version:            (using Devel)
OS:                Linux
Installed from:    Compiled sources

For Unix, memcheck provides a replacement heap implementation.  There is nothing
like this yet for win32 apps.  However, wine's kernel32 heap is close to being good 
enough; I have patches pending against wine to implement use-after-free and overrun
detection without any changes to valgrind at all 
(see http://wiki.winehq.org/Wine_and_Valgrind ).

Detecting new[]/delete mismatches is another matter.  
One could modify the app to use its own wrappers around those functions
that detected mismatch, but it would be nicer to not require any app modifications.

I've started looking at this.  So far, I've verified that I can intercept 
functions in msvcrt90.dll when valgrinding wine (small patch required; I'll attach).
I haven't verified yet that calling conventions are compatible.

What I'm thinking of at the moment is adding something
like this to coregrind/m_replacemalloc/vg_replace_malloc.c like this:

/* how big a preamble to use for each allocation */
#define MAGIC_ALLOCATOR_SIZE 8
/* value to store in preamble for each kind of allocation */
#define MAGIC_ALLOCATOR_MALLOC 'm'
#define MAGIC_ALLOCATOR_NEW 'n'
#define MAGIC_ALLOCATOR_NEW_VECTOR 'v'

void* VG_REPLACE_FUNCTION_ZU(VG_Z_MSVCR90,malloc) (SizeT n);
void* VG_REPLACE_FUNCTION_ZU(VG_Z_MSVCR90,malloc) (SizeT n) {
   if (!init_done) init();
   MALLOC_TRACE("windows malloc" "(%llu)", (ULong)n );

   char *ret = __target_kernel32_HeapAlloc(__target_kernel32_GetProcessHeap(),0, n+MAGIC_ALLOCATOR_SIZE);
   if (!ret)
       __target_msvcrt90__set_errno(MSVCRT_ENOMEM);
   else {
       /* Remember type of this allocation. */
       *ret = MAGIC_ALLOCATOR_MALLOC;
   }
   return ret + MAGIC_ALLOCATOR_SIZE;
}

/* Similar overrides for new and new[], using their visual c++ mangled names. *
/* Similar overrides for free, delete and delete[] which would
 * check the preamble and throw an error if mismatch detected.
 */
/* All of above defined for visual c++ 6, 2003 (7), 2005 (8) and 2008 (9). */

but I have not yet figured out how to call
functions in the target app from within an interceptor.
Presumably we can look up the function addresses and cache them?
Comment 1 Dan Kegel 2009-12-06 18:33:36 UTC
Created attachment 38876 [details]
Patch to add soname definitions for Visual C++ 2005 and 2008

To intercept functions in msvcr90, you have to apply this
patch, download the .pdb file for msvcr90 by running an
app under windbg using the microsoft symbol server (it's worth
spending a day getting comfortable with windbg if you're
going to be hacking on this stuff), and then copying
that .pdb file into the same directory in ~/.wine where
msvcr90 lives (and giving it the same name as the .dll but with .pdb suffix).

You also have to build your test app with visual c++
(as valgrind can't handle the debugging info produced by mingw yet) 
and use the /MD option to get it to use msvcr90.dll 
(as visual c++'s default is to use a static C runtime library).