mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 09:58:19 +08:00
Per-process displaced stepping queue.
* infrun.c (displaced_step_ptid, displaced_step_request_queue) (displaced_step_gdbarch, displaced_step_closure, (displaced_step_original, displaced_step_copy): Move globals to this... (struct displaced_step_inferior_state): ... new structure. (displaced_step_inferior_states): New global. (get_displaced_stepping_state, add_displaced_stepping_state) (remove_displaced_stepping_state, infrun_inferior_exit): New functions. (displaced_step_clear): Add displaced_step_inferior_state parameter, and adjust to handle it. (displaced_step_clear_cleanup): Parameter is now a displaced_step_inferior_state. Adjust. (displaced_step_prepare): Adjust. (displaced_step_fixup, displaced_step_fixup) (infrun_thread_ptid_changed, resume): Adjust. (init_wait_for_inferior): Don't call displaced_step_clear. (infrun_thread_stop_requested): Rewrite. (_initialize_infrun): Install infrun_inferior_exit as inferior_exit observer.
This commit is contained in:
@ -1,3 +1,28 @@
|
|||||||
|
2010-02-24 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
|
Per-process displaced stepping queue.
|
||||||
|
|
||||||
|
* infrun.c (displaced_step_ptid, displaced_step_request_queue)
|
||||||
|
(displaced_step_gdbarch, displaced_step_closure,
|
||||||
|
(displaced_step_original, displaced_step_copy): Move globals to
|
||||||
|
this...
|
||||||
|
(struct displaced_step_inferior_state): ... new structure.
|
||||||
|
(displaced_step_inferior_states): New global.
|
||||||
|
(get_displaced_stepping_state, add_displaced_stepping_state)
|
||||||
|
(remove_displaced_stepping_state, infrun_inferior_exit): New
|
||||||
|
functions.
|
||||||
|
(displaced_step_clear): Add displaced_step_inferior_state
|
||||||
|
parameter, and adjust to handle it.
|
||||||
|
(displaced_step_clear_cleanup): Parameter is now a
|
||||||
|
displaced_step_inferior_state. Adjust.
|
||||||
|
(displaced_step_prepare): Adjust.
|
||||||
|
(displaced_step_fixup, displaced_step_fixup)
|
||||||
|
(infrun_thread_ptid_changed, resume): Adjust.
|
||||||
|
(init_wait_for_inferior): Don't call displaced_step_clear.
|
||||||
|
(infrun_thread_stop_requested): Rewrite.
|
||||||
|
(_initialize_infrun): Install infrun_inferior_exit as
|
||||||
|
inferior_exit observer.
|
||||||
|
|
||||||
2010-02-24 Pedro Alves <pedro@codesourcery.com>
|
2010-02-24 Pedro Alves <pedro@codesourcery.com>
|
||||||
|
|
||||||
* inferior.h (ptid_match): Declare.
|
* inferior.h (ptid_match): Declare.
|
||||||
|
287
gdb/infrun.c
287
gdb/infrun.c
@ -892,32 +892,118 @@ static ptid_t deferred_step_ptid;
|
|||||||
displaced step operation on it. See displaced_step_prepare and
|
displaced step operation on it. See displaced_step_prepare and
|
||||||
displaced_step_fixup for details. */
|
displaced_step_fixup for details. */
|
||||||
|
|
||||||
/* If this is not null_ptid, this is the thread carrying out a
|
|
||||||
displaced single-step. This thread's state will require fixing up
|
|
||||||
once it has completed its step. */
|
|
||||||
static ptid_t displaced_step_ptid;
|
|
||||||
|
|
||||||
struct displaced_step_request
|
struct displaced_step_request
|
||||||
{
|
{
|
||||||
ptid_t ptid;
|
ptid_t ptid;
|
||||||
struct displaced_step_request *next;
|
struct displaced_step_request *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A queue of pending displaced stepping requests. */
|
/* Per-inferior displaced stepping state. */
|
||||||
struct displaced_step_request *displaced_step_request_queue;
|
struct displaced_step_inferior_state
|
||||||
|
{
|
||||||
|
/* Pointer to next in linked list. */
|
||||||
|
struct displaced_step_inferior_state *next;
|
||||||
|
|
||||||
/* The architecture the thread had when we stepped it. */
|
/* The process this displaced step state refers to. */
|
||||||
static struct gdbarch *displaced_step_gdbarch;
|
int pid;
|
||||||
|
|
||||||
/* The closure provided gdbarch_displaced_step_copy_insn, to be used
|
/* A queue of pending displaced stepping requests. One entry per
|
||||||
for post-step cleanup. */
|
thread that needs to do a displaced step. */
|
||||||
static struct displaced_step_closure *displaced_step_closure;
|
struct displaced_step_request *step_request_queue;
|
||||||
|
|
||||||
/* The address of the original instruction, and the copy we made. */
|
/* If this is not null_ptid, this is the thread carrying out a
|
||||||
static CORE_ADDR displaced_step_original, displaced_step_copy;
|
displaced single-step in process PID. This thread's state will
|
||||||
|
require fixing up once it has completed its step. */
|
||||||
|
ptid_t step_ptid;
|
||||||
|
|
||||||
/* Saved contents of copy area. */
|
/* The architecture the thread had when we stepped it. */
|
||||||
static gdb_byte *displaced_step_saved_copy;
|
struct gdbarch *step_gdbarch;
|
||||||
|
|
||||||
|
/* The closure provided gdbarch_displaced_step_copy_insn, to be used
|
||||||
|
for post-step cleanup. */
|
||||||
|
struct displaced_step_closure *step_closure;
|
||||||
|
|
||||||
|
/* The address of the original instruction, and the copy we
|
||||||
|
made. */
|
||||||
|
CORE_ADDR step_original, step_copy;
|
||||||
|
|
||||||
|
/* Saved contents of copy area. */
|
||||||
|
gdb_byte *step_saved_copy;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The list of states of processes involved in displaced stepping
|
||||||
|
presently. */
|
||||||
|
static struct displaced_step_inferior_state *displaced_step_inferior_states;
|
||||||
|
|
||||||
|
/* Get the displaced stepping state of process PID. */
|
||||||
|
|
||||||
|
static struct displaced_step_inferior_state *
|
||||||
|
get_displaced_stepping_state (int pid)
|
||||||
|
{
|
||||||
|
struct displaced_step_inferior_state *state;
|
||||||
|
|
||||||
|
for (state = displaced_step_inferior_states;
|
||||||
|
state != NULL;
|
||||||
|
state = state->next)
|
||||||
|
if (state->pid == pid)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add a new displaced stepping state for process PID to the displaced
|
||||||
|
stepping state list, or return a pointer to an already existing
|
||||||
|
entry, if it already exists. Never returns NULL. */
|
||||||
|
|
||||||
|
static struct displaced_step_inferior_state *
|
||||||
|
add_displaced_stepping_state (int pid)
|
||||||
|
{
|
||||||
|
struct displaced_step_inferior_state *state;
|
||||||
|
|
||||||
|
for (state = displaced_step_inferior_states;
|
||||||
|
state != NULL;
|
||||||
|
state = state->next)
|
||||||
|
if (state->pid == pid)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
state = xcalloc (1, sizeof (*state));
|
||||||
|
state->pid = pid;
|
||||||
|
state->next = displaced_step_inferior_states;
|
||||||
|
displaced_step_inferior_states = state;
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the displaced stepping state of process PID. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_displaced_stepping_state (int pid)
|
||||||
|
{
|
||||||
|
struct displaced_step_inferior_state *it, **prev_next_p;
|
||||||
|
|
||||||
|
gdb_assert (pid != 0);
|
||||||
|
|
||||||
|
it = displaced_step_inferior_states;
|
||||||
|
prev_next_p = &displaced_step_inferior_states;
|
||||||
|
while (it)
|
||||||
|
{
|
||||||
|
if (it->pid == pid)
|
||||||
|
{
|
||||||
|
*prev_next_p = it->next;
|
||||||
|
xfree (it);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_next_p = &it->next;
|
||||||
|
it = *prev_next_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
infrun_inferior_exit (struct inferior *inf)
|
||||||
|
{
|
||||||
|
remove_displaced_stepping_state (inf->pid);
|
||||||
|
}
|
||||||
|
|
||||||
/* Enum strings for "set|show displaced-stepping". */
|
/* Enum strings for "set|show displaced-stepping". */
|
||||||
|
|
||||||
@ -974,23 +1060,25 @@ use_displaced_stepping (struct gdbarch *gdbarch)
|
|||||||
|
|
||||||
/* Clean out any stray displaced stepping state. */
|
/* Clean out any stray displaced stepping state. */
|
||||||
static void
|
static void
|
||||||
displaced_step_clear (void)
|
displaced_step_clear (struct displaced_step_inferior_state *displaced)
|
||||||
{
|
{
|
||||||
/* Indicate that there is no cleanup pending. */
|
/* Indicate that there is no cleanup pending. */
|
||||||
displaced_step_ptid = null_ptid;
|
displaced->step_ptid = null_ptid;
|
||||||
|
|
||||||
if (displaced_step_closure)
|
if (displaced->step_closure)
|
||||||
{
|
{
|
||||||
gdbarch_displaced_step_free_closure (displaced_step_gdbarch,
|
gdbarch_displaced_step_free_closure (displaced->step_gdbarch,
|
||||||
displaced_step_closure);
|
displaced->step_closure);
|
||||||
displaced_step_closure = NULL;
|
displaced->step_closure = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
displaced_step_clear_cleanup (void *ignore)
|
displaced_step_clear_cleanup (void *arg)
|
||||||
{
|
{
|
||||||
displaced_step_clear ();
|
struct displaced_step_inferior_state *state = arg;
|
||||||
|
|
||||||
|
displaced_step_clear (state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump LEN bytes at BUF in hex to FILE, followed by a newline. */
|
/* Dump LEN bytes at BUF in hex to FILE, followed by a newline. */
|
||||||
@ -1029,15 +1117,18 @@ displaced_step_prepare (ptid_t ptid)
|
|||||||
CORE_ADDR original, copy;
|
CORE_ADDR original, copy;
|
||||||
ULONGEST len;
|
ULONGEST len;
|
||||||
struct displaced_step_closure *closure;
|
struct displaced_step_closure *closure;
|
||||||
|
struct displaced_step_inferior_state *displaced;
|
||||||
|
|
||||||
/* We should never reach this function if the architecture does not
|
/* We should never reach this function if the architecture does not
|
||||||
support displaced stepping. */
|
support displaced stepping. */
|
||||||
gdb_assert (gdbarch_displaced_step_copy_insn_p (gdbarch));
|
gdb_assert (gdbarch_displaced_step_copy_insn_p (gdbarch));
|
||||||
|
|
||||||
/* For the first cut, we're displaced stepping one thread at a
|
/* We have to displaced step one thread at a time, as we only have
|
||||||
time. */
|
access to a single scratch space per inferior. */
|
||||||
|
|
||||||
if (!ptid_equal (displaced_step_ptid, null_ptid))
|
displaced = add_displaced_stepping_state (ptid_get_pid (ptid));
|
||||||
|
|
||||||
|
if (!ptid_equal (displaced->step_ptid, null_ptid))
|
||||||
{
|
{
|
||||||
/* Already waiting for a displaced step to finish. Defer this
|
/* Already waiting for a displaced step to finish. Defer this
|
||||||
request and place in queue. */
|
request and place in queue. */
|
||||||
@ -1052,16 +1143,16 @@ displaced_step_prepare (ptid_t ptid)
|
|||||||
new_req->ptid = ptid;
|
new_req->ptid = ptid;
|
||||||
new_req->next = NULL;
|
new_req->next = NULL;
|
||||||
|
|
||||||
if (displaced_step_request_queue)
|
if (displaced->step_request_queue)
|
||||||
{
|
{
|
||||||
for (req = displaced_step_request_queue;
|
for (req = displaced->step_request_queue;
|
||||||
req && req->next;
|
req && req->next;
|
||||||
req = req->next)
|
req = req->next)
|
||||||
;
|
;
|
||||||
req->next = new_req;
|
req->next = new_req;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
displaced_step_request_queue = new_req;
|
displaced->step_request_queue = new_req;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1073,7 +1164,7 @@ displaced_step_prepare (ptid_t ptid)
|
|||||||
target_pid_to_str (ptid));
|
target_pid_to_str (ptid));
|
||||||
}
|
}
|
||||||
|
|
||||||
displaced_step_clear ();
|
displaced_step_clear (displaced);
|
||||||
|
|
||||||
old_cleanups = save_inferior_ptid ();
|
old_cleanups = save_inferior_ptid ();
|
||||||
inferior_ptid = ptid;
|
inferior_ptid = ptid;
|
||||||
@ -1084,15 +1175,17 @@ displaced_step_prepare (ptid_t ptid)
|
|||||||
len = gdbarch_max_insn_length (gdbarch);
|
len = gdbarch_max_insn_length (gdbarch);
|
||||||
|
|
||||||
/* Save the original contents of the copy area. */
|
/* Save the original contents of the copy area. */
|
||||||
displaced_step_saved_copy = xmalloc (len);
|
displaced->step_saved_copy = xmalloc (len);
|
||||||
ignore_cleanups = make_cleanup (free_current_contents,
|
ignore_cleanups = make_cleanup (free_current_contents,
|
||||||
&displaced_step_saved_copy);
|
&displaced->step_saved_copy);
|
||||||
read_memory (copy, displaced_step_saved_copy, len);
|
read_memory (copy, displaced->step_saved_copy, len);
|
||||||
if (debug_displaced)
|
if (debug_displaced)
|
||||||
{
|
{
|
||||||
fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
|
fprintf_unfiltered (gdb_stdlog, "displaced: saved %s: ",
|
||||||
paddress (gdbarch, copy));
|
paddress (gdbarch, copy));
|
||||||
displaced_step_dump_bytes (gdb_stdlog, displaced_step_saved_copy, len);
|
displaced_step_dump_bytes (gdb_stdlog,
|
||||||
|
displaced->step_saved_copy,
|
||||||
|
len);
|
||||||
};
|
};
|
||||||
|
|
||||||
closure = gdbarch_displaced_step_copy_insn (gdbarch,
|
closure = gdbarch_displaced_step_copy_insn (gdbarch,
|
||||||
@ -1103,13 +1196,13 @@ displaced_step_prepare (ptid_t ptid)
|
|||||||
|
|
||||||
/* Save the information we need to fix things up if the step
|
/* Save the information we need to fix things up if the step
|
||||||
succeeds. */
|
succeeds. */
|
||||||
displaced_step_ptid = ptid;
|
displaced->step_ptid = ptid;
|
||||||
displaced_step_gdbarch = gdbarch;
|
displaced->step_gdbarch = gdbarch;
|
||||||
displaced_step_closure = closure;
|
displaced->step_closure = closure;
|
||||||
displaced_step_original = original;
|
displaced->step_original = original;
|
||||||
displaced_step_copy = copy;
|
displaced->step_copy = copy;
|
||||||
|
|
||||||
make_cleanup (displaced_step_clear_cleanup, 0);
|
make_cleanup (displaced_step_clear_cleanup, displaced);
|
||||||
|
|
||||||
/* Resume execution at the copy. */
|
/* Resume execution at the copy. */
|
||||||
regcache_write_pc (regcache, copy);
|
regcache_write_pc (regcache, copy);
|
||||||
@ -1138,34 +1231,40 @@ static void
|
|||||||
displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
||||||
{
|
{
|
||||||
struct cleanup *old_cleanups;
|
struct cleanup *old_cleanups;
|
||||||
|
struct displaced_step_inferior_state *displaced
|
||||||
|
= get_displaced_stepping_state (ptid_get_pid (event_ptid));
|
||||||
|
|
||||||
/* Was this event for the pid we displaced? */
|
/* Was any thread of this process doing a displaced step? */
|
||||||
if (ptid_equal (displaced_step_ptid, null_ptid)
|
if (displaced == NULL)
|
||||||
|| ! ptid_equal (displaced_step_ptid, event_ptid))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
old_cleanups = make_cleanup (displaced_step_clear_cleanup, 0);
|
/* Was this event for the pid we displaced? */
|
||||||
|
if (ptid_equal (displaced->step_ptid, null_ptid)
|
||||||
|
|| ! ptid_equal (displaced->step_ptid, event_ptid))
|
||||||
|
return;
|
||||||
|
|
||||||
|
old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
|
||||||
|
|
||||||
/* Restore the contents of the copy area. */
|
/* Restore the contents of the copy area. */
|
||||||
{
|
{
|
||||||
ULONGEST len = gdbarch_max_insn_length (displaced_step_gdbarch);
|
ULONGEST len = gdbarch_max_insn_length (displaced->step_gdbarch);
|
||||||
write_memory_ptid (displaced_step_ptid, displaced_step_copy,
|
write_memory_ptid (displaced->step_ptid, displaced->step_copy,
|
||||||
displaced_step_saved_copy, len);
|
displaced->step_saved_copy, len);
|
||||||
if (debug_displaced)
|
if (debug_displaced)
|
||||||
fprintf_unfiltered (gdb_stdlog, "displaced: restored %s\n",
|
fprintf_unfiltered (gdb_stdlog, "displaced: restored %s\n",
|
||||||
paddress (displaced_step_gdbarch,
|
paddress (displaced->step_gdbarch,
|
||||||
displaced_step_copy));
|
displaced->step_copy));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did the instruction complete successfully? */
|
/* Did the instruction complete successfully? */
|
||||||
if (signal == TARGET_SIGNAL_TRAP)
|
if (signal == TARGET_SIGNAL_TRAP)
|
||||||
{
|
{
|
||||||
/* Fix up the resulting state. */
|
/* Fix up the resulting state. */
|
||||||
gdbarch_displaced_step_fixup (displaced_step_gdbarch,
|
gdbarch_displaced_step_fixup (displaced->step_gdbarch,
|
||||||
displaced_step_closure,
|
displaced->step_closure,
|
||||||
displaced_step_original,
|
displaced->step_original,
|
||||||
displaced_step_copy,
|
displaced->step_copy,
|
||||||
get_thread_regcache (displaced_step_ptid));
|
get_thread_regcache (displaced->step_ptid));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1173,17 +1272,18 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
|||||||
relocate the PC. */
|
relocate the PC. */
|
||||||
struct regcache *regcache = get_thread_regcache (event_ptid);
|
struct regcache *regcache = get_thread_regcache (event_ptid);
|
||||||
CORE_ADDR pc = regcache_read_pc (regcache);
|
CORE_ADDR pc = regcache_read_pc (regcache);
|
||||||
pc = displaced_step_original + (pc - displaced_step_copy);
|
pc = displaced->step_original + (pc - displaced->step_copy);
|
||||||
regcache_write_pc (regcache, pc);
|
regcache_write_pc (regcache, pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_cleanups (old_cleanups);
|
do_cleanups (old_cleanups);
|
||||||
|
|
||||||
displaced_step_ptid = null_ptid;
|
displaced->step_ptid = null_ptid;
|
||||||
|
|
||||||
/* Are there any pending displaced stepping requests? If so, run
|
/* Are there any pending displaced stepping requests? If so, run
|
||||||
one now. */
|
one now. Leave the state object around, since we're likely to
|
||||||
while (displaced_step_request_queue)
|
need it again soon. */
|
||||||
|
while (displaced->step_request_queue)
|
||||||
{
|
{
|
||||||
struct displaced_step_request *head;
|
struct displaced_step_request *head;
|
||||||
ptid_t ptid;
|
ptid_t ptid;
|
||||||
@ -1192,9 +1292,9 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
|||||||
CORE_ADDR actual_pc;
|
CORE_ADDR actual_pc;
|
||||||
struct address_space *aspace;
|
struct address_space *aspace;
|
||||||
|
|
||||||
head = displaced_step_request_queue;
|
head = displaced->step_request_queue;
|
||||||
ptid = head->ptid;
|
ptid = head->ptid;
|
||||||
displaced_step_request_queue = head->next;
|
displaced->step_request_queue = head->next;
|
||||||
xfree (head);
|
xfree (head);
|
||||||
|
|
||||||
context_switch (ptid);
|
context_switch (ptid);
|
||||||
@ -1225,8 +1325,8 @@ displaced_step_fixup (ptid_t event_ptid, enum target_signal signal)
|
|||||||
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
|
displaced_step_dump_bytes (gdb_stdlog, buf, sizeof (buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gdbarch_displaced_step_hw_singlestep
|
if (gdbarch_displaced_step_hw_singlestep (gdbarch,
|
||||||
(gdbarch, displaced_step_closure))
|
displaced->step_closure))
|
||||||
target_resume (ptid, 1, TARGET_SIGNAL_0);
|
target_resume (ptid, 1, TARGET_SIGNAL_0);
|
||||||
else
|
else
|
||||||
target_resume (ptid, 0, TARGET_SIGNAL_0);
|
target_resume (ptid, 0, TARGET_SIGNAL_0);
|
||||||
@ -1265,6 +1365,7 @@ static void
|
|||||||
infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
|
infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
|
||||||
{
|
{
|
||||||
struct displaced_step_request *it;
|
struct displaced_step_request *it;
|
||||||
|
struct displaced_step_inferior_state *displaced;
|
||||||
|
|
||||||
if (ptid_equal (inferior_ptid, old_ptid))
|
if (ptid_equal (inferior_ptid, old_ptid))
|
||||||
inferior_ptid = new_ptid;
|
inferior_ptid = new_ptid;
|
||||||
@ -1272,15 +1373,20 @@ infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
|
|||||||
if (ptid_equal (singlestep_ptid, old_ptid))
|
if (ptid_equal (singlestep_ptid, old_ptid))
|
||||||
singlestep_ptid = new_ptid;
|
singlestep_ptid = new_ptid;
|
||||||
|
|
||||||
if (ptid_equal (displaced_step_ptid, old_ptid))
|
|
||||||
displaced_step_ptid = new_ptid;
|
|
||||||
|
|
||||||
if (ptid_equal (deferred_step_ptid, old_ptid))
|
if (ptid_equal (deferred_step_ptid, old_ptid))
|
||||||
deferred_step_ptid = new_ptid;
|
deferred_step_ptid = new_ptid;
|
||||||
|
|
||||||
for (it = displaced_step_request_queue; it; it = it->next)
|
for (displaced = displaced_step_inferior_states;
|
||||||
if (ptid_equal (it->ptid, old_ptid))
|
displaced;
|
||||||
it->ptid = new_ptid;
|
displaced = displaced->next)
|
||||||
|
{
|
||||||
|
if (ptid_equal (displaced->step_ptid, old_ptid))
|
||||||
|
displaced->step_ptid = new_ptid;
|
||||||
|
|
||||||
|
for (it = displaced->step_request_queue; it; it = it->next)
|
||||||
|
if (ptid_equal (it->ptid, old_ptid))
|
||||||
|
it->ptid = new_ptid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1417,6 +1523,8 @@ a command like `return' or `jump' to continue execution."));
|
|||||||
|| (step && gdbarch_software_single_step_p (gdbarch)))
|
|| (step && gdbarch_software_single_step_p (gdbarch)))
|
||||||
&& sig == TARGET_SIGNAL_0)
|
&& sig == TARGET_SIGNAL_0)
|
||||||
{
|
{
|
||||||
|
struct displaced_step_inferior_state *displaced;
|
||||||
|
|
||||||
if (!displaced_step_prepare (inferior_ptid))
|
if (!displaced_step_prepare (inferior_ptid))
|
||||||
{
|
{
|
||||||
/* Got placed in displaced stepping queue. Will be resumed
|
/* Got placed in displaced stepping queue. Will be resumed
|
||||||
@ -1430,8 +1538,9 @@ a command like `return' or `jump' to continue execution."));
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
step = gdbarch_displaced_step_hw_singlestep
|
displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
|
||||||
(gdbarch, displaced_step_closure);
|
step = gdbarch_displaced_step_hw_singlestep (gdbarch,
|
||||||
|
displaced->step_closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we need to do it the hard way, w/temp breakpoints? */
|
/* Do we need to do it the hard way, w/temp breakpoints? */
|
||||||
@ -1953,8 +2062,6 @@ init_wait_for_inferior (void)
|
|||||||
previous_inferior_ptid = null_ptid;
|
previous_inferior_ptid = null_ptid;
|
||||||
init_infwait_state ();
|
init_infwait_state ();
|
||||||
|
|
||||||
displaced_step_clear ();
|
|
||||||
|
|
||||||
/* Discard any skipped inlined frames. */
|
/* Discard any skipped inlined frames. */
|
||||||
clear_inline_frame_state (minus_one_ptid);
|
clear_inline_frame_state (minus_one_ptid);
|
||||||
}
|
}
|
||||||
@ -2098,28 +2205,34 @@ infrun_thread_stop_requested_callback (struct thread_info *info, void *arg)
|
|||||||
static void
|
static void
|
||||||
infrun_thread_stop_requested (ptid_t ptid)
|
infrun_thread_stop_requested (ptid_t ptid)
|
||||||
{
|
{
|
||||||
struct displaced_step_request *it, *next, *prev = NULL;
|
struct displaced_step_inferior_state *displaced;
|
||||||
|
|
||||||
/* PTID was requested to stop. Remove it from the displaced
|
/* PTID was requested to stop. Remove it from the displaced
|
||||||
stepping queue, so we don't try to resume it automatically. */
|
stepping queue, so we don't try to resume it automatically. */
|
||||||
for (it = displaced_step_request_queue; it; it = next)
|
|
||||||
|
for (displaced = displaced_step_inferior_states;
|
||||||
|
displaced;
|
||||||
|
displaced = displaced->next)
|
||||||
{
|
{
|
||||||
next = it->next;
|
struct displaced_step_request *it, **prev_next_p;
|
||||||
|
|
||||||
if (ptid_equal (it->ptid, ptid)
|
it = displaced->step_request_queue;
|
||||||
|| ptid_equal (minus_one_ptid, ptid)
|
prev_next_p = &displaced->step_request_queue;
|
||||||
|| (ptid_is_pid (ptid)
|
while (it)
|
||||||
&& ptid_get_pid (ptid) == ptid_get_pid (it->ptid)))
|
|
||||||
{
|
{
|
||||||
if (displaced_step_request_queue == it)
|
if (ptid_match (it->ptid, ptid))
|
||||||
displaced_step_request_queue = it->next;
|
{
|
||||||
|
*prev_next_p = it->next;
|
||||||
|
it->next = NULL;
|
||||||
|
xfree (it);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
prev->next = it->next;
|
{
|
||||||
|
prev_next_p = &it->next;
|
||||||
|
}
|
||||||
|
|
||||||
xfree (it);
|
it = *prev_next_p;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
prev = it;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iterate_over_threads (infrun_thread_stop_requested_callback, &ptid);
|
iterate_over_threads (infrun_thread_stop_requested_callback, &ptid);
|
||||||
@ -6515,11 +6628,11 @@ Tells gdb whether to detach the child of a fork."),
|
|||||||
minus_one_ptid = ptid_build (-1, 0, 0);
|
minus_one_ptid = ptid_build (-1, 0, 0);
|
||||||
inferior_ptid = null_ptid;
|
inferior_ptid = null_ptid;
|
||||||
target_last_wait_ptid = minus_one_ptid;
|
target_last_wait_ptid = minus_one_ptid;
|
||||||
displaced_step_ptid = null_ptid;
|
|
||||||
|
|
||||||
observer_attach_thread_ptid_changed (infrun_thread_ptid_changed);
|
observer_attach_thread_ptid_changed (infrun_thread_ptid_changed);
|
||||||
observer_attach_thread_stop_requested (infrun_thread_stop_requested);
|
observer_attach_thread_stop_requested (infrun_thread_stop_requested);
|
||||||
observer_attach_thread_exit (infrun_thread_thread_exit);
|
observer_attach_thread_exit (infrun_thread_thread_exit);
|
||||||
|
observer_attach_inferior_exit (infrun_inferior_exit);
|
||||||
|
|
||||||
/* Explicitly create without lookup, since that tries to create a
|
/* Explicitly create without lookup, since that tries to create a
|
||||||
value with a void typed value, and when we get here, gdbarch
|
value with a void typed value, and when we get here, gdbarch
|
||||||
|
Reference in New Issue
Block a user