aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@ericsson.com>2014-12-10 13:03:47 -0500
committerSimon Marchi <simon.marchi@ericsson.com>2014-12-10 13:03:47 -0500
commit1abf3a143773819e195fceaa485060dcac9e6089 (patch)
treef1d0a6fee8726be5a383e7d554c1da0a182d4c66 /gdb
parentf4943d8253e8c9c539fd72d23e94a65f84c92d1a (diff)
downloadgdb-1abf3a143773819e195fceaa485060dcac9e6089.zip
gdb-1abf3a143773819e195fceaa485060dcac9e6089.tar.gz
gdb-1abf3a143773819e195fceaa485060dcac9e6089.tar.bz2
Restore terminal state in mi_thread_exit (PR gdb/17627)
When a thread exits, the terminal is left in mode "terminal_is_ours" while the target executes. This patch fixes that. We need to manually restore the terminal setting in this particular observer. In the case of the other MI observers that call target_terminal_ours, gdb will end up resuming the inferior later in the execution and call target_terminal_inferior. In the case of the thread exit event, we still need to call target_terminal_ours to be able to print something, but there is nothing that gdb will need to resume after that. We therefore need to call target_terminal_inferior ourselves. gdb/ChangeLog: PR gdb/17627 * target.c (cleanup_restore_target_terminal): New function. (make_cleanup_restore_target_terminal): New function. * target.h (make_cleanup_restore_target_terminal): New declaration. * mi/mi-interp.c (mi_thread_exit): Use the new cleanup. Signed-off-by: Simon Marchi <simon.marchi@ericsson.com>
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/mi/mi-interp.c4
-rw-r--r--gdb/target.c34
-rw-r--r--gdb/target.h4
4 files changed, 50 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ad845a7..4aeb0cc 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2014-12-10 Simon Marchi <simon.marchi@ericsson.com>
+
+ PR gdb/17627
+ * target.c (cleanup_restore_target_terminal): New function.
+ (make_cleanup_restore_target_terminal): New function.
+ * target.h (make_cleanup_restore_target_terminal): New declaration.
+ * mi/mi-interp.c (mi_thread_exit): Use the new cleanup.
+
2014-12-08 Doug Evans <dje@google.com>
* python/py-objfile.c (objfpy_get_owner): Increment refcount of result.
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c
index df2b558..60f0666 100644
--- a/gdb/mi/mi-interp.c
+++ b/gdb/mi/mi-interp.c
@@ -386,6 +386,7 @@ mi_thread_exit (struct thread_info *t, int silent)
{
struct mi_interp *mi;
struct inferior *inf;
+ struct cleanup *old_chain;
if (silent)
return;
@@ -393,11 +394,14 @@ mi_thread_exit (struct thread_info *t, int silent)
inf = find_inferior_pid (ptid_get_pid (t->ptid));
mi = top_level_interpreter_data ();
+ old_chain = make_cleanup_restore_target_terminal ();
target_terminal_ours ();
fprintf_unfiltered (mi->event_channel,
"thread-exited,id=\"%d\",group-id=\"i%d\"",
t->num, inf->num);
gdb_flush (mi->event_channel);
+
+ do_cleanups (old_chain);
}
/* Emit notification on changing the state of record. */
diff --git a/gdb/target.c b/gdb/target.c
index ab5f2b9..7161e62 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -528,6 +528,40 @@ target_supports_terminal_ours (void)
return 0;
}
+/* Restore the terminal to its previous state (helper for
+ make_cleanup_restore_target_terminal). */
+
+static void
+cleanup_restore_target_terminal (void *arg)
+{
+ enum terminal_state *previous_state = arg;
+
+ switch (*previous_state)
+ {
+ case terminal_is_ours:
+ target_terminal_ours ();
+ break;
+ case terminal_is_ours_for_output:
+ target_terminal_ours_for_output ();
+ break;
+ case terminal_is_inferior:
+ target_terminal_inferior ();
+ break;
+ }
+}
+
+/* See target.h. */
+
+struct cleanup *
+make_cleanup_restore_target_terminal (void)
+{
+ enum terminal_state *ts = xmalloc (sizeof (*ts));
+
+ *ts = terminal_state;
+
+ return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
+}
+
static void
tcomplain (void)
{
diff --git a/gdb/target.h b/gdb/target.h
index d363b61..cff146a 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -1413,6 +1413,10 @@ extern void target_terminal_ours (void);
extern int target_supports_terminal_ours (void);
+/* Make a cleanup that restores the state of the terminal to the current
+ state. */
+extern struct cleanup *make_cleanup_restore_target_terminal (void);
+
/* Print useful information about our terminal status, if such a thing
exists. */