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: jsew...@acm.org Reporter: m...@klomp.org 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.