This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Inadvertently run inferior threads
- From: Eli Zaretskii <eliz at gnu dot org>
- To: Pedro Alves <palves at redhat dot com>
- Cc: gdb-patches at sourceware dot org
- Date: Thu, 11 Jun 2015 16:26:10 +0300
- Subject: Re: Inadvertently run inferior threads
- Authentication-results: sourceware.org; auth=none
- References: <83h9tq3zu3 dot fsf at gnu dot org> <55043A63 dot 6020103 at redhat dot com> <8361a339xd dot fsf at gnu dot org> <5504555C dot 804 at redhat dot com> <550458E0 dot 10206 at redhat dot com> <83y4jrsgui dot fsf at gnu dot org>
- Reply-to: Eli Zaretskii <eliz at gnu dot org>
[I'm taking this to gdb-patches@, as I'm suggesting a patch.]
> Date: Wed, 10 Jun 2015 18:50:13 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> Cc: gdb@sourceware.org
>
> So 'set_running' is called, and it is called with minus_one_ptid,
> which then has the effect of marking all the threads as running.
>
> What I don't understand is why doesn't the breakpoint we set at exit
> from the inferior function countermand that. I do see the effect of
> that breakpoint if I turn on infrun debugging:
>
> infrun: target_wait (-1, status) =
> infrun: 4608 [Thread 4608.0x4900],
> infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
> infrun: TARGET_WAITKIND_STOPPED
> infrun: stop_pc = 0x88ba9f
> infrun: BPSTAT_WHAT_STOP_SILENT
> infrun: stop_waiting
>
> Why don't we mark all threads as stopped when we hit the breakpoint?
> is that because of #3 above?
Answering myself: yes.
> Any ideas how to solve this annoying problem?
One idea is implemented in the patch below. I tested it in a
MinGW-compiled GDB doing native debugging, and it completely solved
the problem for me: I see additional threads started during an
infcall, but none of those dreaded "the selected thread is running"
error messages.
OK to commit (with a suitable ChangeLog entry)?
--- gdb/infrun.c~0 2015-01-13 15:14:47 +0200
+++ gdb/infrun.c 2015-06-11 07:13:54 +0300
@@ -6508,8 +6508,14 @@ normal_stop (void)
running, all without informing the user/frontend about state
transition changes. If this is actually a call command, then the
thread was originally already stopped, so there's no state to
- finish either. */
- if (target_has_execution && inferior_thread ()->control.in_infcall)
+ finish either. Howevever, if target doesn't support asynchronous
+ execution, we must mark all of its threads as stopped, because
+ that's what such targets do when the thread running in an infcall
+ stops. (The cleanup will call finish_thread_state with
+ minus_one_ptid in that case.) */
+ if (target_has_execution
+ && inferior_thread ()->control.in_infcall
+ && target_can_async_p ())
discard_cleanups (old_chain);
else
do_cleanups (old_chain);