[PATCH 1/2] Fix error when GDB connects to GDBserver with qC disabled

Yao Qi
2013-01-23T08:36:39Z

GDB gets an internal error when it connects to GDBserver started with
'--disable-packet=qC'.

Sending packet: $QNonStop:0#8c...Packet received: OK
Sending packet: $?#3f...Packet received: T0505:00000000;04:00f0ffbf;08:b0c2e44c;thread:p4255.4255;core:1;
Sending packet: $Hc-1#09...Packet received: E01
Sending packet: $qC#b4...Packet received:
Sending packet: $qAttached:a410#bf...Packet received: E01
Packet qAttached (query-attached) is supported
warning: Remote failure reply: E01
Sending packet: $qOffsets#4b...Packet received:
../../../git/gdb/target.c:3248: internal-error: Can't determine the current address space of thread Thread 16981

When start remote, the call chain is as follows,

remote_start_remote
add_current_inferior_and_thread <--[1]
...
start_remote
wait_for_inferior
remote_wait_as
process_stop_reply
get_thread_arch_regcache <--[2]
remote_notice_new_inferior <--[3]

GDB sends packet "qC" in [1] and adds the thread/inferior if the remote
stubs understands "qC". In [2], GDB looks for the inferior to build a
regcache, and notices a new inferior in [3]. As we can see, GDB assumes
that the inferior can be found in [2]. Once the remote stub doesn't
support "qC", GDB can't look for the inferior in [2], and emits an
internal error.

This patch fix this internal error by exchanging the order of [2] and
[3].

gdb:

2013-01-22 Yao Qi <yao@codesourcery.com>

* remote.c (process_stop_reply): Call remote_notice_new_inferior
earlier.
---
gdb/remote.c | 12 +++++++++---
1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/gdb/remote.c b/gdb/remote.c
index 7ea9597..3271ca0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5690,11 +5690,18 @@ process_stop_reply (struct stop_reply *stop_reply,
/* Expedited registers. */
if (stop_reply->regcache)
{
- struct regcache *regcache
- = get_thread_arch_regcache (ptid, target_gdbarch ());
+ struct regcache *regcache;
cached_reg_t *reg;
int ix;

+ /* Add the inferior earlier, because the following
+ 'get_thread_arch_regcache' calls
+ 'target_thread_address_space', which requires the
+ inferior should be found in the inferior list. */
+ remote_notice_new_inferior (ptid, 0);
+
+ regcache = get_thread_arch_regcache (ptid,
+ target_gdbarch ());
for (ix = 0;
VEC_iterate(cached_reg_t, stop_reply->regcache, ix, reg);
ix++)
@@ -5705,7 +5712,6 @@ process_stop_reply (struct stop_reply *stop_reply,
remote_stopped_by_watchpoint_p = stop_reply->stopped_by_watchpoint_p;
remote_watch_data_address = stop_reply->watch_data_address;

- remote_notice_new_inferior (ptid, 0);
demand_private_info (ptid)->core = stop_reply->core;
}

--
1.7.7.6