Fix 353891 Assert 'bad_scanned_addr < VG_ROUNDDN(start+len, sizeof(Addr))' failed
All memory dereferences during leak search are checked either with
aspacemgr or using the VA-bits.
So, in theory, no memory fault should occur.
However, the leak search is done so as to resist to e.g.
- desynchronisation between the real pages mapped and the aspacemgr state.
- client pages mprotected against reading
- any other reason why dereferencing a client address would fail.
So, the function lc_scan_memory installs a fault catcher that
is called if a memory fault signal is raised during memory scan.
However, memory dereference is also done in the function heuristic_reachedness.
So, this function must also resist to memory fault.
This patch also installs a fault catcher for the function heuristic_reachedness.
More in details, the following changes are done:
* pub_tool_signal.h and m_signals.c :
VG_(set_fault_catcher) now returns the previously set fault catcher.
This is needed so that heuristic_reachedness/lc_scan_memory can save
and restore the previous fault catcher.
* mc_leakcheck.c:
Addition of leak_search_fault_catcher that contains the common
code for the (currently 2) fault catchers used during leak search.
* Modification of heuristic_reachedness and lc_scan_memory:
Add 2 (small) specific fault catcher that are calling the common
leak_search_fault_catcher.
* The way sigprocmask is handled has been changed:
Before this patch, lc_scan_memory was saving/restoring the procsigmask
for each scanned block (and was restoring it when the fault catcher
was longjmp-ing back to lc_scan_memory in case of SEGV or BUS.
This was causing 2 system calls for each block scanned.
Now, lc_scan_memory and heuristic_reachedness are not saving/restoring
the procmask: the work to reset the sigprocmask is only done
in leak_search_fault_catcher. This is more efficient as no syscall
anymore is done during leak search, except for (normally) unfrequent
SIGSEGV/BUS. It is also simpler as signal handling is now done at
a single place.
It is ok to reset the procmask (in fact, just remove the caught signal
from the process sigmask) as during leak search, no other activity than
the leak search is on-going, and so no other SEGV/BUS can be received
while the handler runs.
This gives moderate speed improvements for applications allocating a lot of
blocks (about 10% improvement when leak searching in 1 million small blocks).
Test case (slightly modified) by Matthias Schwarzott.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15716 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/include/pub_tool_signals.h b/include/pub_tool_signals.h
index c346504..1bab478 100644
--- a/include/pub_tool_signals.h
+++ b/include/pub_tool_signals.h
@@ -36,11 +36,14 @@
// Register an interest in apparently internal faults; used code which
// wanders around dangerous memory (ie, leakcheck). The catcher is
// not expected to return.
+// Returns the previously set fault_catcher (NULL if there was no fault
+// catcher set)
//
// It's frustrating that we need this header for a single function used
// only by Memcheck during leak checking. We should find a way to remove
// the need for this file.
-extern void VG_(set_fault_catcher)(void (*catcher)(Int sig, Addr addr));
+typedef void (*fault_catcher_t)(Int sig, Addr addr);
+extern fault_catcher_t VG_(set_fault_catcher)(fault_catcher_t catcher);
#endif // __PUB_TOOL_SIGNALS_H