This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: Updating pc from wrong inferior
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Cc: Simo Melenius <simo dot melenius at iki dot fi>
- Date: Sat, 6 Mar 2010 00:21:41 +0000
- Subject: Re: Updating pc from wrong inferior
- References: <6575aed11003040543t6ae0cb50j55b00c563ce11b03@mail.gmail.com>
On Thursday 04 March 2010 13:43:59, Simo Melenius wrote:
> [ Disclaimer: I've quite new to gdb so I might have missed something
> obvious, invalidating my patch. ]
>
> I noticed that in gdbserver's linux_wait_for_lwp() the program counter
> is sometimes updated from the wrong inferior. After a breakpoint was
> hit in another thread, get_thread_regcache() was called before
> current_inferior was updated, causing ptrace() getregs to fail on a
> non-stopped thread.
Outch. This code is only reached when gdbserver is
started with the --debug switch, though, so in principle
one only trips on it if debugging something else. :-)
> This in turn caused gdbserver to mess up its communication or
> something, and thus clientside gdb received a bad packet and entered
> into a loop waiting for good data.
>
> I fixed my test case with this patch. If it's OK, I'd like to see it
> included in upstream. Thank you.
Your patch is correct. Thanks for fixing! I've applied this
to mainline, and 7.1 release branch, with this ChangeLog entry:
2010-03-06 Simo Melenius <simo.melenius@iki.fi>
* linux-low.c (linux_wait_for_lwp): Fetch the regcache after
switching the current inferior, not before.
>
>
> kind regards,
> Simo
>
> --- /tmp/CVS/src/gdb/gdbserver/linux-low.c 2010-02-13
> 03:13:54.000000000 +0200
> +++ gdb/gdbserver/linux-low.c 2010-03-04 14:21:20.000000000 +0200
> @@ -1067,11 +1067,12 @@
> && the_low_target.get_pc != NULL)
> {
> struct thread_info *saved_inferior = current_inferior;
> - struct regcache *regcache = get_thread_regcache (current_inferior, 1);
> + struct regcache *regcache;
> CORE_ADDR pc;
>
> current_inferior = (struct thread_info *)
> find_inferior_id (&all_threads, child->head.id);
> + regcache = get_thread_regcache (current_inferior, 1);
> pc = (*the_low_target.get_pc) (regcache);
> fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
> current_inferior = saved_inferior;
>
>
>
--
Pedro Alves