aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-05-14 13:59:53 +0200
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>2020-05-14 13:59:53 +0200
commitfc75c28ba1ea7353fb6e1e5904c5703a48504b67 (patch)
tree5b1a59f1c2cb60a34c7ca6b34e7868aaac49c975 /gdb/infrun.c
parent9d95b8e9d631e76eb152c86003db6b89e913bdd9 (diff)
downloadgdb-fc75c28ba1ea7353fb6e1e5904c5703a48504b67.zip
gdb-fc75c28ba1ea7353fb6e1e5904c5703a48504b67.tar.gz
gdb-fc75c28ba1ea7353fb6e1e5904c5703a48504b67.tar.bz2
gdb: protect some 'regcache_read_pc' calls
It possible that a thread whose PC we attempt to read is already dead. In this case, 'regcache_read_pc' errors out. This impacts the "proceed" execution flow, where GDB quits early before having a chance to check if there exists a pending event. To remedy, keep going with a 0 value for the PC if 'regcache_read_pc' fails. Because the value of PC before resuming a thread is mostly used for storing and checking the next time the thread stops, this tolerance is expected to be harmless for a dead thread/process. gdb/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * regcache.c (regcache_read_pc_protected): New function implementation that returns 0 if the PC cannot read via 'regcache_read_pc'. * infrun.c (proceed): Call 'regcache_read_pc_protected' instead of 'regcache_read_pc'. (keep_going_pass_signal): Ditto. gdbsupport/ChangeLog: 2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> * common-regcache.h (regcache_read_pc_protected): New function declaration.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 3c6b201..5e01336 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2995,7 +2995,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
gdbarch = regcache->arch ();
const address_space *aspace = regcache->aspace ();
- pc = regcache_read_pc (regcache);
+ pc = regcache_read_pc_protected (regcache);
+
thread_info *cur_thr = inferior_thread ();
/* Fill in with reasonable starting values. */
@@ -3122,7 +3123,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
advanced. Must do this before resuming any thread, as in
all-stop/remote, once we resume we can't send any other packet
until the target stops again. */
- cur_thr->prev_pc = regcache_read_pc (regcache);
+ cur_thr->prev_pc = regcache_read_pc_protected (regcache);
{
scoped_restore save_defer_tc = make_scoped_defer_target_commit_resume ();
@@ -7929,7 +7930,7 @@ keep_going_pass_signal (struct execution_control_state *ecs)
/* Save the pc before execution, to compare with pc after stop. */
ecs->event_thread->prev_pc
- = regcache_read_pc (get_thread_regcache (ecs->event_thread));
+ = regcache_read_pc_protected (get_thread_regcache (ecs->event_thread));
if (ecs->event_thread->control.trap_expected)
{