https://bugs.kde.org/show_bug.cgi?id=441474
Bug ID: 441474
Summary: vgdb might eat all memory while waiting for sigstop
Product: valgrind
Version: unspecified
Platform: Other
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
In coregrind/vgdb-invoker-ptrace.c we have this code:
/* pid received a signal which is not the signal we are waiting for.
If we have not (yet) changed the registers of the inferior
or we have (already) reset them, we can transmit the signal.
If we have already set the registers of the inferior, we cannot
transmit the signal, as this signal would arrive when the
gdbserver code runs. And valgrind only expects signals to
arrive in a small code portion around
client syscall logic, where signal are unmasked (see e.g.
m_syswrap/syscall-x86-linux.S ML_(do_syscall_for_client_WRK).
As ptrace is forcing a call to gdbserver by jumping
'out of this region', signals are not masked, but
will arrive outside of the allowed/expected code region.
So, if we have changed the registers of the inferior, we
rather queue the signal to transmit them when detaching,
after having restored the registers to the initial values. */
if (pid_of_save_regs) {
siginfo_t *newsiginfo;
// realloc a bigger queue, and store new signal at the end.
// This is not very efficient but we assume not many sigs are queued.
if (signal_queue_sz >= 64) {
DEBUG(0, "too many queued signals while waiting for SIGSTOP\n");
return False;
}
signal_queue_sz++;
signal_queue = vrealloc(signal_queue,
sizeof(siginfo_t) * signal_queue_sz);
newsiginfo = signal_queue + (signal_queue_sz - 1);
res = ptrace (PTRACE_GETSIGINFO, pid, NULL, newsiginfo);
This is inside a while (1) loop and could run infinitely when valgrind itself
is crashing (getting a SIGSEGV over and over again). I haven't identified
precisely why valgrind is failing (it is only on s390x during the
gdbserver_tests/nlvgdbsigqueue testcase), but I propose to limit this loop and
bail out after having seen 64 non SIGSTOP signals, so that vgdb isn't stuck
inside this loop slowly eating all memory:
t a/coregrind/vgdb-invoker-ptrace.c b/coregrind/vgdb-invoker-ptrace.c
index 389748960..07f3400f9 100644
--- a/coregrind/vgdb-invoker-ptrace.c
+++ b/coregrind/vgdb-invoker-ptrace.c
@@ -300,6 +300,10 @@ Bool waitstopped (pid_t pid, int signal_expected, const
char *msg)
// realloc a bigger queue, and store new signal at the end.
// This is not very efficient but we assume not many sigs are queued.
+ if (signal_queue_sz >= 64) {
+ DEBUG(0, "too many queued signals while waiting for SIGSTOP\n");
+ return False;
+ }
signal_queue_sz++;
signal_queue = vrealloc(signal_queue,
sizeof(siginfo_t) * signal_queue_sz);
Note that this is different from bug #434035 since that involved a fatal
signal, in this case the signal (SIGSEGV) isn't fatal since valgrind tries to
handle it (but fails).
--
You are receiving this mail because:
You are watching all bug changes.