Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tcmalloc crashes on Windows #133

Closed
alk opened this issue Aug 22, 2015 · 13 comments
Closed

tcmalloc crashes on Windows #133

alk opened this issue Aug 22, 2015 · 13 comments

Comments

@alk
Copy link
Contributor

alk commented Aug 22, 2015

Originally reported on Google Code with ID 130

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().


Reported by yinyunqiao on 2009-05-13 14:43:45


- _Attachment: google-perftools-crashes.PNG
![google-perftools-crashes.PNG](https://storage.googleapis.com/google-code-attachments/gperftools/issue-130/comment-0/google-perftools-crashes.PNG)_
@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by csilvers on 2009-05-13 15:20:32

  • Labels added: Type-Defect, Priority-Medium

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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()

Reported by yinyunqiao on 2009-05-13 15:32:58

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by csilvers on 2009-05-13 15:55:11

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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 ) 

Reported by kpatelPro on 2009-06-11 19:21:44

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

} 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!

Reported by csilvers on 2009-06-11 19:57:42

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by ionpulse on 2009-06-15 16:07:36

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by csilvers on 2009-06-15 20:03:11

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by ionpulse on 2009-07-01 23:04:49

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by csilvers on 2009-07-02 02:47:33

@alk
Copy link
Contributor Author

alk commented Aug 22, 2015

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.

Reported by csilvers on 2010-08-02 01:45:21

  • Status changed: CannotReproduce

@alk alk closed this as completed Aug 22, 2015
@pkxpp
Copy link

pkxpp commented Mar 22, 2017

crush in win7, stack info:
> libtcmalloc_minimal.dll!anonymous namespace'::LibcInfo::PopulateWindowsFn(const anonymous-namespace'::ModuleEntryCopy & module_entry) 行 536 C++ libtcmalloc_minimal.dll!anonymous namespace'::PatchMainExecutableLocked() 行 648 C++
libtcmalloc_minimal.dll!anonymous namespace'::PatchAllModules() 行 765 C++ libtcmalloc_minimal.dll!TCMallocGuard::TCMallocGuard() 行 909 + 0x5 字节 C++ libtcmalloc_minimal.dll!dynamic initializer for 'tcmalloc_initializer''() 行 585 + 0xa 字节 C++
msvcr100.dll!6a6a263d()
libtcmalloc_minimal.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved) 行 284 + 0xf 字节 C
libtcmalloc_minimal.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) 行 506 + 0x8 字节 C
libtcmalloc_minimal.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved) 行 476 + 0xe 字节 C
`

@alk
Copy link
Contributor Author

alk commented Apr 16, 2017

Lets open new ticket with all the details. I am afraid that just stack trace won't be enough to debug this. Would be very nice if you can provide simple test program that reproduces the issue.

@chrisdoherty4
Copy link

Was a new ticket opened somewhere and can you link it if so?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants