From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16607 invoked by alias); 4 Mar 2004 22:28:03 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 16520 invoked from network); 4 Mar 2004 22:28:01 -0000 Received: from unknown (HELO nevyn.them.org) (66.93.172.17) by sources.redhat.com with SMTP; 4 Mar 2004 22:28:01 -0000 Received: from drow by nevyn.them.org with local (Exim 4.30 #1 (Debian)) id 1Az1Jw-0008Ki-MY; Thu, 04 Mar 2004 17:28:00 -0500 Date: Fri, 19 Mar 2004 00:09:00 -0000 From: Daniel Jacobowitz To: Atsushi Nemoto Cc: gdb-patches@sources.redhat.com Subject: Re: remote debugging a multi-threaded program with signal Message-ID: <20040304222800.GA29911@nevyn.them.org> Mail-Followup-To: Atsushi Nemoto , gdb-patches@sources.redhat.com References: <20040304.010624.59462252.anemo@mba.ocn.ne.jp> <20040305.000540.59461353.anemo@mba.ocn.ne.jp> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040305.000540.59461353.anemo@mba.ocn.ne.jp> User-Agent: Mutt/1.5.1i X-SW-Source: 2004-03/txt/msg00076.txt.bz2 Message-ID: <20040319000900.0qkHIYBWZdSSVVNTp8fx7c9AhfJ5fdG8PxCZoAXrr5Q@z> On Fri, Mar 05, 2004 at 12:05:40AM +0900, Atsushi Nemoto wrote: > >>>>> On Thu, 04 Mar 2004 01:06:24 +0900 (JST), Atsushi Nemoto said: > > anemo> There is a program on remote-debugging a multi-threaded program > anemo> which uses signals. After receiving a signal (configured to > anemo> "nostop"), the thread which receives it resumes normally but > anemo> other threads leave stopped. > > The last packet sent to gdbserver is "$vCont;C1e:402" (see gdb.output1). > > gdb's info states: > > `vCont'[;ACTION[`:'TID]]... -- extended resume > Resume the inferior. Different actions may be specified for each > thread. If an action is specified with no TID, then it is applied > to any threads that don't have a specific action specified; if no > default action is specified then other threads should remain > stopped. ... > > So the patcket means "continue thread 0x402 with signal 0x1e, others > remain stopped". Then current gdbserver's behavior is correct. > > Following the info statements, gdb should send "$vCont;C1e:402;c" to > handle a "nostop" signal correctly? I thought you said you got the same results without verbose-resume? Oh, I suppose you would; without verbose-resume it's pot-luck which thread gets the signal. If I use a pre-vCont gdb client with the current gdbserver I see: [sigtest:30016:16384]:main [sigtest:30018:16386]:func [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 [sigtest:30016:16384]:send SIGUSR1 This means that the signal is being delivered to the wrong thread, since neither thread appears to be stopped. Which is what I would expect without vCont, since vCont was intended to solve this exact problem. GDB's behavior with threads is a little under-specified, but code to generate the "correct" vCont packet is definitely there. Unfortunately it is not reached. We get this: Breakpoint 1, remote_vcont_resume (ptid={pid = 16386, lwp = 0, tid = 0}, step=0, siggnal=TARGET_SIGNAL_USR1) at /opt/src/gdb/src/gdb/remote.c:2461 i.e. the remote target was asked to resume only one thread. Aha, here's the bug: /* If it's not SIGTRAP and not a signal we want to stop for, then continue the thread. */ if (stop_signal != TARGET_SIGNAL_TRAP && !signal_stop[stop_signal]) { if (printed) target_terminal_inferior (); /* Clear the signal if it should not be passed. */ if (signal_program[stop_signal] == 0) stop_signal = TARGET_SIGNAL_0; target_resume (ecs->ptid, 0, stop_signal); prepare_to_wait (ecs); return; } That resumes only the thread in question. This is in target-indepenedent code and the only reason that lin-lwp native execution does not show the same problem is that it shortcuts around this code completely (see lin_lwp_wait). Could you try this instead? -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer 2004-03-04 Daniel Jacobowitz * infrun.c (handle_inferior_event): Pass nostop signals to the correct thread. Index: infrun.c =================================================================== RCS file: /cvs/src/src/gdb/infrun.c,v retrieving revision 1.137 diff -u -p -r1.137 infrun.c --- infrun.c 16 Feb 2004 20:49:51 -0000 1.137 +++ infrun.c 4 Mar 2004 22:27:11 -0000 @@ -1918,32 +1918,29 @@ handle_inferior_event (struct execution_ #endif } + context_switch (ecs); + + if (context_hook) + context_hook (pid_to_thread_id (ecs->ptid)); + + flush_cached_frames (); + /* If it's not SIGTRAP and not a signal we want to stop for, then continue the thread. */ if (stop_signal != TARGET_SIGNAL_TRAP && !signal_stop[stop_signal]) { - if (printed) - target_terminal_inferior (); - /* Clear the signal if it should not be passed. */ if (signal_program[stop_signal] == 0) stop_signal = TARGET_SIGNAL_0; - target_resume (ecs->ptid, 0, stop_signal); + resume (currently_stepping (ecs), stop_signal); prepare_to_wait (ecs); return; } - /* It's a SIGTRAP or a signal we're interested in. Switch threads, - and fall into the rest of wait_for_inferior(). */ - - context_switch (ecs); - - if (context_hook) - context_hook (pid_to_thread_id (ecs->ptid)); - - flush_cached_frames (); + /* It's a SIGTRAP or a signal we're interested in. Fall into the + rest of wait_for_inferior(). */ } if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p)