summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2017-11-16 18:44:42 +0000
committerPedro Alves <palves@redhat.com>2017-11-16 18:44:42 +0000
commit688fca4fe6c83a6802731faa8455d177998d614d (patch)
tree6aa69934c00de76f93c0f3998271e75f30427ac6
parente2c33ac745108550dcc2dc61d23378fb2fa9e911 (diff)
downloadbinutils-gdb-688fca4fe6c83a6802731faa8455d177998d614d.tar.gz
Fix swallowed "Quit" when inserting breakpoints
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 <palves@redhat.com> * breakpoint.c (insert_bp_location): Replace bp_err and bp_err_message locals by a gdb_exception local.
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/breakpoint.c41
2 files changed, 26 insertions, 20 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 52bd6156254..23403b6cfef 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,10 @@
2017-11-16 Pedro Alves <palves@redhat.com>
+ * breakpoint.c (insert_bp_location): Replace bp_err and
+ bp_err_message locals by a gdb_exception local.
+
+2017-11-16 Pedro Alves <palves@redhat.com>
+
* inflow.c (scoped_ignore_sigttou): New class.
(child_terminal_ours_1, new_tty): Use it.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index b170a14cb58..516cccfd88c 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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;
@@ -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
}
@@ -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",
@@ -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
}
@@ -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. */
@@ -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,
@@ -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,
@@ -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;