displaced_step_finish: Don't fetch the regcache of exited threads
displaced_step_finish can be called with event_status.kind == TARGET_WAITKIND_THREAD_EXITED, and in that case it is not possible to get at the already-exited thread's registers. This patch moves the get_thread_regcache calls to branches that actually need it, where we know the thread is still alive. It also adds an assertion to get_thread_regcache, to help catching these broken cases sooner. Approved-By: Simon Marchi <simon.marchi@efficios.com> Change-Id: I63b5eacb3e02a538fc5087c270d8025adfda88c3
This commit is contained in:
parent
d0b5914979
commit
249d081287
2 changed files with 14 additions and 7 deletions
19
gdb/infrun.c
19
gdb/infrun.c
|
@ -2021,8 +2021,6 @@ displaced_step_finish (thread_info *event_thread,
|
|||
const target_waitstatus &event_status)
|
||||
{
|
||||
/* Check whether the parent is displaced stepping. */
|
||||
struct regcache *regcache = get_thread_regcache (event_thread);
|
||||
struct gdbarch *gdbarch = regcache->arch ();
|
||||
inferior *parent_inf = event_thread->inf;
|
||||
|
||||
/* If this was a fork/vfork/clone, this event indicates that the
|
||||
|
@ -2040,10 +2038,15 @@ displaced_step_finish (thread_info *event_thread,
|
|||
gdbarch_displaced_step_restore_all_in_ptid. This is not enforced
|
||||
during gdbarch validation to support architectures which support
|
||||
displaced stepping but not forks. */
|
||||
if (event_status.kind () == TARGET_WAITKIND_FORKED
|
||||
&& gdbarch_supports_displaced_stepping (gdbarch))
|
||||
gdbarch_displaced_step_restore_all_in_ptid
|
||||
(gdbarch, parent_inf, event_status.child_ptid ());
|
||||
if (event_status.kind () == TARGET_WAITKIND_FORKED)
|
||||
{
|
||||
struct regcache *parent_regcache = get_thread_regcache (event_thread);
|
||||
struct gdbarch *gdbarch = parent_regcache->arch ();
|
||||
|
||||
if (gdbarch_supports_displaced_stepping (gdbarch))
|
||||
gdbarch_displaced_step_restore_all_in_ptid
|
||||
(gdbarch, parent_inf, event_status.child_ptid ());
|
||||
}
|
||||
|
||||
displaced_step_thread_state *displaced = &event_thread->displaced_step_state;
|
||||
|
||||
|
@ -2082,11 +2085,13 @@ displaced_step_finish (thread_info *event_thread,
|
|||
child hasn't been added to the inferior list yet at this
|
||||
point. */
|
||||
|
||||
struct regcache *parent_regcache = get_thread_regcache (event_thread);
|
||||
struct gdbarch *gdbarch = parent_regcache->arch ();
|
||||
struct regcache *child_regcache
|
||||
= get_thread_arch_regcache (parent_inf, event_status.child_ptid (),
|
||||
gdbarch);
|
||||
/* Read PC value of parent. */
|
||||
CORE_ADDR parent_pc = regcache_read_pc (regcache);
|
||||
CORE_ADDR parent_pc = regcache_read_pc (parent_regcache);
|
||||
|
||||
displaced_debug_printf ("write child pc from %s to %s",
|
||||
paddress (gdbarch,
|
||||
|
|
|
@ -430,6 +430,8 @@ get_thread_regcache (process_stratum_target *target, ptid_t ptid)
|
|||
struct regcache *
|
||||
get_thread_regcache (thread_info *thread)
|
||||
{
|
||||
gdb_assert (thread->state != THREAD_EXITED);
|
||||
|
||||
return get_thread_regcache (thread->inf->process_target (),
|
||||
thread->ptid);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue