fix PR gdb/17130

This fixes PR gdb/17130.

The bug is that some code in utils.c was not updated during the target
delegation change:

  if (job_control
      /* If there is no terminal switching for this target, then we can't
         possibly get screwed by the lack of job control.  */
      || current_target.to_terminal_ours == NULL)
    fatal ("Quit");
  else
    fatal ("Quit (expect signal SIGINT when the program is resumed)");

After the delegation change, to_terminal_ours will never be NULL.

I think this bug can be seen before the target delegation change by
enabling target debugging -- this would also cause to_terminal_ours to
be non-NULL.

The fix is to introduce a new target_supports_terminal_ours function,
that properly checks the target stack.  This is not perhaps ideal, but
I think is a reasonable-enough approach, and in keeping with some
other existing code of the same form.

This patch also fixes a similar bug in target_supports_delete_record.

2014-07-18  Tom Tromey  <tromey@redhat.com>

	PR gdb/17130:
	* utils.c (quit): Use target_supports_terminal_ours.
	* target.h (target_supports_terminal_ours): Declare.
	* target.c (target_supports_delete_record): Don't check
	to_delete_record against NULL.
	(target_supports_terminal_ours): New function.
This commit is contained in:
Tom Tromey 2014-07-11 08:30:34 -06:00
parent e75fdfcad1
commit b0ed115fa5
4 changed files with 34 additions and 2 deletions

View file

@ -1,3 +1,12 @@
2014-07-18 Tom Tromey <tromey@redhat.com>
PR gdb/17130:
* utils.c (quit): Use target_supports_terminal_ours.
* target.h (target_supports_terminal_ours): Declare.
* target.c (target_supports_delete_record): Don't check
to_delete_record against NULL.
(target_supports_terminal_ours): New function.
2014-07-18 Tom Tromey <tromey@redhat.com>
PR gdb/17130:

View file

@ -499,6 +499,23 @@ target_terminal_inferior (void)
(*current_target.to_terminal_inferior) (&current_target);
}
/* See target.h. */
int
target_supports_terminal_ours (void)
{
struct target_ops *t;
for (t = current_target.beneath; t != NULL; t = t->beneath)
{
if (t->to_terminal_ours != delegate_terminal_ours
&& t->to_terminal_ours != tdefault_terminal_ours)
return 1;
}
return 0;
}
static void
tcomplain (void)
{
@ -3457,7 +3474,8 @@ target_supports_delete_record (void)
struct target_ops *t;
for (t = current_target.beneath; t != NULL; t = t->beneath)
if (t->to_delete_record != NULL)
if (t->to_delete_record != delegate_delete_record
&& t->to_delete_record != tdefault_delete_record)
return 1;
return 0;

View file

@ -1397,6 +1397,11 @@ extern void target_terminal_inferior (void);
#define target_terminal_ours() \
(*current_target.to_terminal_ours) (&current_target)
/* Return true if the target stack has a non-default
"to_terminal_ours" method. */
extern int target_supports_terminal_ours (void);
/* Save our terminal settings.
This is called from TUI after entering or leaving the curses
mode. Since curses modifies our terminal this call is here

View file

@ -1095,7 +1095,7 @@ quit (void)
if (job_control
/* If there is no terminal switching for this target, then we can't
possibly get screwed by the lack of job control. */
|| current_target.to_terminal_ours == NULL)
|| !target_supports_terminal_ours ())
fatal ("Quit");
else
fatal ("Quit (expect signal SIGINT when the program is resumed)");