According to the man page of `fork': A process shall be created with a single thread. If a multi-threaded process calls fork(), the new process shall contain a replica of the calling thread and its entire address space, possibly including the states of mutexes and other resources. Consequently, to avoid errors, the child process may only execute async-signal-safe operations until such time as one of the exec functions is called. Fork handlers may be established by means of the pthread_atfork() function in order to maintain application invariants across fork() calls. Below is a patch which simply forbids to create a checkpoint when GDB knows that there are multiple threads in the debuggee. The Man page obviously assumes a kernel-based thread library, so does my patch (user-level thread libraries should fork correctly), but do we want to handle this situation? (linux-thread-db.c is -- at least was, a few years ago -- tight to GlibC's Pthread implementation, so it might be fine to continue on this way. Cordially, Kevin --- diff --git a/gdb/linux-fork.c b/gdb/linux-fork.c index 7f654af..3eddea4 100644 --- a/gdb/linux-fork.c +++ b/gdb/linux-fork.c @@ -628,6 +628,11 @@ checkpoint_command (char *args, int from_tty) pid_t retpid; struct cleanup *old_chain; + /* Ensure that the inferior is not multithreaded. */ + update_thread_list () ; + if (thread_count () > 1) + error(_("checkpoint: can't checkpoint multiple threads.")) ; + /* Make the inferior fork, record its (and gdb's) state. */ if (lookup_minimal_symbol ("fork", NULL, NULL) != NULL)
Here is a testcase: cat > threads.c << EOF #include <pthread.h> void *thread_fct(void *arg) { return NULL ; } int main (int argc, char *argv) { pthread_t thread ; pthread_create(&thread, NULL, thread_fct, NULL); pthread_join(thread, NULL) ; } EOF gcc -lpthread threads.c -o threads -g gdb threads > break thread_fct > run > [set scheduler-locking on ] #might be necessary > checkpoint > info checkpoint 1 process 5310 at 0x40057c, file threads.c, line 4 Segmentation fault (core dumped) OR > restart 1 /home/kevin/travail/srcs/cvs/gdb/gdb/linux-fork.c:687: internal-error: linux_fork_context: Assertion `oldfp != NULL' failed.
CVSROOT: /cvs/src Module name: src Changes by: kpouget@sourceware.org 2011-09-15 12:47:07 Modified files: gdb : ChangeLog linux-fork.c Log message: 2011-09-15 Kevin Pouget <kevin.pouget@st.com> PR threads/12628 * linux-fork.c (checkpoint_command): Disallow checkpointing of processes with multiple threads. (inf_has_multiple_thread_cb): New function. (inf_has_multiple_threads): New function. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.13333&r2=1.13334 http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/linux-fork.c.diff?cvsroot=src&r1=1.38&r2=1.39
fixed