From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26949 invoked by alias); 13 Jan 2010 15:11:41 -0000 Received: (qmail 26924 invoked by uid 22791); 13 Jan 2010 15:11:40 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Jan 2010 15:11:33 +0000 Received: (qmail 14045 invoked from network); 13 Jan 2010 15:11:32 -0000 Received: from unknown (HELO wind.localnet) (vladimir@127.0.0.2) by mail.codesourcery.com with ESMTPA; 13 Jan 2010 15:11:32 -0000 From: Vladimir Prus To: gdb-patches@sourceware.org Subject: Fix a couple of multiexec races Date: Wed, 13 Jan 2010 15:11:00 -0000 User-Agent: KMail/1.12.2 (Linux/2.6.31-14-generic-pae; KDE/4.3.2; i686; ; ) MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_iKeTLZypvLXzl0R" Message-Id: <201001131811.30403.vladimir@codesourcery.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-01/txt/msg00347.txt.bz2 --Boundary-00=_iKeTLZypvLXzl0R Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-length: 2782 The attached patch fixes a couple of glitches preventing (upcoming) '-exec-run --all' from working. First, consider this code inside linux_nat_wait_1: if (lp && ptid_is_pid (ptid) && ptid_get_pid (lp->ptid) != ptid_get_pid (ptid)) { if (debug_linux_nat) fprintf (stderr, "LWP %ld got an event %06x, leaving pending.\n", ptid_get_lwp (lp->ptid), status); if (WIFSTOPPED (lp->status)) { if (WSTOPSIG (lp->status) != SIGSTOP) { stop_callback (lp, NULL); /* Resume in order to collect the sigstop. */ ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); stop_wait_callback (lp, NULL); } Because lp->status is naturally not NULL when calling stop_callback, and because stop_callback has: gdb_assert (lp->status == 0); if we ever enter the inner "if", GDB will crash. Offlist, Pedro suggested the inner if be just removed. Second change is to address the issue I have reported earlier. I reproduce the original email below. I have read the comment inside cancel_breakpoints_callback, but I am not sure I fully understand it. The situation being handled is when GDB expects an event in thread A, and thread B hits a breakpoint. For all-stop mode, this makes sense -- after all we don't support reporting more than one event, and when user examines event in A he might indeed delete a breakpoint. And if he does not deletes a breakpoint, 'continue' resumes all threads by default, so we'll hit breakpoint in B again. But is this reasonable for non-stop. In non-stop, we get can further stop events while user examines event in A. Further, 'continue' resumes only the current thread. So, if we don't report event in B, user does not have any idea it has to be resumed. What I observe, specifically, is when I use '-exec-run --all' (a local patch), one inferior is not resumed. Here's the relevant bit of 'debug lin-lwp' output: *running,thread-id="2" &"linux_nat_wait: [process 4659]\n" &"LLW: waitpid 4656 received Trace/breakpoint trap (stopped)\n" LWP 4656 got an event 00057f, leaving pending. &"LLW: waitpid 4659 received Trace/breakpoint trap (stopped)\n" &"LLW: Candidate event Trace/breakpoint trap (stopped) in process 4659.\n" &"CB: Push back breakpoint for process 4656\n" And there's no further mention of this pid in the log; it remains stopped. The attached patch appears to improve things. Pedro, what do you think? Note that this patch also comments out the code that tries to stop a thread if it got != SIGSTOP. As discussed offlist, that code fires assertion inside stop_callback. - Volodya --Boundary-00=_iKeTLZypvLXzl0R Content-Type: text/x-patch; charset="UTF-8"; name="races.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="races.diff" Content-length: 1532 commit 12fb288b309af44de0b6709d80d172be852368ad Author: Vladimir Prus Date: Fri Jan 8 17:07:44 2010 +0300 Fix issues preventing '-exec-run --all' from work. * linux-nat.c (linux_nat_wait_1): When getting event in undesired inferior, do not try to resume it and get SIGSTOP. In non-stop, do not try to cancel breakpoints. diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index bf0a5f1..682949d 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3419,20 +3419,9 @@ retry: if (WIFSTOPPED (lp->status)) { - if (WSTOPSIG (lp->status) != SIGSTOP) - { - stop_callback (lp, NULL); - - /* Resume in order to collect the sigstop. */ - ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0); - - stop_wait_callback (lp, NULL); - } - else - { - lp->stopped = 1; - lp->signalled = 0; - } + lp->stopped = 1; + if (WSTOPSIG (lp->status) == SIGSTOP) + lp->signalled = 0; } else if (WIFEXITED (status) || WIFSIGNALED (status)) { @@ -3621,7 +3610,8 @@ retry: /* Now that we've selected our final event LWP, cancel any breakpoints in other LWPs that have hit a GDB breakpoint. See the comment in cancel_breakpoints_callback to find out why. */ - iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp); + if (!non_stop) + iterate_over_lwps (minus_one_ptid, cancel_breakpoints_callback, lp); if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP) { --Boundary-00=_iKeTLZypvLXzl0R--