From 7a8e8974c6883f1271b991a821221694cdddabdd Mon Sep 17 00:00:00 2001 From: das Date: Sun, 10 Apr 2005 02:31:24 +0000 Subject: Suspend all other threads in the process while generating a core dump. The main reason for doing this is that the ELF dump handler expects the thread list to be fixed while the dump header is generated, so an upcall that occurs at the wrong time can lead to buffer overruns and other Bad Things. Another solution would be to grab sched_lock in the ELF dump handler, but we might as well single-thread, since the process is about to die. Furthermore, I think this should ensure that the register sets in the core file are sequentially consistent. --- sys/kern/kern_sig.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'sys/kern') diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 7928120..71427d7 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -2430,7 +2430,16 @@ sigexit(td, sig) PROC_LOCK_ASSERT(p, MA_OWNED); p->p_acflag |= AXSIG; - if (sigprop(sig) & SA_CORE) { + /* + * We must be single-threading to generate a core dump. This + * ensures that the registers in the core file are up-to-date. + * Also, the ELF dump handler assumes that the thread list doesn't + * change out from under it. + * + * XXX If another thread attempts to single-thread before us + * (e.g. via fork()), we won't get a dump at all. + */ + if ((sigprop(sig) & SA_CORE) && (thread_single(SINGLE_NO_EXIT) == 0)) { p->p_sig = sig; /* * Log signals which would cause core dumps @@ -2553,6 +2562,7 @@ coredump(struct thread *td) off_t limit; PROC_LOCK_ASSERT(p, MA_OWNED); + MPASS((p->p_flag & P_HADTHREADS) == 0 || p->p_singlethread == td); _STOPEVENT(p, S_CORE, 0); if (((sugid_coredump == 0) && p->p_flag & P_SUGID) || do_coredump == 0) { -- cgit v1.1