From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19945 invoked by alias); 23 Jan 2006 15:52:46 -0000 Received: (qmail 19924 invoked by uid 22791); 23 Jan 2006 15:52:45 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Mon, 23 Jan 2006 15:52:43 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1F13zk-0004YN-9o; Mon, 23 Jan 2006 10:52:40 -0500 Date: Mon, 23 Jan 2006 16:02:00 -0000 From: Daniel Jacobowitz To: Vladimir Prus Cc: gdb@sources.redhat.com Subject: Re: Multithreaded debugging: strange thread switches Message-ID: <20060123155240.GA16524@nevyn.them.org> Mail-Followup-To: Vladimir Prus , gdb@sources.redhat.com References: <200601231820.33372.ghost@cs.msu.su> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200601231820.33372.ghost@cs.msu.su> User-Agent: Mutt/1.5.8i X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2006-01/txt/msg00218.txt.bz2 On Mon, Jan 23, 2006 at 06:20:32PM +0300, Vladimir Prus wrote: > > Hello, > I'm observing strange behaviour when debugging with gdb using a custom stub. > I have two threads. After connecting, I say "next" several times and that > steps in thread 1. Then I say "thread 2" and "next". Gdb then stops again in > thread 1, not in thread 2 as I'd expected. > > In the remote protocol I see "Hc1" packet after last "next" though I'd expect This, generally, is part of the problem. If you want this to work, you need to implement the vCont packet in the stub. The Hc1 packet is supposed to mean "step only thread 1, leaving thread 2 stopped", and that's not what the gdb "next" command is supposed to map to - that's "step this thread but leave other threads free-running". > "Hc2", and in infrun.c, function prepare_to_proceed, I see this: > > > if (!ptid_equal (wait_ptid, minus_one_ptid) > && !ptid_equal (inferior_ptid, wait_ptid)) > { > /* Switched over from WAIT_PID. */ > CORE_ADDR wait_pc = read_pc_pid (wait_ptid); > > if (wait_pc != read_pc ()) > { > /* Switch back to WAIT_PID thread. */ > inferior_ptid = wait_ptid; > > /* FIXME: This stuff came from switch_to_thread() in > thread.c (which should probably be a public function). */ > flush_cached_frames (); > registers_changed (); > stop_pc = wait_pc; > select_frame (get_current_frame ()); > } > > Can somebody explain the reason for this explicit switch back to "wait_ptid"? I have no idea, but if you remove it you're going to bust the bit below that steps over breakpoints, and then GDB will really get unhappy. Maybe we can adjust that block of code, though. See the comment in proceed(): /* In a multi-threaded task we may select another thread and then continue or step. But if the old thread was stopped at a breakpoint, it will immediately cause another breakpoint stop without any execution (i.e. it will report a breakpoint hit incorrectly). So we must step over it first. prepare_to_proceed checks the current thread against the thread that reported the most recent event. If a step-over is required it returns TRUE and sets the current thread to the old thread. */ The current code was modified to always select the previous thread in arch-utils.c revision 1.28 in order to support resuming after hitting Control-C: http://sourceware.org/ml/gdb-patches/2001-05/msg00419.html I can't tell from Jonathan's post what problem he's trying to fix. Previously the thread would only be switched if (SIGTRAP && breakpoint here). Now it's switched if (SIGTRAP || SIGINT) and then we single-step if (breakpoint here). Which doesn't make much sense. -- Daniel Jacobowitz CodeSourcery