From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15213 invoked by alias); 21 Jul 2006 18:16:12 -0000 Received: (qmail 15205 invoked by uid 22791); 21 Jul 2006 18:16:10 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 21 Jul 2006 18:16:05 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k6LIG13S009085; Fri, 21 Jul 2006 14:16:02 -0400 Received: from pobox.stuttgart.redhat.com (pobox.stuttgart.redhat.com [172.16.2.10]) by int-mx1.corp.redhat.com (8.12.11.20060308/8.12.11) with ESMTP id k6LIG1X4021936; Fri, 21 Jul 2006 14:16:01 -0400 Received: from lace.redhat.com (vpn50-19.rdu.redhat.com [172.16.50.19]) by pobox.stuttgart.redhat.com (8.12.8/8.12.8) with ESMTP id k6LIFwXl018978; Fri, 21 Jul 2006 20:15:59 +0200 Received: from lace.redhat.com (localhost.localdomain [127.0.0.1]) by lace.redhat.com (8.13.6/8.13.6) with ESMTP id k6LIFvbL009579; Fri, 21 Jul 2006 20:15:57 +0200 Received: (from lace@localhost) by lace.redhat.com (8.13.6/8.13.6/Submit) id k6LIFvrA009578; Fri, 21 Jul 2006 20:15:57 +0200 Date: Fri, 21 Jul 2006 18:16:00 -0000 From: Jan Kratochvil To: Daniel Jacobowitz Cc: gdb-patches@sourceware.org Subject: Re: RFC: Fix crash on i386 (%gs-)threaded programs using execve(2) Message-ID: <20060721181556.GA9150@lace.redhat.com> References: <20060614105510.GA12067@host0.dyn.jankratochvil.net> <20060614142552.GA15021@nevyn.them.org> <20060615203519.GA9603@host0.dyn.jankratochvil.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="sm4nu43k4a2Rpi4c" Content-Disposition: inline In-Reply-To: <20060615203519.GA9603@host0.dyn.jankratochvil.net> User-Agent: Mutt/1.4.2.1i Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00299.txt.bz2 --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 1710 Hi Daniel, I am now copyright assignment compliant (as Red Hat employee). The mail below was never replied; the patch still applies to the latest CVS. Could you please review it? Thanks, Jan On Thu, 15 Jun 2006 22:35:20 +0200, Jan Kratochvil wrote: ------------------------------------------------------------------------------ Hi Daniel, [ regarding debugging of exec*(2) called from programs using -lpthread ] On Wed, 14 Jun 2006 16:25:52 +0200, Daniel Jacobowitz wrote: ... > Your problem combines two different issues: > > - libthread_db doesn't do anything sensible at the beginning of > execution, before libpthread is initialized. I filed a bug in the > glibc bugzilla about this with a possible patch. http://sourceware.org/bugzilla/show_bug.cgi?id=2696 Still I do not see much a problem, gdb(1) just runs in non-threaded mode and with my patch it properly drops back to the non-threaded mode after exec*(2). > - gdb thinks threading is still active after an exec. > > We already have a way to detect exec events: PTRACE_EVENT_EXEC. > Support for it is disabled, because it really doesn't work very well, Does the rewritten patch look fine? Why was follow_exec() enabled only for HP-UX? (and in fact it would have to be enabled there by hand) ... > Oh, and please don't add more tests to the testsuite which would spin > forever if detached from GDB; we've already got a few and I'm convinced > in hindsight that it was a mistake. You only need it to exec once, so > you could make it quietly exit the second time. I did not understood the problem exactly; I dropped my test case as it is already tested by the existing (originally HP-UX only) "gdb.base/foll-exec". Thanks, Jan --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="gdb-cvs20060614-follow_exec.patch" Content-length: 5156 Index: inf-ptrace.c =================================================================== RCS file: /cvs/src/src/gdb/inf-ptrace.c,v retrieving revision 1.32 diff -u -p -r1.32 inf-ptrace.c --- inf-ptrace.c 24 Jan 2006 22:34:34 -0000 1.32 +++ inf-ptrace.c 15 Jun 2006 19:49:24 -0000 @@ -166,8 +166,10 @@ inf_ptrace_mourn_inferior (void) /* Wait just one more time to collect the inferior's exit status. Do not check whether this succeeds though, since we may be dealing with a process that we attached to. Such a process will - only report its exit status to its original parent. */ - waitpid (ptid_get_pid (inferior_ptid), &status, 0); + only report its exit status to its original parent. + WNOHANG is required as on follow_exec() (due to TARGET_WAITKIND_EXECD) + resulted from waitpid(2) and it called us by target_mourn_inferior(). */ + waitpid (ptid_get_pid (inferior_ptid), &status, WNOHANG); unpush_target (ptrace_ops_hack); generic_mourn_inferior (); Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.210 diff -u -p -r1.210 infrun.c --- infrun.c 30 Mar 2006 16:37:13 -0000 1.210 +++ infrun.c 15 Jun 2006 19:49:31 -0000 @@ -47,6 +47,7 @@ #include "language.h" #include "solib.h" #include "main.h" +#include "objfiles.h" #include "gdb_assert.h" #include "mi/mi-common.h" @@ -109,10 +110,10 @@ int sync_execution = 0; static ptid_t previous_inferior_ptid; /* This is true for configurations that may follow through execl() and - similar functions. At present this is only true for HP-UX native. */ + similar functions. */ #ifndef MAY_FOLLOW_EXEC -#define MAY_FOLLOW_EXEC (0) +#define MAY_FOLLOW_EXEC (1) #endif static int may_follow_exec = MAY_FOLLOW_EXEC; @@ -382,6 +383,7 @@ follow_exec (int pid, char *execd_pathna { int saved_pid = pid; struct target_ops *tgt; + struct objfile *objfile, *objfile_temp; if (!may_follow_exec) return; @@ -427,6 +429,19 @@ follow_exec (int pid, char *execd_pathna error (_("Could find run target to save before following exec")); gdb_flush (gdb_stdout); + + /* As symbol_file_add_main()->thread_db_new_objfile()->check_for_thread_db() + * would fine already loaded libpthread.so while the threading structures + * would not be yet initialized for this early inferior. + * Call before target_mourn_inferior() as it will breakpoint_re_set(). */ + clear_solib (); + /* Do not: symbol_file_clear()->clear_symtab_users()->breakpoint_re_set(). */ + ALL_OBJFILES_SAFE (objfile, objfile_temp) + { + free_objfile (objfile); + } + symfile_objfile = NULL; + target_mourn_inferior (); inferior_ptid = pid_to_ptid (saved_pid); /* Because mourn_inferior resets inferior_ptid. */ Index: linux-thread-db.c =================================================================== RCS file: /cvs/src/src/gdb/linux-thread-db.c,v retrieving revision 1.16 diff -u -p -r1.16 linux-thread-db.c --- linux-thread-db.c 5 May 2006 22:42:43 -0000 1.16 +++ linux-thread-db.c 15 Jun 2006 19:49:33 -0000 @@ -945,6 +945,10 @@ thread_db_wait (ptid_t ptid, struct targ if (ourstatus->kind == TARGET_WAITKIND_EXITED) return pid_to_ptid (-1); + /* Threading structures got reset. Return as nonthreaded. */ + if (ourstatus->kind == TARGET_WAITKIND_EXECD) + return pid_to_ptid (GET_PID (ptid)); + if (ourstatus->kind == TARGET_WAITKIND_STOPPED && ourstatus->value.sig == TARGET_SIGNAL_TRAP) /* Check for a thread event. */ @@ -1111,6 +1115,9 @@ thread_db_mourn_inferior (void) the inferior, so that we don't try to uninsert them. */ remove_thread_event_breakpoints (); + /* Destroy thread info; it's no longer valid. */ + init_thread_list (); + /* Detach thread_db target ops. */ unpush_target (&thread_db_ops); using_thread_db = 0; Index: testsuite/gdb.base/foll-exec.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/foll-exec.exp,v retrieving revision 1.2 diff -u -p -r1.2 foll-exec.exp --- testsuite/gdb.base/foll-exec.exp 6 Mar 2001 08:21:50 -0000 1.2 +++ testsuite/gdb.base/foll-exec.exp 15 Jun 2006 19:49:34 -0000 @@ -45,12 +45,6 @@ if { [gdb_compile "${srcdir}/${subdir}/ } -# Until "catch exec" is implemented on other targets... -# -if ![istarget "hppa*-hp-hpux*"] then { - continue -} - proc zap_session {} { global gdb_prompt global binfile @@ -212,7 +206,9 @@ proc do_exec_tests {} { setup_xfail hppa2.0w-hp-hpux* CLLbs16760 send_gdb "continue\n" gdb_expect { - -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .START..*$gdb_prompt $"\ + # It is OS dependent and no symbols may be found, GNU/Linux has "_start" + # while HP-UX has " in .START..*$gdb_prompt" etc. + -re ".*Executing new program:.*${testfile2}.*Catchpoint .*(exec\'d .*${testfile2}).*in .*$gdb_prompt $"\ {pass "hit catch exec"} -re "$gdb_prompt $" {fail "hit catch exec"} timeout {fail "(timeout) hit catch exec"} --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="gdb.sum.diff" Content-length: 6994 --- - 2006-06-15 21:42:30.996632000 +0200 +++ testsuite/gdb.sum 2006-06-15 21:33:45.000000000 +0200 @@ -1,4 +1,4 @@ -Test Run By lace on Wed Jun 14 08:49:44 2006 +Test Run By lace on Thu Jun 15 21:19:26 2006 Native configuration is i686-pc-linux-gnu === gdb tests === @@ -385,8 +385,8 @@ PASS: gdb.base/bigcore.exp: tbreak 264 PASS: gdb.base/bigcore.exp: continue PASS: gdb.base/bigcore.exp: next -PASS: gdb.base/bigcore.exp: extract next heap (stop at 50) -PASS: gdb.base/bigcore.exp: extract prev heap (stop at 50) +PASS: gdb.base/bigcore.exp: extract next heap +PASS: gdb.base/bigcore.exp: extract prev heap PASS: gdb.base/bigcore.exp: save heap size PASS: gdb.base/bigcore.exp: grab pid PASS: gdb.base/bigcore.exp: signal SIGABRT @@ -2730,6 +2730,33 @@ Running ../.././gdb/testsuite/gdb.base/float.exp ... PASS: gdb.base/float.exp: info float Running ../.././gdb/testsuite/gdb.base/foll-exec.exp ... +PASS: gdb.base/foll-exec.exp: step to exec call +PASS: gdb.base/foll-exec.exp: print follow-exec/global_i +PASS: gdb.base/foll-exec.exp: print follow-exec/local_j +PASS: gdb.base/foll-exec.exp: print follow-exec/local_k +PASS: gdb.base/foll-exec.exp: step through execlp call +PASS: gdb.base/foll-exec.exp: step after execlp call +PASS: gdb.base/foll-exec.exp: print execd-program/global_i (after execlp) +PASS: gdb.base/foll-exec.exp: print execd-program/local_j (after execlp) +PASS: gdb.base/foll-exec.exp: print follow-exec/local_k (after execlp) +PASS: gdb.base/foll-exec.exp: set catch exec +PASS: gdb.base/foll-exec.exp: info shows catchpoint without exec pathname +PASS: gdb.base/foll-exec.exp: hit catch exec +PASS: gdb.base/foll-exec.exp: sync up after possible failure 1 +PASS: gdb.base/foll-exec.exp: sync up after possible failure 2 +PASS: gdb.base/foll-exec.exp: info shows catchpoint exec pathname +PASS: gdb.base/foll-exec.exp: continue after hit catch exec +PASS: gdb.base/foll-exec.exp: prepare to jump to execl call +PASS: gdb.base/foll-exec.exp: jump to execl call +PASS: gdb.base/foll-exec.exp: step through execl call +PASS: gdb.base/foll-exec.exp: step after execl call +PASS: gdb.base/foll-exec.exp: print execd-program/local_j (after execl) +PASS: gdb.base/foll-exec.exp: prepare to jump to execv call +PASS: gdb.base/foll-exec.exp: jump to execv call +PASS: gdb.base/foll-exec.exp: step through execv call +PASS: gdb.base/foll-exec.exp: step after execv call +PASS: gdb.base/foll-exec.exp: print execd-program/local_j (after execv) +PASS: gdb.base/foll-exec.exp: continue through exec Running ../.././gdb/testsuite/gdb.base/foll-fork.exp ... Running ../.././gdb/testsuite/gdb.base/foll-vfork.exp ... Running ../.././gdb/testsuite/gdb.base/freebpcmd.exp ... @@ -11226,16 +11253,27 @@ PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 3 (fast) PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 4 (fast) PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 5 (fast) -FAIL: gdb.threads/print-threads.exp: Running threads (fast) (unknown output) -FAIL: gdb.threads/print-threads.exp: setting breakpoint at main -FAIL: gdb.threads/print-threads.exp: break thread_function (2) +PASS: gdb.threads/print-threads.exp: program exited normally +PASS: gdb.threads/print-threads.exp: all threads ran once (fast) +PASS: gdb.threads/print-threads.exp: break thread_function (2) PASS: gdb.threads/print-threads.exp: set var slow = 1 -FAIL: gdb.threads/print-threads.exp: Running threads (slow) (unknown output) -FAIL: gdb.threads/print-threads.exp: setting breakpoint at main -FAIL: gdb.threads/print-threads.exp: break thread_function (3) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 1 (slow) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 2 (slow) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 3 (slow) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 4 (slow) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 5 (slow) +PASS: gdb.threads/print-threads.exp: program exited normally +PASS: gdb.threads/print-threads.exp: all threads ran once (slow) +PASS: gdb.threads/print-threads.exp: break thread_function (3) PASS: gdb.threads/print-threads.exp: set var slow = 1 (2) -FAIL: gdb.threads/print-threads.exp: break kill -FAIL: gdb.threads/print-threads.exp: Running threads (slow with kill breakpoint) (unknown output) +PASS: gdb.threads/print-threads.exp: break kill +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 1 (slow with kill breakpoint) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 2 (slow with kill breakpoint) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 3 (slow with kill breakpoint) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 4 (slow with kill breakpoint) +PASS: gdb.threads/print-threads.exp: Hit thread_function breakpoint, 5 (slow with kill breakpoint) +PASS: gdb.threads/print-threads.exp: program exited normally +PASS: gdb.threads/print-threads.exp: all threads ran once (slow with kill breakpoint) Running ../.././gdb/testsuite/gdb.threads/pthread_cond_wait.exp ... PASS: gdb.threads/pthread_cond_wait.exp: successfully compiled posix threads test case PASS: gdb.threads/pthread_cond_wait.exp: breakpoint on break_me @@ -11356,7 +11394,7 @@ PASS: gdb.threads/staticthreads.exp: rerun to main PASS: gdb.threads/staticthreads.exp: handle SIG32 nostop noprint pass FAIL: gdb.threads/staticthreads.exp: handle SIG32 helps -KFAIL: gdb.threads/staticthreads.exp: info threads (PRMS: gdb/1328) +PASS: gdb.threads/staticthreads.exp: info threads PASS: gdb.threads/staticthreads.exp: GDB exits with static thread program Running ../.././gdb/testsuite/gdb.threads/step.exp ... Running ../.././gdb/testsuite/gdb.threads/step2.exp ... @@ -11454,9 +11492,8 @@ PASS: gdb.threads/tls.exp: 3 info address another_thread_local PASS: gdb.threads/tls.exp: threads exited PASS: gdb.threads/tls.exp: Expect only base thread at end -FAIL: gdb.threads/tls.exp: running to spin in runto (timeout) -FAIL: gdb.threads/tls.exp: info address a_global (timeout) -KFAIL: gdb.threads/tls.exp: info address me (timeout) (PRMS: gdb/1294) +PASS: gdb.threads/tls.exp: info address a_global +KFAIL: gdb.threads/tls.exp: info address me (PRMS: gdb/1294) Running ../.././gdb/testsuite/gdb.threads/watchthreads.exp ... PASS: gdb.threads/watchthreads.exp: successfully compiled posix threads test case PASS: gdb.threads/watchthreads.exp: watch args[0] @@ -11608,12 +11645,12 @@ === gdb Summary === -# of expected passes 11048 -# of unexpected failures 52 +# of expected passes 11096 +# of unexpected failures 42 # of unexpected successes 1 # of expected failures 42 # of unknown successes 9 -# of known failures 75 +# of known failures 74 # of untested testcases 4 # of unsupported tests 13 /home/lace/redhat/src/gdb/testsuite/../../gdb/gdb version 6.5.50.20060614-cvs -nx --sm4nu43k4a2Rpi4c--