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

false heap mismatch reported w/o msvcr120 symbols from _calloc_impl() allocation but free() free #1831

Closed
derekbruening opened this issue Dec 1, 2015 · 2 comments

Comments

@derekbruening
Copy link
Contributor

At the very end of a run of 64-bit Chromium unit_tests.exe, at shutdown,
this is reported:

~~Dr.M~~ Error #3: INVALID HEAP ARGUMENT: allocated with Windows API layer, freed with C library layer
~~Dr.M~~ # 0 replace_free                                                       [d:\derek\drmemory\git\src\common\alloc_replace.c:2696]
~~Dr.M~~ # 1 MSVCP120.dll!std::ctype<>::`default constructor closure'          +0x6f     (0x000007fef14aa4e0 <MSVCP120.dll+0xa4e0>)
~~Dr.M~~ # 2 std::`dynamic atexit destructor for '_Fac_tidy_reg''
~~Dr.M~~ # 3 MSVCR120.dll!initterm_e                                           +0x198    (0x000007feefba2925 <MSVCR120.dll+0x22925>)
~~Dr.M~~ # 4 __tmainCRTStartup                                                  [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c:649]
~~Dr.M~~ # 5 KERNEL32.dll!BaseThreadInitThunk
~~Dr.M~~ Note: @2:16:31.446 in thread 1604
~~Dr.M~~ Note: memory was allocated here:
~~Dr.M~~ Note: # 0 replace_RtlAllocateHeap                                      [d:\derek\drmemory\git\src\common\alloc_replace.c:3737]
~~Dr.M~~ Note: # 1 MSVCR120.dll!realloc                                        +0x130    (0x000007feefbe7795 <MSVCR120.dll+0x67795>)
~~Dr.M~~ Note: # 2 MSVCR120.dll!calloc_crt                                     +0x32     (0x000007feefbe6ae7 <MSVCR120.dll+0x66ae7>)
~~Dr.M~~ Note: # 3 MSVCP120.dll!Getctype                                       +0x20     (0x000007fef14de161 <MSVCP120.dll+0x3e161>)
~~Dr.M~~ Note: # 4 MSVCP120.dll!std::ctype<>::_Getcat                          +0x9f     (0x000007fef14aa234 <MSVCP120.dll+0xa234>)
~~Dr.M~~ Note: # 5 MSVCR120.dll!getptd                                         +0x97     (0x000007feefba3490 <MSVCR120.dll+0x23490>)
~~Dr.M~~ Note: # 6 MSVCP120.dll!std::_Lockit::_Lockit                          +0x16     (0x000007fef14ddfab <MSVCP120.dll+0x3dfab>)
~~Dr.M~~ Note: # 7 std::use_facet<>                                             [z:\derek\depot_tools\win_toolchain\vs2013_files\vc\include\xlocale:578]
~~Dr.M~~ Note: # 8 std::operator>><>                                            [z:\derek\depot_tools\win_toolchain\vs2013_files\vc\include\string:36]
~~Dr.M~~ Note: # 9 i18n::phonenumbers::GenericSimpleItoa<>                      [z:\derek\chromium\src\third_party\libphonenumber\src\phonenumbers\stringutil.cc:46]
~~Dr.M~~ Note: #10 i18n::phonenumbers::SimpleItoa                               [z:\derek\chromium\src\third_party\libphonenumber\src\phonenumbers\stringutil.cc:56]
~~Dr.M~~ Note: #11 i18n::phonenumbers::StringHolder::StringHolder               [z:\derek\chromium\src\third_party\libphonenumber\src\phonenumbers\stringutil.cc:199]

This only happens with long runs: M* did not trigger it.

So the alloc is using a libc routine but we're not intercepting until RtlAllocateHeap?

It's not calling the exported realloc():

MSVCR120!calloc_crt+0x2e:
000007fe`efbe6ae2 e8510c0000      call    MSVCR120!realloc+0xd4 (000007fe`efbe7738)

With symbols:

MSVCR120!_calloc_impl+0x57 [f:\dd\vctools\crt\crtw32\heap\calloc_impl.c @ 44]:
000007fe`efbe778f ff154b0c0400    call    qword ptr [MSVCR120!_imp_HeapAlloc (000007fe`efc283e0)]
0:012> U 0x000007feefbe6ae7-5
MSVCR120!_calloc_crt+0x2e [f:\dd\vctools\crt\crtw32\heap\crtheap.c @ 62]:
000007fe`efbe6ae2 e8510c0000      call    MSVCR120!_calloc_impl (000007fe`efbe7738)

So the alloc is from the internal _calloc_impl() but the free is the
exported free(). In a sense, like many similar allocs we've seen before,
this is a mismatch and not very clean code in msvcr120.dll.

We do intercept _calloc_impl so this should go away w/ symbols, but we're
trying to avoid requiring libc symbols.

I don't see this precise thing in a prior issue though the general asymmetry of internal routines being called directly yet not being paired with corresponding internal has been a frequent thorn in our sides.

Xref #1532: free inlined but malloc not in static libc
Xref #643: operator collapse
Xref #1233: no-syms module calling into msvcr*.dll

@derekbruening
Copy link
Contributor Author

Solution: how about if we have no syms (either trust dbghelp query for pdb,
or if we don't find _calloc_impl we assume no syms) for libc then we turn
off API layer mismatch checking? Though that will match most users unless
our auto-symbol-fetch operates properly which it wasn't here -- why not?

Or, we notice that msvcr120 is calling RtlAllocateHeap and disable the
mismatch there? That would require a drwrap_get_retaddr() call and a
module lookup on every replace_RtlAllocateHeap entry which is not
insignificant.

Or, we add a suppression that works for no-syms and syms, which is probably
the route I will go as the other solutions have negatives.

@derekbruening
Copy link
Contributor Author

I did not realize it before but this is really just a variant of #960.

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

1 participant