Skip to content

Commit 5cd63fd

Browse files
committed
Fix "Remote 'g' packet reply is too long" problems with multiple inferiors
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-04 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. (struct stop_reply) <arch>: New field. (remote_parse_stop_reply): Use the stopped thread's architecture, not the current inferior's. Save the architecture in the stop_reply. (process_stop_reply): Use the stop reply's architecture. (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. * spu-multiarch.c (spu_thread_architecture): Defer to the target beneath instead of calling target_gdbarch. * target.c (default_thread_architecture): Use the specified inferior's architecture, instead of the current inferior's architecture (via target_gdbarch). gdb/testsuite/ChangeLog: 2017-10-04 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.
1 parent ed4227b commit 5cd63fd

File tree

8 files changed

+169
-30
lines changed

8 files changed

+169
-30
lines changed

gdb/ChangeLog

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,31 @@
1+
2017-10-04 Pedro Alves <palves@redhat.com>
2+
3+
* remote.c (get_remote_arch_state): New 'gdbarch' parameter. Use
4+
it instead of target_gdbarch.
5+
(get_remote_state, get_remote_packet_size): Adjust
6+
get_remote_arch_state calls, passing down target_gdbarch
7+
explicitly.
8+
(packet_reg_from_regnum, packet_reg_from_pnum): New parameter
9+
'gdbarch' and use it instead of target_gdbarch.
10+
(get_memory_packet_size): Adjust get_remote_arch_state calls,
11+
passing down target_gdbarch explicitly.
12+
(struct stop_reply) <arch>: New field.
13+
(remote_parse_stop_reply): Use the stopped thread's architecture,
14+
not the current inferior's. Save the architecture in the
15+
stop_reply.
16+
(process_stop_reply): Use the stop reply's architecture.
17+
(process_g_packet, remote_fetch_registers)
18+
(remote_prepare_to_store, store_registers_using_G)
19+
(remote_store_registers): Adjust get_remote_arch_state calls,
20+
using the regcache's architecture.
21+
(remote_get_trace_status): Adjust get_remote_arch_state calls,
22+
passing down target_gdbarch explicitly.
23+
* spu-multiarch.c (spu_thread_architecture): Defer to the target
24+
beneath instead of calling target_gdbarch.
25+
* target.c (default_thread_architecture): Use the specified
26+
inferior's architecture, instead of the current inferior's
27+
architecture (via target_gdbarch).
28+
129
2017-10-04 Pedro Alves <palves@redhat.com>
230

331
* regcache.c (get_thread_arch_regcache): Remove null_ptid special

gdb/remote.c

Lines changed: 73 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -654,11 +654,11 @@ remote_get_noisy_reply ()
654654
static struct gdbarch_data *remote_gdbarch_data_handle;
655655

656656
static struct remote_arch_state *
657-
get_remote_arch_state (void)
657+
get_remote_arch_state (struct gdbarch *gdbarch)
658658
{
659-
gdb_assert (target_gdbarch () != NULL);
659+
gdb_assert (gdbarch != NULL);
660660
return ((struct remote_arch_state *)
661-
gdbarch_data (target_gdbarch (), remote_gdbarch_data_handle));
661+
gdbarch_data (gdbarch, remote_gdbarch_data_handle));
662662
}
663663

664664
/* Fetch the global remote target state. */
@@ -671,7 +671,7 @@ get_remote_state (void)
671671
function which calls getpkt also needs to be mindful of changes
672672
to rs->buf, but this call limits the number of places which run
673673
into trouble. */
674-
get_remote_arch_state ();
674+
get_remote_arch_state (target_gdbarch ());
675675

676676
return get_remote_state_raw ();
677677
}
@@ -878,7 +878,7 @@ static long
878878
get_remote_packet_size (void)
879879
{
880880
struct remote_state *rs = get_remote_state ();
881-
struct remote_arch_state *rsa = get_remote_arch_state ();
881+
remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
882882

883883
if (rs->explicit_packet_size)
884884
return rs->explicit_packet_size;
@@ -887,9 +887,10 @@ get_remote_packet_size (void)
887887
}
888888

889889
static struct packet_reg *
890-
packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
890+
packet_reg_from_regnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa,
891+
long regnum)
891892
{
892-
if (regnum < 0 && regnum >= gdbarch_num_regs (target_gdbarch ()))
893+
if (regnum < 0 && regnum >= gdbarch_num_regs (gdbarch))
893894
return NULL;
894895
else
895896
{
@@ -901,11 +902,12 @@ packet_reg_from_regnum (struct remote_arch_state *rsa, long regnum)
901902
}
902903

903904
static struct packet_reg *
904-
packet_reg_from_pnum (struct remote_arch_state *rsa, LONGEST pnum)
905+
packet_reg_from_pnum (struct gdbarch *gdbarch, struct remote_arch_state *rsa,
906+
LONGEST pnum)
905907
{
906908
int i;
907909

908-
for (i = 0; i < gdbarch_num_regs (target_gdbarch ()); i++)
910+
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
909911
{
910912
struct packet_reg *r = &rsa->regs[i];
911913

@@ -1049,7 +1051,7 @@ static long
10491051
get_memory_packet_size (struct memory_packet_config *config)
10501052
{
10511053
struct remote_state *rs = get_remote_state ();
1052-
struct remote_arch_state *rsa = get_remote_arch_state ();
1054+
remote_arch_state *rsa = get_remote_arch_state (target_gdbarch ());
10531055

10541056
long what_they_get;
10551057
if (config->fixed_p)
@@ -6364,6 +6366,9 @@ typedef struct stop_reply
63646366

63656367
struct target_waitstatus ws;
63666368

6369+
/* The architecture associated with the expedited registers. */
6370+
gdbarch *arch;
6371+
63676372
/* Expedited registers. This makes remote debugging a bit more
63686373
efficient for those targets that provide critical registers as
63696374
part of their normal status mechanism (as another roundtrip to
@@ -6838,7 +6843,7 @@ strprefix (const char *p, const char *pend, const char *prefix)
68386843
static void
68396844
remote_parse_stop_reply (char *buf, struct stop_reply *event)
68406845
{
6841-
struct remote_arch_state *rsa = get_remote_arch_state ();
6846+
remote_arch_state *rsa = NULL;
68426847
ULONGEST addr;
68436848
const char *p;
68446849
int skipregs = 0;
@@ -7018,9 +7023,47 @@ Packet: '%s'\n"),
70187023
reason. */
70197024
if (p_temp == p1)
70207025
{
7021-
struct packet_reg *reg = packet_reg_from_pnum (rsa, pnum);
7026+
/* If we haven't parsed the event's thread yet, find
7027+
it now, in order to find the architecture of the
7028+
reported expedited registers. */
7029+
if (event->ptid == null_ptid)
7030+
{
7031+
const char *thr = strstr (p1 + 1, ";thread:");
7032+
if (thr != NULL)
7033+
event->ptid = read_ptid (thr + strlen (";thread:"),
7034+
NULL);
7035+
else
7036+
event->ptid = magic_null_ptid;
7037+
}
7038+
7039+
if (rsa == NULL)
7040+
{
7041+
inferior *inf = (event->ptid == null_ptid
7042+
? NULL
7043+
: find_inferior_ptid (event->ptid));
7044+
/* If this is the first time we learn anything
7045+
about this process, skip the registers
7046+
included in this packet, since we don't yet
7047+
know which architecture to use to parse them.
7048+
We'll determine the architecture later when
7049+
we process the stop reply and retrieve the
7050+
target description, via
7051+
remote_notice_new_inferior ->
7052+
post_create_inferior. */
7053+
if (inf == NULL)
7054+
{
7055+
p = strchrnul (p1 + 1, ';');
7056+
p++;
7057+
continue;
7058+
}
7059+
7060+
event->arch = inf->gdbarch;
7061+
rsa = get_remote_arch_state (event->arch);
7062+
}
7063+
7064+
packet_reg *reg
7065+
= packet_reg_from_pnum (event->arch, rsa, pnum);
70227066
cached_reg_t cached_reg;
7023-
struct gdbarch *gdbarch = target_gdbarch ();
70247067

70257068
if (reg == NULL)
70267069
error (_("Remote sent bad register number %s: %s\n\
@@ -7029,13 +7072,13 @@ Packet: '%s'\n"),
70297072

70307073
cached_reg.num = reg->regnum;
70317074
cached_reg.data = (gdb_byte *)
7032-
xmalloc (register_size (gdbarch, reg->regnum));
7075+
xmalloc (register_size (event->arch, reg->regnum));
70337076

70347077
p = p1 + 1;
70357078
fieldsize = hex2bin (p, cached_reg.data,
7036-
register_size (gdbarch, reg->regnum));
7079+
register_size (event->arch, reg->regnum));
70377080
p += 2 * fieldsize;
7038-
if (fieldsize < register_size (gdbarch, reg->regnum))
7081+
if (fieldsize < register_size (event->arch, reg->regnum))
70397082
warning (_("Remote reply is too short: %s"), buf);
70407083

70417084
VEC_safe_push (cached_reg_t, event->regcache, &cached_reg);
@@ -7251,7 +7294,7 @@ process_stop_reply (struct stop_reply *stop_reply,
72517294
if (stop_reply->regcache)
72527295
{
72537296
struct regcache *regcache
7254-
= get_thread_arch_regcache (ptid, target_gdbarch ());
7297+
= get_thread_arch_regcache (ptid, stop_reply->arch);
72557298
cached_reg_t *reg;
72567299
int ix;
72577300

@@ -7608,7 +7651,7 @@ process_g_packet (struct regcache *regcache)
76087651
{
76097652
struct gdbarch *gdbarch = get_regcache_arch (regcache);
76107653
struct remote_state *rs = get_remote_state ();
7611-
struct remote_arch_state *rsa = get_remote_arch_state ();
7654+
remote_arch_state *rsa = get_remote_arch_state (gdbarch);
76127655
int i, buf_len;
76137656
char *p;
76147657
char *regs;
@@ -7742,15 +7785,16 @@ static void
77427785
remote_fetch_registers (struct target_ops *ops,
77437786
struct regcache *regcache, int regnum)
77447787
{
7745-
struct remote_arch_state *rsa = get_remote_arch_state ();
7788+
struct gdbarch *gdbarch = get_regcache_arch (regcache);
7789+
remote_arch_state *rsa = get_remote_arch_state (gdbarch);
77467790
int i;
77477791

77487792
set_remote_traceframe ();
77497793
set_general_thread (regcache_get_ptid (regcache));
77507794

77517795
if (regnum >= 0)
77527796
{
7753-
struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
7797+
packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum);
77547798

77557799
gdb_assert (reg != NULL);
77567800

@@ -7776,7 +7820,7 @@ remote_fetch_registers (struct target_ops *ops,
77767820

77777821
fetch_registers_using_g (regcache);
77787822

7779-
for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
7823+
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
77807824
if (!rsa->regs[i].in_g_packet)
77817825
if (!fetch_register_using_p (regcache, &rsa->regs[i]))
77827826
{
@@ -7792,7 +7836,7 @@ remote_fetch_registers (struct target_ops *ops,
77927836
static void
77937837
remote_prepare_to_store (struct target_ops *self, struct regcache *regcache)
77947838
{
7795-
struct remote_arch_state *rsa = get_remote_arch_state ();
7839+
remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
77967840
int i;
77977841

77987842
/* Make sure the entire registers array is valid. */
@@ -7858,7 +7902,7 @@ static void
78587902
store_registers_using_G (const struct regcache *regcache)
78597903
{
78607904
struct remote_state *rs = get_remote_state ();
7861-
struct remote_arch_state *rsa = get_remote_arch_state ();
7905+
remote_arch_state *rsa = get_remote_arch_state (regcache->arch ());
78627906
gdb_byte *regs;
78637907
char *p;
78647908

@@ -7897,15 +7941,16 @@ static void
78977941
remote_store_registers (struct target_ops *ops,
78987942
struct regcache *regcache, int regnum)
78997943
{
7900-
struct remote_arch_state *rsa = get_remote_arch_state ();
7944+
struct gdbarch *gdbarch = regcache->arch ();
7945+
remote_arch_state *rsa = get_remote_arch_state (gdbarch);
79017946
int i;
79027947

79037948
set_remote_traceframe ();
79047949
set_general_thread (regcache_get_ptid (regcache));
79057950

79067951
if (regnum >= 0)
79077952
{
7908-
struct packet_reg *reg = packet_reg_from_regnum (rsa, regnum);
7953+
packet_reg *reg = packet_reg_from_regnum (gdbarch, rsa, regnum);
79097954

79107955
gdb_assert (reg != NULL);
79117956

@@ -7929,7 +7974,7 @@ remote_store_registers (struct target_ops *ops,
79297974

79307975
store_registers_using_G (regcache);
79317976

7932-
for (i = 0; i < gdbarch_num_regs (get_regcache_arch (regcache)); i++)
7977+
for (i = 0; i < gdbarch_num_regs (gdbarch); i++)
79337978
if (!rsa->regs[i].in_g_packet)
79347979
if (!store_register_using_P (regcache, &rsa->regs[i]))
79357980
/* See above for why we do not issue an error here. */
@@ -12697,7 +12742,8 @@ remote_get_trace_status (struct target_ops *self, struct trace_status *ts)
1269712742
if (packet_support (PACKET_qTStatus) == PACKET_DISABLE)
1269812743
return -1;
1269912744

12700-
trace_regblock_size = get_remote_arch_state ()->sizeof_g_packet;
12745+
trace_regblock_size
12746+
= get_remote_arch_state (target_gdbarch ())->sizeof_g_packet;
1270112747

1270212748
putpkt ("qTStatus");
1270312749

gdb/spu-multiarch.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,8 @@ spu_thread_architecture (struct target_ops *ops, ptid_t ptid)
121121
if (parse_spufs_run (ptid, &spufs_fd, &spufs_addr))
122122
return spu_gdbarch (spufs_fd);
123123

124-
return target_gdbarch ();
124+
target_ops *beneath = find_target_beneath (ops);
125+
return beneath->to_thread_architecture (beneath, ptid);
125126
}
126127

127128
/* Override the to_region_ok_for_hw_watchpoint routine. */

gdb/target.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3137,7 +3137,9 @@ default_watchpoint_addr_within_range (struct target_ops *target,
31373137
static struct gdbarch *
31383138
default_thread_architecture (struct target_ops *ops, ptid_t ptid)
31393139
{
3140-
return target_gdbarch ();
3140+
inferior *inf = find_inferior_ptid (ptid);
3141+
gdb_assert (inf != NULL);
3142+
return inf->gdbarch;
31413143
}
31423144

31433145
static int

gdb/testsuite/ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2017-10-04 Pedro Alves <palves@redhat.com>
2+
3+
* gdb.multi/hangout.c: Include <unistd.h>.
4+
(hangout_loop): New function.
5+
(main): Call alarm. Call hangout_loop in a loop.
6+
* gdb.multi/hello.c: Include <unistd.h>.
7+
(hello_loop): New function.
8+
(main): Call alarm. Call hangout_loop in a loop.
9+
* gdb.multi/multi-arch.exp: Test running to a breakpoint one
10+
inferior with the other selected.
11+
112
2017-10-04 Simon Marchi <simon.marchi@ericsson.com>
213

314
* gdb.mi/list-thread-groups-available.exp: New file.

gdb/testsuite/gdb.multi/hangout.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,28 @@
1616
along with this program. If not, see <http://www.gnu.org/licenses/>. */
1717

1818
#include <stdio.h>
19+
#include <unistd.h>
20+
21+
static void
22+
hangout_loop (void)
23+
{
24+
}
1925

2026
int
2127
main(int argc, char *argv[])
2228
{
2329
int i;
2430

31+
alarm (30);
32+
2533
for (i = 0; i < argc; ++i)
2634
{
2735
printf("Arg %d is %s\n", i, argv[i]);
2836
}
37+
38+
while (1)
39+
{
40+
hangout_loop ();
41+
usleep (20);
42+
}
2943
}

gdb/testsuite/gdb.multi/hello.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
along with this program. If not, see <http://www.gnu.org/licenses/>. */
1717

1818
#include <stdlib.h>
19+
#include <unistd.h>
1920

2021
short hglob = 1;
2122

@@ -37,15 +38,27 @@ hello(int x)
3738
return x + 45;
3839
}
3940

41+
static void
42+
hello_loop (void)
43+
{
44+
}
45+
4046
int
4147
main()
4248
{
4349
int tmpx;
4450

51+
alarm (30);
52+
4553
bar();
4654
tmpx = hello(glob);
4755
commonfun();
4856
glob = tmpx;
4957
commonfun();
50-
}
5158

59+
while (1)
60+
{
61+
hello_loop ();
62+
usleep (20);
63+
}
64+
}

0 commit comments

Comments
 (0)