You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
LibcInfo::PopulateWindowsFn() in src/windows/patch_functions.cc
has this code to deal with multiple modules using the same symbol:
// There's always a chance that our module uses the same function
// as another module that we've already loaded. In that case, we
// need to set our windows_fn to NULL, to avoid double-patching.
for (int ifn = 0; ifn < kNumFunctions; ifn++) {
for (int imod = 0;
imod < sizeof(g_module_libcs)/sizeof(*g_module_libcs); imod++) {
if (g_module_libcs[imod]->is_valid() &&
this->windows_fn(ifn) == g_module_libcs[imod]->windows_fn(ifn)) {
windows_fn_[ifn] = NULL;
}
}
}
I am not sure this works. An earlier line sets windows_fn_:
windows_fn_[i] = PreamblePatcher::ResolveTarget(fn);
The problem is that ResolveTarget() chases JMP instructions. If the
function appeared in an earlier module, it has been patched, and its
first instruction is now a jump to the corresponding
LibcInfoWithPatchFunctions<T>::Perftools_XXX(). So windows_fn_[i]
in the current module gets set to the address of that, but in the
loop you are comparing it with the address of the original Windows
function.
This seems to be the cause of a crash in a program linked with with
libtcmalloc_minimal. PopulateWindowsFn() gets called thrice during
initialization: for MSVCRT, then MSVCR100, and finally the main
executable. In the ModuleEntryCopy argument for the last call, the
addresses of malloc(), free(), realloc(), calloc(), _msize(), and
_expand() are the same as for MSVCR100. The last entry in the
address array, for k_CallocCrt, is calloc() again. But the eight
new/delete function addresses are different and seem to be in the
executable rather than the DLL.
For the functions that are repeated,
PreamblePatcher::RawPatchWithStub() patches
LibcInfoWithPatchFunctions<2>::Perftools_XXX(). It aborts because
Perftools__expand() is too short to patch.
This is a 32-bit executable running on 64-bit Windows 7. The
compiler is VS 2010 SP1. Only the 32-bit debug build of the program
fails. The 32-bit release build works, as do the 64-bit debug and
release builds. All builds are statically linked with the release
build of libtcmalloc_minimal, which is compiled with /MD. I am
using gperftools 2.2.1, but even in 2.3.90 the code in src/windows/
is not significantly different.
Original issue reported on code.google.com by [email protected] on 7 Jan 2015 at 3:38
The text was updated successfully, but these errors were encountered:
Original issue reported on code.google.com by
[email protected]
on 7 Jan 2015 at 3:38The text was updated successfully, but these errors were encountered: