This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix for missing *stopped indication due to ctrl-c.


I've applied this patch below.

If you unlucky enough, with target remote/sim, interrupting the
target with ctrl-c/SIGINT would sometimes yield this output,
on Windows:

 -exec-run
 =thread-created,id="5"
 ^running
 *running,thread-id="all"
 (gdb)
 ^error,msg="Quit (expect signal SIGINT when the program is resumed)"
 (gdb)

Whenever this happened, the target was sucessfuly stopped (or better,
not resumed), but gdb didn't output a *stopped indication.  Sometimes
it would.

The problem is related to a new-ish QUIT that can
be called during inferior run control, here:

 keep_going ->  remove_breakpoints -> target_write_with_progress


`resume' is guarded with a cleanup that calls normal_stop when a
QUIT is thrown, and itself has a QUIT, but keep_going hasn't such
guard.  This patch adds such a cleanup.

This makes it so that GDB always outputs an MI *stopped
indication before ^error, such as:

 -exec-run
 =thread-created,id="4"
 ^running
 *running,thread-id="all"
 (gdb)
 *stopped,thread-id="4",stopped-threads="all",frame={addr="0x00ff000c",func="main",args=[],file="main.c",fullname="main.c",line="23"}
 ^error,msg="Quit (expect signal SIGINT when the program is resumed)"
 (gdb)

-- 
Pedro Alves

2009-10-28  Pedro Alves  <pedro@codesourcery.com>

	* infrun.c (keep_going): Wrap with resume_cleanups.

---
 gdb/infrun.c |    7 +++++++
 1 file changed, 7 insertions(+)

Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2009-10-23 19:05:17.000000000 +0100
+++ src/gdb/infrun.c	2009-10-28 16:04:20.000000000 +0000
@@ -4812,6 +4812,10 @@ stop_stepping (struct execution_control_
 static void
 keep_going (struct execution_control_state *ecs)
 {
+  /* Make sure normal_stop is called if we get a QUIT handled before
+     reaching resume.  */
+  struct cleanup *old_cleanups = make_cleanup (resume_cleanups, 0);
+
   /* Save the pc before execution, to compare with pc after stop.  */
   ecs->event_thread->prev_pc
     = regcache_read_pc (get_thread_regcache (ecs->ptid));
@@ -4825,6 +4829,8 @@ keep_going (struct execution_control_sta
       /* We took a signal (which we are supposed to pass through to
 	 the inferior, else we'd not get here) and we haven't yet
 	 gotten our trap.  Simply continue.  */
+
+      discard_cleanups (old_cleanups);
       resume (currently_stepping (ecs->event_thread),
 	      ecs->event_thread->stop_signal);
     }
@@ -4887,6 +4893,7 @@ keep_going (struct execution_control_sta
 	  && !signal_program[ecs->event_thread->stop_signal])
 	ecs->event_thread->stop_signal = TARGET_SIGNAL_0;
 
+      discard_cleanups (old_cleanups);
       resume (currently_stepping (ecs->event_thread),
 	      ecs->event_thread->stop_signal);
     }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]