Bug 12628 - GDB checkpoint can't/shouldn't be possible with multiple threads on Linux
Summary: GDB checkpoint can't/shouldn't be possible with multiple threads on Linux
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: threads (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Kevin Pouget
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-31 11:12 UTC by Kevin Pouget
Modified: 2011-10-05 18:02 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kevin Pouget 2011-03-31 11:12:48 UTC
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)
Comment 1 Kevin Pouget 2011-03-31 14:08:12 UTC
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.
Comment 2 Sourceware Commits 2011-09-15 12:47:14 UTC
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
Comment 3 Kevin Pouget 2011-10-05 18:02:36 UTC
fixed