This is the mail archive of the
mailing list for the GDB project.
[PATCH] remote: Fix a crash on longjmp breakpoint removal
- From: "Maciej W. Rozycki" <macro at codesourcery dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: Tom Tromey <tromey at redhat dot com>
- Date: Tue, 13 Dec 2011 21:09:28 +0000
- Subject: [PATCH] remote: Fix a crash on longjmp breakpoint removal
I have observed a crash, where GDB attempts to send a packet to gdbserver
after the remote target has already exited (and the gdbserver process
terminated) -- here's the tail of an example remote session transcript:
Sending packet: $vCont;c#a8...Packet received: W00
[Inferior 1 (Remote target) exited normally]
Sending packet: $Hg0#df...
This happens on the MIPS/Linux target while GDB is single-stepping with
the "step" command.
I have tracked it down to remote_close calling discard_all_inferiors,
which in turn eventually calls delete_thread_of_inferior, which calls
clear_thread_inferior_resources, which calls delete_longjmp_breakpoint,
which calls remote_remove_breakpoint, which needs to send some packets to
the remote target to get the breakpoint removed. But at this point the
remote file descriptor has already been closed; after a W00 stop reply
gdbserver does not expect any further input anyway.
I have looked through ChangeLogs and I believe this is a regression
2010-12-09 Tom Tromey <firstname.lastname@example.org>
* thread.c (clear_thread_inferior_resources): Call
I have been able to get rid of the crash with the change below, no test
suite regressions on mips-linux-gnu (remote target). OK to apply?
2011-12-13 Maciej W. Rozycki <email@example.com>
* thread.c (clear_thread_inferior_resources): Don't call
delete_longjmp_breakpoint if there's no inferior.
--- gdb-fsf-trunk-quilt.orig/gdb/thread.c 2011-11-02 21:28:38.000000000 +0000
+++ gdb-fsf-trunk-quilt/gdb/thread.c 2011-12-13 19:42:25.805620748 +0000
@@ -119,7 +119,8 @@ clear_thread_inferior_resources (struct
do_all_intermediate_continuations_thread (tp, 1);
do_all_continuations_thread (tp, 1);
- delete_longjmp_breakpoint (tp->num);
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ delete_longjmp_breakpoint (tp->num);