Skip to content

Commit

Permalink
Fix swallowed "Quit" when inserting breakpoints
Browse files Browse the repository at this point in the history
If GDB is inserting a breakpoint and you type Ctrl-C at the exact
"right" time, you'll hit a QUIT call in target_read, and the
breakpoint insertion is cancelled.  However, the related TRY/CATCH
code in insert_bp_location does:

 		  CATCH (e, RETURN_MASK_ALL)
 		    {
		      bp_err = e.error;
		      bp_err_message = e.message;
		    }

The problem with that is that a RETURN_QUIT exception has e.error ==
0, which means that further below, in the places that check for error
with:

      if (bp_err != GDB_NO_ERROR)

because GDB_NO_ERROR == 0, GDB continues as if the breakpoint was
inserted succesfully, and resumes the inferior.  Since the breakpoint
wasn't inserted the inferior runs free, out of our control...

Fix this by having insert_bp_location store a copy of the whole
exception instead of just a error/message parts, and then checking
"gdb_exception::reason" instead.

This was exposed by the new gdb.base/bp-cmds-continue-ctrl-c.exp
testcase added later in the series.

gdb/ChangeLog:
2017-11-16  Pedro Alves  <[email protected]>

	* breakpoint.c (insert_bp_location): Replace bp_err and
	bp_err_message locals by a gdb_exception local.
  • Loading branch information
palves committed Nov 16, 2017
1 parent e2c33ac commit 688fca4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 20 deletions.
5 changes: 5 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2017-11-16 Pedro Alves <[email protected]>

* breakpoint.c (insert_bp_location): Replace bp_err and
bp_err_message locals by a gdb_exception local.

2017-11-16 Pedro Alves <[email protected]>

* inflow.c (scoped_ignore_sigttou): New class.
Expand Down
41 changes: 21 additions & 20 deletions gdb/breakpoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -2458,8 +2458,7 @@ insert_bp_location (struct bp_location *bl,
int *hw_breakpoint_error,
int *hw_bp_error_explained_already)
{
enum errors bp_err = GDB_NO_ERROR;
const char *bp_err_message = NULL;
gdb_exception bp_excpt = exception_none;

if (!should_be_inserted (bl) || (bl->inserted && !bl->needs_update))
return 0;
Expand Down Expand Up @@ -2568,12 +2567,11 @@ insert_bp_location (struct bp_location *bl,

val = bl->owner->ops->insert_location (bl);
if (val)
bp_err = GENERIC_ERROR;
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
bp_err = e.error;
bp_err_message = e.message;
bp_excpt = e;
}
END_CATCH
}
Expand Down Expand Up @@ -2608,16 +2606,16 @@ insert_bp_location (struct bp_location *bl,
val = target_insert_breakpoint (bl->gdbarch,
&bl->overlay_target_info);
if (val)
bp_err = GENERIC_ERROR;
bp_excpt
= gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
bp_err = e.error;
bp_err_message = e.message;
bp_excpt = e;
}
END_CATCH

if (bp_err != GDB_NO_ERROR)
if (bp_excpt.reason != 0)
fprintf_unfiltered (tmp_error_stream,
"Overlay breakpoint %d "
"failed: in ROM?\n",
Expand All @@ -2634,12 +2632,11 @@ insert_bp_location (struct bp_location *bl,

val = bl->owner->ops->insert_location (bl);
if (val)
bp_err = GENERIC_ERROR;
bp_excpt = gdb_exception {RETURN_ERROR, GENERIC_ERROR};
}
CATCH (e, RETURN_MASK_ALL)
{
bp_err = e.error;
bp_err_message = e.message;
bp_excpt = e;
}
END_CATCH
}
Expand All @@ -2651,7 +2648,7 @@ insert_bp_location (struct bp_location *bl,
}
}

if (bp_err != GDB_NO_ERROR)
if (bp_excpt.reason != 0)
{
/* Can't set the breakpoint. */

Expand All @@ -2663,7 +2660,9 @@ insert_bp_location (struct bp_location *bl,
breakpoint insertion failed (e.g., the remote target
doesn't define error codes), so we must treat generic
errors as memory errors. */
if ((bp_err == GENERIC_ERROR || bp_err == MEMORY_ERROR)
if (bp_excpt.reason == RETURN_ERROR
&& (bp_excpt.error == GENERIC_ERROR
|| bp_excpt.error == MEMORY_ERROR)
&& bl->loc_type == bp_loc_software_breakpoint
&& (solib_name_from_address (bl->pspace, bl->address)
|| shared_objfile_contains_address_p (bl->pspace,
Expand Down Expand Up @@ -2691,16 +2690,18 @@ insert_bp_location (struct bp_location *bl,
if (bl->loc_type == bp_loc_hardware_breakpoint)
{
*hw_breakpoint_error = 1;
*hw_bp_error_explained_already = bp_err_message != NULL;
*hw_bp_error_explained_already = bp_excpt.message != NULL;
fprintf_unfiltered (tmp_error_stream,
"Cannot insert hardware breakpoint %d%s",
bl->owner->number, bp_err_message ? ":" : ".\n");
if (bp_err_message != NULL)
fprintf_unfiltered (tmp_error_stream, "%s.\n", bp_err_message);
bl->owner->number,
bp_excpt.message ? ":" : ".\n");
if (bp_excpt.message != NULL)
fprintf_unfiltered (tmp_error_stream, "%s.\n",
bp_excpt.message);
}
else
{
if (bp_err_message == NULL)
if (bp_excpt.message == NULL)
{
std::string message
= memory_error_message (TARGET_XFER_E_IO,
Expand All @@ -2716,7 +2717,7 @@ insert_bp_location (struct bp_location *bl,
fprintf_unfiltered (tmp_error_stream,
"Cannot insert breakpoint %d: %s\n",
bl->owner->number,
bp_err_message);
bp_excpt.message);
}
}
return 1;
Expand Down

0 comments on commit 688fca4

Please sign in to comment.