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.
This commit is contained in:
parent
9d95b8e9d6
commit
fc75c28ba1
@ -1,3 +1,12 @@
|
||||
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.
|
||||
|
||||
2020-05-13 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* ada-lang.c (align_value): Remove.
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -1220,6 +1220,24 @@ regcache_read_pc (struct regcache *regcache)
|
||||
return pc_val;
|
||||
}
|
||||
|
||||
/* See gdbsupport/common-regcache.h. */
|
||||
|
||||
CORE_ADDR
|
||||
regcache_read_pc_protected (regcache *regcache)
|
||||
{
|
||||
CORE_ADDR pc;
|
||||
try
|
||||
{
|
||||
pc = regcache_read_pc (regcache);
|
||||
}
|
||||
catch (const gdb_exception_error &ex)
|
||||
{
|
||||
pc = 0;
|
||||
}
|
||||
|
||||
return pc;
|
||||
}
|
||||
|
||||
void
|
||||
regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
|
||||
{
|
||||
|
@ -1,3 +1,8 @@
|
||||
2020-05-14 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* common-regcache.h (regcache_read_pc_protected): New function
|
||||
declaration.
|
||||
|
||||
2020-04-28 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
||||
|
||||
* gdb-sigmask.h: Fix typo (pthead_sigmask -> pthread_sigmask).
|
||||
|
@ -56,6 +56,11 @@ extern int regcache_register_size (const struct regcache *regcache, int n);
|
||||
|
||||
extern CORE_ADDR regcache_read_pc (struct regcache *regcache);
|
||||
|
||||
/* Read the PC register. If PC cannot be read, return 0.
|
||||
This is a wrapper around 'regcache_read_pc'. */
|
||||
|
||||
extern CORE_ADDR regcache_read_pc_protected (regcache *regcache);
|
||||
|
||||
/* Read a raw register into a unsigned integer. */
|
||||
extern enum register_status regcache_raw_read_unsigned
|
||||
(struct regcache *regcache, int regnum, ULONGEST *val);
|
||||
|
Loading…
Reference in New Issue
Block a user