blueszhangsh / gperftools

Automatically exported from code.google.com/p/gperftools
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

tcmalloc crashes on Windows #130

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Get version 1.2 google perftools source
2. Build with vs2005 or vs2008
3. Run any tcmalloc unittest, it will just crash

What is the expected output? What do you see instead?
expect no crash but see crash message:

Unhandled exception at 0x7c958579 in tcmalloc_minimal_unittest.exe: 
0xC0000005: Access violation writing location 0x00030ffc.

What version of the product are you using? On what operating system?
version 1.2 google-perftools build with vs2005 or vs2008 on Windows 
2003/XP.

Please provide any additional information below.

See attatch file, when  PatchMainExecutableLocked() called, the 
PreamblePatcher::ResolveTarget(fn) returnes "operator new[]" instead of
"Perftools_newarray", and then it crashes late at PreamblePatcher::Patch().

Original issue reported on code.google.com by yinyunq...@gmail.com on 13 May 2009 at 2:43

Attachments:

GoogleCodeExporter commented 9 years ago
Hmm, interesting -- thanks for the screenshot, that's very helpful.  The values 
of
windows_ that you see are expected.  While I can't be sure, I'm guessing that 
if you
did a backtrace from the point of the screenshot, it would show you're calling 
this
from PatchMainExecutableLocked().  It's common -- it happens for me too -- that 
the
main executable is already linked into perftools for malloc and free, but not 
for new
and new[].  In fact, I'm a bit surprised your windows_[4] == Perftools_new; for 
me
it's ::operator new.

So the problem is somewhere else.  Where exactly is the crash occurring?  That 
is,
when you run under the debugger and get the access violation, where exactly is 
it?  A
stack trace at that point would be helpful.

It's always difficult to debug remotely, but I'll give it a shot!  Let me know 
what
you see.

Original comment by csilv...@gmail.com on 13 May 2009 at 3:20

GoogleCodeExporter commented 9 years ago
when patch the windows_fn_[i] (= operator new[]) 

     CHECK_EQ(sidestep::SIDESTEP_SUCCESS,
               PreamblePatcher::Patch(windows_fn_[i], perftools_fn_[i],
                                      &origstub_fn_[i]));

it crashes at ::VirtualProtect WIN32 API call:
  BOOL succeeded = ::VirtualProtect(reinterpret_cast<void*>(target_function),
                                    MAX_PREAMBLE_STUB_SIZE, PAGE_READWRITE,
                                    &old_target_function_protect);

backtrace before this call:

libtcmalloc_minimal-
debug.dll!sidestep::PreamblePatcher::RawPatchWithStubAndProtections(void * 
target_function=0x100575a0, void * replacement_function=0x10020072, unsigned 
char * 
preamble_stub=0x009a0060, unsigned long stub_size=32, unsigned long * 
bytes_needed=0x00000000)  Line 129  C++
    libtcmalloc_minimal-debug.dll!sidestep::PreamblePatcher::RawPatch(void * 
target_function=0x100575a0, void * replacement_function=0x10020072, void * * 
original_function_stub=0x100889dc)  Line 219 + 0x15 bytes   C++
    libtcmalloc_minimal-debug.dll!sidestep::PreamblePatcher::Patch<void 
(__cdecl*)(void)>(void (void)* target_function=0x100575a0, void (void)* 
replacement_function=0x10020072, void (void)* * 
original_function_stub=0x100889dc)  
Line 153 + 0x11 bytes   C++
    libtcmalloc_minimal-debug.dll!`anonymous 
namespace'::LibcInfoWithPatchFunctions<0>::Patch(tagMODULEENTRY32 me32={...})  
Line 
463 + 0x25 bytes    C++
    libtcmalloc_minimal-debug.dll!`anonymous 
namespace'::PatchMainExecutableLocked()  Line 550   C++
    libtcmalloc_minimal-debug.dll!`anonymous namespace'::PatchAllModules()  Line 
600 C++
    libtcmalloc_minimal-debug.dll!PatchWindowsFunctions()  Line 613 C++
    libtcmalloc_minimal-debug.dll!TCMallocGuard::TCMallocGuard()  Line 498  C++
    libtcmalloc_minimal-debug.dll!`dynamic initializer for 
'module_enter_exit_hook''()  Line 516 + 0x28 bytes  C++
    msvcr90d.dll!_initterm(void (void)* * pfbegin=0x1006116c, void (void)* * 
pfend=0x100612b8)  Line 903 C
    libtcmalloc_minimal-debug.dll!_CRT_INIT(void * hDllHandle=0x10000000, 
unsigned long dwReason=1, void * lpreserved=0x0012fd28)  Line 318 + 0xf bytes   C
    libtcmalloc_minimal-debug.dll!__DllMainCRTStartup(void * 
hDllHandle=0x10000000, unsigned long dwReason=1, void * lpreserved=0x0012fd28)  
Line 
540 + 0x11 bytes    C
    libtcmalloc_minimal-debug.dll!_DllMainCRTStartup(void * 
hDllHandle=0x10000000, unsigned long dwReason=1, void * lpreserved=0x0012fd28)  
Line 
510 + 0x11 bytes    C

backtrace after this call:

    libtcmalloc_minimal-debug.dll!__security_check_cookie(unsigned int cookie=0)  
Line 55 C
    libtcmalloc_minimal-debug.dll!_FreeLibrary@4()  + 0x1fca bytes  C++
    ntdll.dll!7c958743()    
    [Frames below may be incorrect and/or missing, no symbols loaded for 
ntdll.dll]  
    ntdll.dll!7c9615f3()    
    ntdll.dll!7c95857e()    
    libtcmalloc_minimal-debug.dll!_FreeLibrary@4()  + 0x1fca bytes  C++
    ntdll.dll!7c958772()    
    ntdll.dll!7c958743()    
    ntdll.dll!7c9615f3()    
    ntdll.dll!7c95857e()    
    libtcmalloc_minimal-debug.dll!_FreeLibrary@4()  + 0x1fca bytes  C++
    ntdll.dll!7c958772()    
    ntdll.dll!7c958743()    
    ntdll.dll!7c9615f3()    
    ntdll.dll!7c95857e()    
    libtcmalloc_minimal-debug.dll!_FreeLibrary@4()  + 0x1fca bytes  C++
    ntdll.dll!7c958772()    
    ntdll.dll!7c958743()    
    ntdll.dll!7c9615f3()    
    ntdll.dll!7c95857e()    
    libtcmalloc_minimal-debug.dll!_FreeLibrary@4()  + 0x1fca bytes  C++
    ntdll.dll!7c958772()    
        ...... a lot of _FreeLibrary@4()

Original comment by yinyunq...@gmail.com on 13 May 2009 at 3:32

GoogleCodeExporter commented 9 years ago
Ok, this sounds almost like you have some virus protection software, or other
software, that is trying to protect parts of memory from having their 
protections
changed.  Is that possible?  Is there a way you could try running this code 
with all
extensions disabled?

::VirtualProtect() should not be crashing in any case.  This error is very 
weird:
} 0xC0000005: Access violation writing location 0x00030ffc

Any idea what is at memory location 0x00030ffc?  Maybe right before the crashing
VirtualProtect call, you can examine what's at that memory location, or else 
look at
target_function and see what address it has (though the screenshot shows it 
having a
different address than 30ffc).  Though this address may be some windows-internal
thing, and there's nothing more to say about it.

} LibcInfoWithPatchFunctions<0>::Patch(tagMODULEENTRY32 me32={...})

Hmm, I see you're not patching the global functions after all, but instead the
functions in your first DLL.  It would be interesting to see what the contents 
of
me32 are.

Original comment by csilv...@gmail.com on 13 May 2009 at 3:55

GoogleCodeExporter commented 9 years ago
FWIW, I have gotten this problem as well.

That is, I get it (this crash) on my: 
  Microsoft Windows Server 2003
  Standard x64 Edition
  Service Pack 2
  Intel(R) Xeon(TM) CPU 3.60GHz
  3.59GHz, 2.00 GB of RAM

But NOT (it works) on my:
  Microsoft Windows XP
  Professional
  Version 2002
  Service Pack 2
  Intel(R) Xeon(R) CPU 
  X5355 @ 2.66GHz
  2.66GHz, 3.00 GB of RAM
  Physical Address Extension

Both machines:
  test was tcmalloc_minimal_unittest.exe
  google-perftools-1.3
  Microsoft Visual Studio 2005
  Symantec Endpoint Protection (which I also disabled, still crashed ) 

Original comment by kpatel...@gmail.com on 11 Jun 2009 at 7:21

GoogleCodeExporter commented 9 years ago
} Standard x64 Edition

This makes it sound like this is a 64-bit version of windows.  Is that right?  
If so,
that would definitely explain the problem: tcmalloc is 32-bit only for windows 
right
now.  I don't know what would be involved to get things working on win64, but I
haven't tested at all on that platform.

That said, it's possible the 64-bit-ness isn't the problem here.  If you can 
explore
in some of the same ways I suggested for the original poster, and report what 
you
see, I can look at it to see if it helps figure out what's going on!

Original comment by csilv...@gmail.com on 11 Jun 2009 at 7:57

GoogleCodeExporter commented 9 years ago
I am also getting this problem when using tcmalloc in the Windows 7 beta 
(64-bit)
using Visual C++ 2008 Express. I'm compiling a 32-bit application, however. This
should work, despite my 64-bit OS, correct? Doesn't Chrome use this library? It 
runs
with no problems on my system. Maybe using the overrides instead of patching 
will
work? I can try that and report back my findings.

Original comment by ionpu...@gmail.com on 15 Jun 2009 at 4:07

GoogleCodeExporter commented 9 years ago
I believe it should work if you compile a 32-bit app.  But I admit I don't 
know.  If
you can do any debugging and get some stack traces like in comment 2, I can try 
to
track it down.  It definitely looks like there are some situations the patching
doesn't correctly handle yet.

It's likely that creating your own libc, like chrome does, is more reliable 
than the
run-time patching perftools does by default.  By all means let me know how the
overrides works out!  One day I hope to get patching as reliable as overriding, 
but
it looks like we're not there yet.

Original comment by csilv...@gmail.com on 15 Jun 2009 at 8:03

GoogleCodeExporter commented 9 years ago
Short story: the overrides work.

I had to make the provided libtcmalloc-minimal DLL project produce a static lib
instead, and include the overrides.cc in the project, then just ignore the 
libcmt.lib
default library. I didn't end up having to create a custom CRT either. 

I believe that Windows 7 might have some sort of application protection against 
the
patching method, so it may not be a viable technique on that platform.

Original comment by ionpu...@gmail.com on 1 Jul 2009 at 11:04

GoogleCodeExporter commented 9 years ago
Glad to hear the overriding worked.  I'm still keeping this bug open, in the 
hopes we
can track down this particular crash and maybe fix it.

Original comment by csilv...@gmail.com on 2 Jul 2009 at 2:47

GoogleCodeExporter commented 9 years ago
It's been more than a year, so I think keeping this bug open hasn't been that 
helpful.  Since we never figured out what caused the problem, exactly, and I 
can't reproduce it, I'm closing CannotReproduce.  Feel free to reopen if you 
have more info about what was going on.

Original comment by csilv...@gmail.com on 2 Aug 2010 at 1:45