Open GoogleCodeExporter opened 9 years ago
Your explanation looks plausible. Would be great if you could prepare a patch
with fix.
E.g. we can detect if jmp leads to one of perftools functions and don't follow
it.
Original comment by alkondratenko
on 10 Jan 2015 at 8:14
A proper fix will take some effort (and somebody who knows more
about Windows than I do: I am new to it). It is easy to avoid
patching a function that has already been patched, but the problem
is that the patching code assumes that if any function in a module
is patched, then the original free() and realloc() for that module
can be called. Hence these lines in PopulateWindowsFn():
CHECK(windows_fn_[kFree]);
CHECK(windows_fn_[kRealloc]);
In my program, malloc/free/calloc/realloc in the main executable
resolve to functions in MSVCR100, but the new/delete functions are
different. If I simply NULL out the windows_fn_ entry for malloc()
and free() because they are already patched, then
LibcInfoWithPatchFunctions<T>::Perftools_delete() will fail because
it needs to be able to call the original free().
In my program, where all files are compiled with /MD, it turns out
that the addresses for new, delete etc. in static_fn_ for the main
executable are not actually the functions called for new, delete,
etc. I have no idea what these functions do, but they do not seem
to be called. Each is a jump to a short instruction sequence ending
with OUTS (a privileged instruction). My workaround for the bug was
to avoid patching the main executable, but that is not a general
solution.
BTW, the code works accidentally in some builds because the Visual
Studio linker merges identical functions. Some patch functions,
e.g. LibcInfoWithPatchFunctions<T>::Perftools_malloc(), do not
depend on the template parameter, so the linker merges them all.
For those functions the perftools_fn_ entry for all instantiations
of LibcInfoWithPatchFunctions end up pointing to the same function.
LibcInfoWithPatchFunctions<T>::Patch() has this test for whether a
function has already been patched:
if (windows_fn_[i] && windows_fn_[i] != perftools_fn_[i]) {
Logically this tests whether the function has been patched in the
current module but, because of the linker optimization, for
functions like malloc() it accidentally checks whether the function
has been patched in any module.
Original comment by manojkum...@gmail.com
on 14 Jan 2015 at 7:08
You can certainly quite safely assume that nobody will fix this before you can.
So you have time for "some effort".
Right now project lacks anybody with decent attention to windows issues.
Original comment by alkondratenko
on 18 Jan 2015 at 3:47
Original issue reported on code.google.com by
manojkum...@gmail.com
on 7 Jan 2015 at 3:38