c9f35b348e
When using GDB to debug an RX target using the GDB remote protocol, using a Renesas supplied debug agent, I encountered the following assertion error: thread.c:85: internal-error: inferior_thread: Assertion `tp' failed. A problem internal to GDB has been detected, further debugging may prove unreliable. Create a core file of GDB? (y or n) n Command aborted. This assertion error occurs due to the fact that the value associated with inferior_ptid is not on the thread list. The remote debug output (obtained with "set debug remote 1") is fairly short, so I will include it up to the point where things go wrong - which is somewhat before the assertion failure: (gdb) target remote coyote.lan:61234 Remote debugging using coyote.lan:61234 Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+#c9...Ack Packet received: PacketSize=c00;qXfer:memory-map:read-;qXfer:features:read-;QStartNoAckMode+;multiprocess+;QNonStop+ Packet qSupported (supported-packets) is supported Sending packet: $QStartNoAckMode#b0...Ack Packet received: OK Sending packet: $Hgp0.0#ad...Packet received: OK Sending packet: $QNonStop:0#8c...Packet received: OK Sending packet: $qTStatus#49...Packet received: Packet qTStatus (trace-status) is NOT supported Sending packet: $?#3f...Packet received: S02 Sending packet: $qfThreadInfo#bb...Packet received: m1 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $qAttached:a410#bf...Packet received: 0 Packet qAttached (query-attached) is supported Sending packet: $Hc-1#09...Packet received: OK Sending packet: $qC#b4...Packet received: QC not supported Above is the trace starting from the invocation of "target remote" through the call of get_current_thread() in remote_start_remote(). Below, I've pasted this line of code along with additional lines of context. The test following the call is especially important to understanding both the problem and my patch. /* We have thread information; select the thread the target says should be current. If we're reconnecting to a multi-threaded program, this will ideally be the thread that last reported an event before GDB disconnected. */ inferior_ptid = get_current_thread (wait_status); if (ptid_equal (inferior_ptid, null_ptid)) { /* Odd... The target was able to list threads, but not tell us which thread was current (no "thread" register in T stop reply?). Just pick the first thread in the thread list then. */ inferior_ptid = thread_list->ptid; } } Prior to getting to the code pasted above, remote_start_remote() made a call to target_update_thread_list(). This corresponds to the following lines from the above trace: Sending packet: $qfThreadInfo#bb...Packet received: m1 Sending packet: $qsThreadInfo#c8...Packet received: l Sending packet: $qAttached:a410#bf...Packet received: 0 Packet qAttached (query-attached) is supported Once target_update_thread_list has completed, the thread list contains a single entry: {pid = 42000, lwp = 1, tid = 0}. remote_start_remote() then makes a call to set_continue_thread(), accounting for this line of the trace: Sending packet: $Hc-1#09...Packet received: OK Finally, the call to get_current_thread() is responsible for the last line of the trace that I provided above: Sending packet: $qC#b4...Packet received: QC not supported get_current_thread() calls stop_reply_extract_thread() with the wait status. This returns null_ptid. get_current_thread() then calls remote_current_thread with a null inferior_ptid. After the calls to putpkt() and getpkt(), rs->buf[0] is 'Q', so read_ptid() is called and its result is returned. The buffer passed to read_ptid() is " not supported". read_ptid ultimately returns a ptid of {pid = 4200, lwp = 0, tid = 0}. However, this thread is not on the thread list. As noted earlier, the call to target_update_thread_list() had placed {pid = 42000, lwp = 1, tid = 0} on the list. This is the only thread in the list. When these calls ultimately return to remote_start_remote(), inferior_ptid gets set to {pid = 4200, lwp = 0, tid = 0}, which (again) is not on the thread list. It appears to me that the string " not supported" is coming from the debug agent. If so, it should be fixed, but I don't see a reason to not consult the thread list in order to place a valid thread id in inferior_ptid. This (consultation of the thread list) is what is done when inferior_ptid is null_ptid: if (ptid_equal (inferior_ptid, null_ptid)) { /* Odd... The target was able to list threads, but not tell us which thread was current (no "thread" register in T stop reply?). Just pick the first thread in the thread list then. */ inferior_ptid = thread_list->ptid; } My patch causes a null inferior_ptid to be returned by read_ptid when no thread id is found in the response from the debug agent. This return value ends up being returned by remote_current_thread() and then by get_current_thread. The assignment then places this null value into inferior_ptid. That, in turn, allows the ptid_equal test (noted above) to fetch a valid thread from the thread list. I no longer see the assertion failure due a good value (which is on the thread list) being placed in inferior_ptid. This patch also adds two log warnings that may be output when "set debug remote 1" is used. When running against the Renesas debug agent mentioned earlier, this is the relevant portion of the log output: Sending packet: $qC#b4...Packet received: QC not supported warning: garbage in qC reply warning: couldn't determine remote current thread; picking first in list. gdb/ChangeLog: * remote.c (read_ptid): Return null_ptid when no thread id is found. (remote_current_thread): Add log warning for malformed qC reply. (remote_start_remote): Add log warning when current thread not found. |
||
---|---|---|
bfd | ||
binutils | ||
config | ||
cpu | ||
elfcpp | ||
etc | ||
gas | ||
gdb | ||
gold | ||
gprof | ||
include | ||
intl | ||
ld | ||
libdecnumber | ||
libiberty | ||
opcodes | ||
readline | ||
sim | ||
texinfo | ||
zlib | ||
.cvsignore | ||
.gitattributes | ||
.gitignore | ||
COPYING | ||
COPYING.LIB | ||
COPYING.LIBGLOSS | ||
COPYING.NEWLIB | ||
COPYING3 | ||
COPYING3.LIB | ||
ChangeLog | ||
MAINTAINERS | ||
Makefile.def | ||
Makefile.in | ||
Makefile.tpl | ||
README | ||
README-maintainer-mode | ||
compile | ||
config-ml.in | ||
config.guess | ||
config.rpath | ||
config.sub | ||
configure | ||
configure.ac | ||
depcomp | ||
djunpack.bat | ||
install-sh | ||
libtool.m4 | ||
ltgcc.m4 | ||
ltmain.sh | ||
ltoptions.m4 | ||
ltsugar.m4 | ||
ltversion.m4 | ||
lt~obsolete.m4 | ||
makefile.vms | ||
missing | ||
mkdep | ||
mkinstalldirs | ||
move-if-change | ||
setup.com | ||
src-release.sh | ||
symlink-tree | ||
ylwrap |
README
README for GNU development tools This directory contains various GNU compilers, assemblers, linkers, debuggers, etc., plus their support routines, definitions, and documentation. If you are receiving this as part of a GDB release, see the file gdb/README. If with a binutils release, see binutils/README; if with a libg++ release, see libg++/README, etc. That'll give you info about this package -- supported targets, how to use it, how to report bugs, etc. It is now possible to automatically configure and build a variety of tools with one command. To build all of the tools contained herein, run the ``configure'' script here, e.g.: ./configure make To install them (by default in /usr/local/bin, /usr/local/lib, etc), then do: make install (If the configure script can't determine your type of computer, give it the name as an argument, for instance ``./configure sun4''. You can use the script ``config.sub'' to test whether a name is recognized; if it is, config.sub translates it to a triplet specifying CPU, vendor, and OS.) If you have more than one compiler on your system, it is often best to explicitly set CC in the environment before running configure, and to also set CC when running make. For example (assuming sh/bash/ksh): CC=gcc ./configure make A similar example using csh: setenv CC gcc ./configure make Much of the code and documentation enclosed is copyright by the Free Software Foundation, Inc. See the file COPYING or COPYING.LIB in the various directories, for a description of the GNU General Public License terms under which you can copy the files. REPORTING BUGS: Again, see gdb/README, binutils/README, etc., for info on where and how to report problems.