[3/3] Fix "Remote 'g' packet reply is too long" problems with multiple inferiors
Commit Message
When debugging two inferiors (or more) against gdbserver, and the
inferiors have different architectures, such as e.g., on x86_64
GNU/Linux and one inferior is 64-bit while the other is 32-bit, then
GDB can get confused with the different architectures in a couple
spots.
In both cases I ran into, GDB incorrectly ended up using the
architecture of whatever happens to be the selected inferior instead
of the architecture of some other given inferior:
#1 - When parsing the expedited registers in stop replies.
#2 - In the default implementation of the target_thread_architecture
target method.
These resulted in instances of the infamous "Remote 'g' packet reply
is too long" error. For example, with the test added in this commit,
we get:
~~~
Continuing.
Remote 'g' packet reply is too long (expected 440 bytes, got 816 bytes): ad064000000000000[snip]
(gdb) FAIL: gdb.multi/multi-arch.exp: inf1 event with inf2 selected: continue to hello_loop
c
Continuing.
Truncated register 50 in remote 'g' packet
(gdb) PASS: gdb.multi/multi-arch.exp: inf2 event with inf1 selected: c
~~~
This commit fixes that.
gdb/ChangeLog:
2017-10-02 Pedro Alves <palves@redhat.com>
* remote.c (get_remote_arch_state): New 'gdbarch' parameter. Use
it instead of target_gdbarch.
(get_remote_state, get_remote_packet_size): Adjust
get_remote_arch_state calls, passing down target_gdbarch
explicitly.
(packet_reg_from_regnum, packet_reg_from_pnum): New parameter
'gdbarch' and use it instead of target_gdbarch.
(get_memory_packet_size): Adjust get_remote_arch_state calls,
passing down target_gdbarch explicitly.
(remote_parse_stop_reply): Use the stopped thread's architecture,
not the current inferior's.
(process_g_packet, remote_fetch_registers)
(remote_prepare_to_store, store_registers_using_G)
(remote_store_registers): Adjust get_remote_arch_state calls,
using the regcache's architecture.
(remote_get_trace_status): Adjust get_remote_arch_state calls,
passing down target_gdbarch explicitly.
* target.c (default_thread_architecture): Use the sepecified
inferior's architecture, instead of the current inferior's
architecture (via target_gdbarch).
gdb/testsuite/ChangeLog:
2017-10-02 Pedro Alves <palves@redhat.com>
* gdb.multi/hangout.c: Include <unistd.h>.
(hangout_loop): New function.
(main): Call alarm. Call hangout_loop in a loop.
* gdb.multi/hello.c: Include <unistd.h>.
(hello_loop): New function.
(main): Call alarm. Call hangout_loop in a loop.
* gdb.multi/multi-arch.exp: Test running to a breakpoint one
inferior with the other selected.
---
gdb/remote.c | 92 ++++++++++++++++++++++++----------
gdb/target.c | 4 +-
gdb/testsuite/gdb.multi/hangout.c | 14 ++++++
gdb/testsuite/gdb.multi/hello.c | 15 +++++-
gdb/testsuite/gdb.multi/multi-arch.exp | 24 +++++++++
5 files changed, 121 insertions(+), 28 deletions(-)
Comments
Pedro Alves <palves@redhat.com> writes:
> @@ -7015,9 +7018,43 @@ Packet: '%s'\n"),
> reason. */
> if (p_temp == p1)
> {
> - struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
> + /* If we haven't parsed the event's thread yet, find
> + it now, in order to find the architecture of the
> + reported expedited registers. */
> + if (event->ptid == null_ptid)
> + {
> + const char *thr = strstr (p1 + 1, ";thread:");
> + if (thr != NULL)
> + event->ptid = read_ptid (thr + strlen (";thread:"),
> + NULL);
> + else
> + event->ptid = magic_null_ptid;
> + }
> +
> + if (rsa == NULL)
> + {
> + inferior *inf = (event->ptid == null_ptid
> + ? NULL
> + : find_inferior_ptid (event->ptid));
> + /* If this is the first time we learn anything
> + about this process, skip the registers
> + included in this packet, since we don't yet
> + know which architecture to use to parse
> + them. */
Could you add a comment about when/how does GDB fetch the target
description of the first-time-seen process?
> + if (inf == NULL)
> + {
> + p = strchrnul (p1 + 1, ';');
> + p++;
> + continue;
> + }
Otherwise, patch is good to me.
Pedro Alves <palves@redhat.com> writes:
> struct gdbarch *
> default_thread_architecture (struct target_ops *ops, ptid_t ptid)
> {
> - return target_gdbarch ();
> + inferior *inf = find_inferior_ptid (ptid);
> + gdb_assert (inf != NULL);
> + return inf->gdbarch;
> }
It is right, but forgot to mention that we need to update
spu_thread_architecture too,
if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
return spu_gdbarch (spufs_fd);
return target_gdbarch ();
it looks wrong to call target_gdbarch. We may need to replace
target_gdbarch with default_thread_architecture.
On Mon, 2 Oct 2017, Pedro Alves wrote:
> When debugging two inferiors (or more) against gdbserver, and the
> inferiors have different architectures, such as e.g., on x86_64
> GNU/Linux and one inferior is 64-bit while the other is 32-bit, then
> GDB can get confused with the different architectures in a couple
> spots.
Another regression. This makes `mips-mti-linux-gnu' GDB stop working
with older stubs. I have discovered it in an attempt to regression-test
said GDB with a remote n64 target and `x86_64-pc-linux-gnu' host, and an
outstanding change which affects non-XML stubs. Any attempt to continue
execution after the initial connection fails with:
[...]
Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 2670
Listening on port 2346
target remote [...]:2346
Remote debugging using [...]:2346
Reading symbols from .../lib64/ld.so.1...done.
[Switching to Thread <main>]
(gdb) continue
Cannot execute this command without a live selected thread.
(gdb)
This is as from commit 5cd63fda035d. Up to 5cd63fda035d^ instead I get:
[...]
Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 30044
Listening on port 2346
target remote [...]:2346
Remote debugging using [...]:2346
Reading symbols from .../lib64/ld.so.1...done.
0x000000fff79534f0 in __start () from .../lib64/ld.so.1
(gdb) continue
Continuing.
warning: Could not load shared library symbols for linux-vdso.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Breakpoint 1, main () at .../gdb/testsuite/gdb.base/advance.c:41
41 c = 5;
(gdb)
At the protocol level the difference starts here (bad):
Sending packet: $qfThreadInfo#bb...Ack
Packet received: m1814
Sending packet: $qsThreadInfo#c8...Ack
Packet received: l
[Switching to Thread <main>]
Sending packet: $qSymbol::#5b...Ack
Packet received: qSymbol:6e70746c5f76657273696f6e
Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
Packet received: OK
Sending packet: $Hg1814#7d...Ack
Packet received: OK
Sending packet: $Hg0#df...Ack
Packet received: E01
(gdb) continue
Cannot execute this command without a live selected thread.
(gdb)
vs (good):
Sending packet: $qfThreadInfo#bb...Ack
Packet received: m154d
Sending packet: $qsThreadInfo#c8...Ack
Packet received: l
Sending packet: $mfff726c4f0,4#cb...Ack
Packet received: 03e0c825
Sending packet: $mfff726c4ec,4#fd...Ack
Packet received: 00000000
Sending packet: $mfff726c4f0,4#cb...Ack
Packet received: 03e0c825
0x000000fff726c4f0 in __start () from .../lib64/ld.so.1
Sending packet: $qSymbol::#5b...Ack
Packet received: qSymbol:6e70746c5f76657273696f6e
Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
Packet received: OK
(gdb) continue
Continuing.
Sending packet: $mfff726c4f0,4#cb...Ack
Packet received: 03e0c825
Sending packet: $Z0,120000d6c,4#36...Ack
Packet received:
Packet Z0 (software-breakpoint) is NOT supported
[...]
The version of `gdbserver' causing this regression is as at commit
f8b73d13b7ca^, the last MIPS backend version with no XML support. It's
likely that later versions hit this regression too, as the mode of failure
is clearly not XML-related.
I'll paste it into Bugzilla too; please feel free to tweak as required,
and, as always, I'll be happy to supply any details missing.
Maciej
On 12/12/2017 09:33 PM, Maciej W. Rozycki wrote:
> On Mon, 2 Oct 2017, Pedro Alves wrote:
>
>> When debugging two inferiors (or more) against gdbserver, and the
>> inferiors have different architectures, such as e.g., on x86_64
>> GNU/Linux and one inferior is 64-bit while the other is 32-bit, then
>> GDB can get confused with the different architectures in a couple
>> spots.
>
> Another regression. This makes `mips-mti-linux-gnu' GDB stop working
> with older stubs. I have discovered it in an attempt to regression-test
> said GDB with a remote n64 target and `x86_64-pc-linux-gnu' host, and an
> outstanding change which affects non-XML stubs. Any attempt to continue
> execution after the initial connection fails with:
>
> [...]
> Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 2670
> Listening on port 2346
> target remote [...]:2346
> Remote debugging using [...]:2346
> Reading symbols from .../lib64/ld.so.1...done.
> [Switching to Thread <main>]
> (gdb) continue
> Cannot execute this command without a live selected thread.
> (gdb)
>
> This is as from commit 5cd63fda035d. Up to 5cd63fda035d^ instead I get:
>
> [...]
> Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 30044
> Listening on port 2346
> target remote [...]:2346
> Remote debugging using [...]:2346
> Reading symbols from .../lib64/ld.so.1...done.
> 0x000000fff79534f0 in __start () from .../lib64/ld.so.1
> (gdb) continue
> Continuing.
> warning: Could not load shared library symbols for linux-vdso.so.1.
> Do you need "set solib-search-path" or "set sysroot"?
>
> Breakpoint 1, main () at .../gdb/testsuite/gdb.base/advance.c:41
> 41 c = 5;
> (gdb)
>
> At the protocol level the difference starts here (bad):
>
> Sending packet: $qfThreadInfo#bb...Ack
> Packet received: m1814
> Sending packet: $qsThreadInfo#c8...Ack
> Packet received: l
> [Switching to Thread <main>]
> Sending packet: $qSymbol::#5b...Ack
> Packet received: qSymbol:6e70746c5f76657273696f6e
> Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
> Packet received: OK
> Sending packet: $Hg1814#7d...Ack
> Packet received: OK
> Sending packet: $Hg0#df...Ack
> Packet received: E01
> (gdb) continue
> Cannot execute this command without a live selected thread.
> (gdb)
So IIUC, the difference is that after this patch, we now start sending those
two Hg / select-thread packets, and I assume that the second one throws,
an error (given the E01) which leaves the thread state out of sync.
Strange, off hand I'm not seeing how this patch can affect/cause this, since
it's mostly touching gdbarch / register bits.
OK, in the bugzilla report you mentioned
"Empty `qsThreadInfo' reply handling regression causing inability
to execute".
That sequence:
> Sending packet: $qfThreadInfo#bb...Ack
> Packet received: m1814
> Sending packet: $qsThreadInfo#c8...Ack
> Packet received: l
looks OK to me off hand, since "l" means there are no more
threads (other than 1814).
Just to double-check; you're positive that this is the right
commit to blame? I'm wondering that because the remote.c thread
listing bits were touched by other patches recently, and
I'd suspect those changes first.
>
> vs (good):
>
> Sending packet: $qfThreadInfo#bb...Ack
> Packet received: m154d
> Sending packet: $qsThreadInfo#c8...Ack
> Packet received: l
> Sending packet: $mfff726c4f0,4#cb...Ack
> Packet received: 03e0c825
> Sending packet: $mfff726c4ec,4#fd...Ack
> Packet received: 00000000
> Sending packet: $mfff726c4f0,4#cb...Ack
> Packet received: 03e0c825
> 0x000000fff726c4f0 in __start () from .../lib64/ld.so.1
> Sending packet: $qSymbol::#5b...Ack
> Packet received: qSymbol:6e70746c5f76657273696f6e
> Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
> Packet received: OK
> (gdb) continue
> Continuing.
> Sending packet: $mfff726c4f0,4#cb...Ack
> Packet received: 03e0c825
> Sending packet: $Z0,120000d6c,4#36...Ack
> Packet received:
> Packet Z0 (software-breakpoint) is NOT supported
> [...]
So here we didn't used to see any Hg.
>
> The version of `gdbserver' causing this regression is as at commit
> f8b73d13b7ca^, the last MIPS backend version with no XML support. It's
> likely that later versions hit this regression too, as the mode of failure
> is clearly not XML-related.
>
Note: with current master, you can disable XML support with
"set remote target-features-packet off" before connecting.
Up until recently (7cc244debb58) that command didn't really work.
So maybe it's possible to use current master gdbserver
as proxy for emulating the old gdbserver.
> I'll paste it into Bugzilla too; please feel free to tweak as required,
> and, as always, I'll be happy to supply any details missing.
Thanks,
Pedro Alves
On Tue, 12 Dec 2017, Pedro Alves wrote:
> > [...]
> > Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 2670
> > Listening on port 2346
> > target remote [...]:2346
> > Remote debugging using [...]:2346
> > Reading symbols from .../lib64/ld.so.1...done.
> > [Switching to Thread <main>]
> > (gdb) continue
> > Cannot execute this command without a live selected thread.
> > (gdb)
> >
> > This is as from commit 5cd63fda035d. Up to 5cd63fda035d^ instead I get:
> >
> > [...]
> > Process .../gdb/testsuite/outputs/gdb.base/advance/advance created; pid = 30044
> > Listening on port 2346
> > target remote [...]:2346
> > Remote debugging using [...]:2346
> > Reading symbols from .../lib64/ld.so.1...done.
> > 0x000000fff79534f0 in __start () from .../lib64/ld.so.1
> > (gdb) continue
> > Continuing.
> > warning: Could not load shared library symbols for linux-vdso.so.1.
> > Do you need "set solib-search-path" or "set sysroot"?
> >
> > Breakpoint 1, main () at .../gdb/testsuite/gdb.base/advance.c:41
> > 41 c = 5;
> > (gdb)
> >
> > At the protocol level the difference starts here (bad):
> >
> > Sending packet: $qfThreadInfo#bb...Ack
> > Packet received: m1814
> > Sending packet: $qsThreadInfo#c8...Ack
> > Packet received: l
> > [Switching to Thread <main>]
> > Sending packet: $qSymbol::#5b...Ack
> > Packet received: qSymbol:6e70746c5f76657273696f6e
> > Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
> > Packet received: OK
> > Sending packet: $Hg1814#7d...Ack
> > Packet received: OK
> > Sending packet: $Hg0#df...Ack
> > Packet received: E01
> > (gdb) continue
> > Cannot execute this command without a live selected thread.
> > (gdb)
>
> So IIUC, the difference is that after this patch, we now start sending those
> two Hg / select-thread packets, and I assume that the second one throws,
> an error (given the E01) which leaves the thread state out of sync.
Right, I somehow missed this error reply. My first observation was that
we don't issue these memory examination packets after the `l' response
anymore (those are clearly used to report where the debuggee has stopped
at connection).
> Strange, off hand I'm not seeing how this patch can affect/cause this, since
> it's mostly touching gdbarch / register bits.
>
> OK, in the bugzilla report you mentioned
> "Empty `qsThreadInfo' reply handling regression causing inability
> to execute".
I didn't read the description of `qsThreadInfo' carefully enough in the
manual and didn't notice it is related to `qfThreadInfo'. Sorry about
that. The title of the bug will have to be changed according to further
findings.
> That sequence:
>
> > Sending packet: $qfThreadInfo#bb...Ack
> > Packet received: m1814
> > Sending packet: $qsThreadInfo#c8...Ack
> > Packet received: l
>
> looks OK to me off hand, since "l" means there are no more
> threads (other than 1814).
>
> Just to double-check; you're positive that this is the right
> commit to blame? I'm wondering that because the remote.c thread
> listing bits were touched by other patches recently, and
> I'd suspect those changes first.
I am positive, I tried several times and the failure is always the same
from 5cd63fda035d onwards, whereas earlier revisions work just fine.
> > vs (good):
> >
> > Sending packet: $qfThreadInfo#bb...Ack
> > Packet received: m154d
> > Sending packet: $qsThreadInfo#c8...Ack
> > Packet received: l
> > Sending packet: $mfff726c4f0,4#cb...Ack
> > Packet received: 03e0c825
> > Sending packet: $mfff726c4ec,4#fd...Ack
> > Packet received: 00000000
> > Sending packet: $mfff726c4f0,4#cb...Ack
> > Packet received: 03e0c825
> > 0x000000fff726c4f0 in __start () from .../lib64/ld.so.1
> > Sending packet: $qSymbol::#5b...Ack
> > Packet received: qSymbol:6e70746c5f76657273696f6e
> > Sending packet: $qSymbol::6e70746c5f76657273696f6e#4d...Ack
> > Packet received: OK
> > (gdb) continue
> > Continuing.
> > Sending packet: $mfff726c4f0,4#cb...Ack
> > Packet received: 03e0c825
> > Sending packet: $Z0,120000d6c,4#36...Ack
> > Packet received:
> > Packet Z0 (software-breakpoint) is NOT supported
> > [...]
>
> So here we didn't used to see any Hg.
Correct indeed. Now that you mention it I wonder if there actually was a
`gdbserver' issue with `Hg0' handling in f8b73d13b7ca^, hmm... Let's
check:
case 'H':
if (own_buf[1] == 'c' || own_buf[1] == 'g' || own_buf[1] == 's')
{
unsigned long gdb_id, thread_id;
gdb_id = strtoul (&own_buf[2], NULL, 16);
thread_id = gdb_id_to_thread_id (gdb_id);
if (thread_id == 0)
{
write_enn (own_buf);
break;
}
-- so `Hg0' actually wasn't yet supported back then. AFAICT it was only
your commit bd99dc858385 ("Non-stop mode support.") that added this
special exception.
So I think we need to handle such a situation somehow, and given that
`Hg1814' immediately precedes I think that `Hg0' packet can be safely
discarded from the sequence of requests issued (unless it is meant to
verify `0' thread ID support, that is).
> > The version of `gdbserver' causing this regression is as at commit
> > f8b73d13b7ca^, the last MIPS backend version with no XML support. It's
> > likely that later versions hit this regression too, as the mode of failure
> > is clearly not XML-related.
>
> Note: with current master, you can disable XML support with
> "set remote target-features-packet off" before connecting.
> Up until recently (7cc244debb58) that command didn't really work.
> So maybe it's possible to use current master gdbserver
> as proxy for emulating the old gdbserver.
Thanks for the hint, I'll try that as well.
So far I started regression-testing with 5cd63fda035d^ as the change in
question is contained with the MIPS backend and there have been no
significant recent updates there. This works reasonably well with the
f8b73d13b7ca^ `gdbserver', except I had to patch `--once' out in the
harness as not supported back then and execution is slow due to the lack
of `monitor exit' command support.
Anyway I think we should strive to continue supporting old stubs as
people may be stuck with them for some reason (and need current GDB for
another).
Maciej
@@ -654,11 +654,11 @@ remote_get_noisy_reply ()
static struct gdbarch_data *remote_gdbarch_data_handle;
static struct remote_arch_state *
-get_remote_arch_state (void)
+get_remote_arch_state (struct gdbarch *gdbarch)
{
- gdb_assert (target_gdbarch () != NULL);
+ gdb_assert (gdbarch != NULL);
return ((struct remote_arch_state *)
- gdbarch_data (target_gdbarch (), remote_gdbarch_data_handle));
+ gdbarch_data (gdbarch, remote_gdbarch_data_handle));
}
/* Fetch the global remote target state. */
@@ -671,7 +671,7 @@ get_remote_state (void)
function which calls getpkt also needs to be mindful of changes
to rs->buf, but this call limits the number of places which run
into trouble. */
- get_remote_arch_state ();
+ get_remote_arch_state (target_gdbarch ());
return get_remote_state_raw ();
}
@@ -878,7 +878,7 @@ static long
get_remote_packet_size (void)
{
struct remote_state *rs = get_remote_state ();
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
if (rs->explicit_packet_size)
return rs->explicit_packet_size;
@@ -887,9 +887,10 @@ get_remote_packet_size (void)
}
static struct packet_reg *
-packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
+packet_reg_from_regnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa,
+ long regnum)
{
- if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch ()))
+ if (regnum < 0 && regnum >= gdbarch_num_regs (gdbarch))
return NULL;
else
{
@@ -901,11 +902,12 @@ packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
}
static struct packet_reg *
-packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
+packet_reg_from_pnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa,
+ LONGEST pnum)
{
int i;
- for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
{
struct packet_reg *r = &rsa->regs[i];
@@ -1049,7 +1051,7 @@ static long
get_memory_packet_size (struct memory_packet_config *config)
{
struct remote_state *rs = get_remote_state ();
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
long what_they_get;
if (config->fixed_p)
@@ -6835,7 +6837,8 @@ strprefix (const char *p, const char *pend, const char *prefix)
static void
remote_parse_stop_reply (char *buf, struct stop_reply *event)
{
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ remote_arch_state *rsa = NULL;
+ struct gdbarch *reply_arch = NULL;
ULONGEST addr;
const char *p;
int skipregs = 0;
@@ -7015,9 +7018,43 @@ Packet: '%s'\n"),
reason. */
if (p_temp == p1)
{
- struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
+ /* If we haven't parsed the event's thread yet, find
+ it now, in order to find the architecture of the
+ reported expedited registers. */
+ if (event->ptid == null_ptid)
+ {
+ const char *thr = strstr (p1 + 1, ";thread:");
+ if (thr != NULL)
+ event->ptid = read_ptid (thr + strlen (";thread:"),
+ NULL);
+ else
+ event->ptid = magic_null_ptid;
+ }
+
+ if (rsa == NULL)
+ {
+ inferior *inf = (event->ptid == null_ptid
+ ? NULL
+ : find_inferior_ptid (event->ptid));
+ /* If this is the first time we learn anything
+ about this process, skip the registers
+ included in this packet, since we don't yet
+ know which architecture to use to parse
+ them. */
+ if (inf == NULL)
+ {
+ p = strchrnul (p1 + 1, ';');
+ p++;
+ continue;
+ }
+
+ reply_arch = inf->gdbarch;
+ rsa = get_remote_arch_state (reply_arch);
+ }
+
+ struct packet_reg *reg = packet_reg_from_pnum (reply_arch,
+ rsa, pnum);
cached_reg_t cached_reg;
- struct gdbarch *gdbarch = target_gdbarch ();
if (reg == NULL)
error (_("Remote sent bad register number %s: %s\n\
@@ -7026,13 +7063,13 @@ Packet: '%s'\n"),
cached_reg.num = reg->regnum;
cached_reg.data = (gdb_byte *)
- xmalloc (register_size (gdbarch, reg->regnum));
+ xmalloc (register_size (reply_arch, reg->regnum));
p = p1 + 1;
fieldsize = hex2bin (p, cached_reg.data,
- register_size (gdbarch, reg->regnum));
+ register_size (reply_arch, reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < register_size (gdbarch, reg->regnum))
+ if (fieldsize < register_size (reply_arch, reg->regnum))
warning (_("Remote reply is too short: %s"), buf);
VEC_safe_push (cached_reg_t, event->regcache, &cached_reg);
@@ -7605,7 +7642,7 @@ process_g_packet (struct regcache *regcache)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct remote_state *rs = get_remote_state ();
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct remote_arch_state *rsa = get_remote_arch_state (gdbarch);
int i, buf_len;
char *p;
char *regs;
@@ -7739,7 +7776,8 @@ static void
remote_fetch_registers (struct target_ops *ops,
struct regcache *regcache, int regnum)
{
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ remote_arch_state *rsa = get_remote_arch_state (gdbarch);
int i;
set_remote_traceframe ();
@@ -7747,7 +7785,7 @@ remote_fetch_registers (struct target_ops *ops,
if (regnum >= 0)
{
- struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
+ struct packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum);
gdb_assert (reg != NULL);
@@ -7773,7 +7811,7 @@ remote_fetch_registers (struct target_ops *ops,
fetch_registers_using_g (regcache);
- for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
if (!rsa->regs[i].in_g_packet)
if (!fetch_register_using_p (regcache, &rsa->regs[i]))
{
@@ -7789,7 +7827,7 @@ remote_fetch_registers (struct target_ops *ops,
static void
remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
{
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
int i;
/* Make sure the entire registers array is valid. */
@@ -7855,7 +7893,7 @@ static void
store_registers_using_G (const struct regcache *regcache)
{
struct remote_state *rs = get_remote_state ();
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
gdb_byte *regs;
char *p;
@@ -7894,7 +7932,8 @@ static void
remote_store_registers (struct target_ops *ops,
struct regcache *regcache, int regnum)
{
- struct remote_arch_state *rsa = get_remote_arch_state ();
+ struct gdbarch *gdbarch = regcache->arch ();
+ remote_arch_state *rsa = get_remote_arch_state (gdbarch);
int i;
set_remote_traceframe ();
@@ -7902,7 +7941,7 @@ remote_store_registers (struct target_ops *ops,
if (regnum >= 0)
{
- struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
+ struct packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum);
gdb_assert (reg != NULL);
@@ -7926,7 +7965,7 @@ remote_store_registers (struct target_ops *ops,
store_registers_using_G (regcache);
- for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
+ for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
if (!rsa->regs[i].in_g_packet)
if (!store_register_using_P (regcache, &rsa->regs[i]))
/* See above for why we do not issue an error here. */
@@ -12653,7 +12692,8 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
if (packet_support (PACKET_qTStatus) == PACKET_DISABLE)
return -1;
- trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet;
+ trace_regblock_size
+ = get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
putpkt ("qTStatus");
@@ -3131,7 +3131,9 @@ default_watchpoint_addr_within_range (struct target_ops *target,
struct gdbarch *
default_thread_architecture (struct target_ops *ops, ptid_t ptid)
{
- return target_gdbarch ();
+ inferior *inf = find_inferior_ptid (ptid);
+ gdb_assert (inf != NULL);
+ return inf->gdbarch;
}
static int
@@ -16,14 +16,28 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <stdio.h>
+#include <unistd.h>
+
+static void
+hangout_loop (void)
+{
+}
int
main(int argc, char *argv[])
{
int i;
+ alarm (30);
+
for (i = 0; i < argc; ++i)
{
printf("Arg %d is %s\n", i, argv[i]);
}
+
+ while (1)
+ {
+ hangout_loop ();
+ usleep (20);
+ }
}
@@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <stdlib.h>
+#include <unistd.h>
short hglob = 1;
@@ -37,15 +38,27 @@ hello(int x)
return x + 45;
}
+static void
+hello_loop (void)
+{
+}
+
int
main()
{
int tmpx;
+ alarm (30);
+
bar();
tmpx = hello(glob);
commonfun();
glob = tmpx;
commonfun();
-}
+ while (1)
+ {
+ hello_loop ();
+ usleep (20);
+ }
+}
@@ -96,3 +96,27 @@ if ![runto_main] then {
gdb_test "info inferiors" \
"Executable.*${exec1}.*${exec2}.*"
+
+# Now select inferior 2, and trigger an event in inferior 1. This
+# tries to check that GDB doesn't incorrectly uses the architecture of
+# inferior 2 when parsing the expedited registers in a stop reply for
+# inferior 1 (when remote debugging).
+
+gdb_test_no_output "set schedule-multiple on"
+
+with_test_prefix "inf1 event with inf2 selected" {
+ gdb_test "inferior 2" "Switching to inferior 2.*thread 2\.1.*main.*${srcfile2}.*"
+ gdb_test "b hello_loop" "Breakpoint .* at .*${srcfile1}.*"
+ gdb_test "c" " hello_loop.*" "continue to hello_loop"
+}
+
+delete_breakpoints
+
+# Same, but the other way around: select inferior 1 and trigger an
+# event in inferior 2.
+
+with_test_prefix "inf2 event with inf1 selected" {
+ gdb_test "inferior 1" "Switching to inferior 1.*thread 1\.1.*hello_loop.*${srcfile1}.*"
+ gdb_test "b hangout_loop" "Breakpoint .* at .*${srcfile2}.*"
+ gdb_test "c" " hangout_loop.*" "continue to hangout_loop"
+}