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
{{ message }}
Repository navigation
Linux: dump fails with EIO when a thread stack mapping runs into a MADV_GUARD_INSTALL guard page (glibc ≥ 2.42) #244
On Linux with glibc 2.42+ and kernel 6.13+, minidumps of multi-threaded processes fail as a whole, because a thread's stack copy runs into a neighbouring thread's guard page.
What happens
glibc 2.42 creates pthread stack guard pages with madvise(MADV_GUARD_INSTALL) rather than a separate PROT_NONE mapping. Those guard regions don't appear in /proc/<pid>/maps, so adjacent thread stacks can merge into a single rw-p VMA. get_stack_info returns the range from the stack pointer to the end of that mapping, fill_thread_stack copies the whole range, and the copy fails when it reaches the next stack's guard page (reads of guard regions fail with EIO). The error propagates out of write_thread_list_stream and the dump is abandoned.
GDB hit the same issue with merged thread stack VMAs and fixed it in binutils-gdb c1da013.
Observed
Fedora 43, x86_64, glibc 2.42, a Tauri (WebKitGTK) app with about 50 threads, through sentry-rust-minidump → minidumper-child 0.2 → minidumper 0.8.3 → minidump-writer 0.8.9. ptrace_scope is 0, and SELinux logged no denials. Tracing the crash reporter process, PTRACE_ATTACH succeeds for every thread, then:
after which the dump is abandoned, leaving a 236-byte minidump file. The same app's native crashes are captured fine on macOS and Windows.
Latest release
As far as I can read 0.13.0, the same path still fails the dump: fill_thread_stack propagates the copy_from_process error with ?, and write_dump treats an error from write_thread_list_stream as fatal. I haven't run 0.13.0, so I can't say whether its process reader returns a short read rather than an error at the guard page.
Coincidentally we've been working on adjacent parts of the code recently, so the situation has gotten marginally better with the main branch. The writer won't fail outright, just record the failure to dump the thread stacks in the produced minidump. We still need to fix this, though.
We've been shipping the soft error code in Firefox since mid-september, so I would have expected the number of crash reports with empty stacks to rise significantly since then. Interestingly, it didn't. In parallel, I have reproduced the problem easily with toy programs. Both facts seem contradictory.
A little bit of digging explained why: it turns out that the issue was fixed (or at least greatly alleviated) by 07c2bd2 or even possibly earlier. Sadly, what @marti4d giveth, @marti4d taketh away: in f432734, copy_from_process switched from using read_to_vec to read_all_to_vec, thus reverting back to a strict read.
Activity
schopin-mozilla commentedon Oct 6, 2026
Coincidentally we've been working on adjacent parts of the code recently, so the situation has gotten marginally better with the main branch. The writer won't fail outright, just record the failure to dump the thread stacks in the produced minidump. We still need to fix this, though.
schopin-mozilla commentedon Oct 7, 2026
We've been shipping the soft error code in Firefox since mid-september, so I would have expected the number of crash reports with empty stacks to rise significantly since then. Interestingly, it didn't. In parallel, I have reproduced the problem easily with toy programs. Both facts seem contradictory.
A little bit of digging explained why: it turns out that the issue was fixed (or at least greatly alleviated) by 07c2bd2 or even possibly earlier. Sadly, what @marti4d giveth, @marti4d taketh away: in f432734,
copy_from_processswitched from usingread_to_vectoread_all_to_vec, thus reverting back to a strict read.linux: read the stacks right up until the guard page
linux: read the stacks right up until the guard page
linux: read the stacks right up until the guard page