mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-18 00:32:30 +08:00
* infrun.c (wait_for_inferior): When switching from one thread to
another, save infrun's state for the old thread and load infrun's previous state for the new thread. * thread.c (struct thread_info): Add new fields for thread specific state saved/restored in infrun.c. (add_thread): Initialize new fields. (load_infrun_state): New function. (save_infrun_state): New function. * thread.h (load_infrun_state): Provide external decl. (save_infrun_state): Likewise. More single-stepping patches for lynx-6100.
This commit is contained in:
@ -1,5 +1,16 @@
|
|||||||
Tue Jul 4 10:30:22 1995 Jeffrey A. Law <law@rtl.cygnus.com>
|
Tue Jul 4 10:30:22 1995 Jeffrey A. Law <law@rtl.cygnus.com>
|
||||||
|
|
||||||
|
* infrun.c (wait_for_inferior): When switching from one thread to
|
||||||
|
another, save infrun's state for the old thread and load infrun's
|
||||||
|
previous state for the new thread.
|
||||||
|
* thread.c (struct thread_info): Add new fields for thread specific
|
||||||
|
state saved/restored in infrun.c.
|
||||||
|
(add_thread): Initialize new fields.
|
||||||
|
(load_infrun_state): New function.
|
||||||
|
(save_infrun_state): New function.
|
||||||
|
* thread.h (load_infrun_state): Provide external decl.
|
||||||
|
(save_infrun_state): Likewise.
|
||||||
|
|
||||||
* infrun.c (wait_for_inferior): When we hit a breakpoint for the
|
* infrun.c (wait_for_inferior): When we hit a breakpoint for the
|
||||||
wrong thread, make sure to write the fixed PC value into the thread
|
wrong thread, make sure to write the fixed PC value into the thread
|
||||||
that stopped. Restart all threads after single stepping over a
|
that stopped. Restart all threads after single stepping over a
|
||||||
|
104
gdb/thread.c
104
gdb/thread.c
@ -42,6 +42,17 @@ struct thread_info
|
|||||||
struct thread_info *next;
|
struct thread_info *next;
|
||||||
int pid; /* Actual process id */
|
int pid; /* Actual process id */
|
||||||
int num; /* Convenient handle */
|
int num; /* Convenient handle */
|
||||||
|
CORE_ADDR prev_pc; /* State from wait_for_inferior */
|
||||||
|
CORE_ADDR prev_func_start;
|
||||||
|
char *prev_func_name;
|
||||||
|
struct breakpoint *step_resume_breakpoint;
|
||||||
|
struct breakpoint *through_sigtramp_breakpoint;
|
||||||
|
CORE_ADDR step_range_start;
|
||||||
|
CORE_ADDR step_range_end;
|
||||||
|
CORE_ADDR step_frame_address;
|
||||||
|
int trap_expected;
|
||||||
|
int handling_longjmp;
|
||||||
|
int another_trap;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct thread_info *thread_list = NULL;
|
static struct thread_info *thread_list = NULL;
|
||||||
@ -83,6 +94,17 @@ add_thread (pid)
|
|||||||
|
|
||||||
tp->pid = pid;
|
tp->pid = pid;
|
||||||
tp->num = ++highest_thread_num;
|
tp->num = ++highest_thread_num;
|
||||||
|
tp->prev_pc = 0;
|
||||||
|
tp->prev_func_start = 0;
|
||||||
|
tp->prev_func_name = NULL;
|
||||||
|
tp->step_range_start = 0;
|
||||||
|
tp->step_range_end = 0;
|
||||||
|
tp->step_frame_address =0;
|
||||||
|
tp->step_resume_breakpoint = 0;
|
||||||
|
tp->through_sigtramp_breakpoint = 0;
|
||||||
|
tp->handling_longjmp = 0;
|
||||||
|
tp->trap_expected = 0;
|
||||||
|
tp->another_trap = 0;
|
||||||
tp->next = thread_list;
|
tp->next = thread_list;
|
||||||
thread_list = tp;
|
thread_list = tp;
|
||||||
}
|
}
|
||||||
@ -139,6 +161,88 @@ in_thread_list (pid)
|
|||||||
return 0; /* Never heard of 'im */
|
return 0; /* Never heard of 'im */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Load infrun state for the thread PID. */
|
||||||
|
|
||||||
|
void load_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
|
||||||
|
trap_expected, step_resume_breakpoint,
|
||||||
|
through_sigtramp_breakpoint, step_range_start,
|
||||||
|
step_range_end, step_frame_address,
|
||||||
|
handling_longjmp, another_trap)
|
||||||
|
int pid;
|
||||||
|
CORE_ADDR *prev_pc;
|
||||||
|
CORE_ADDR *prev_func_start;
|
||||||
|
char **prev_func_name;
|
||||||
|
int *trap_expected;
|
||||||
|
struct breakpoint **step_resume_breakpoint;
|
||||||
|
struct breakpoint **through_sigtramp_breakpoint;
|
||||||
|
CORE_ADDR *step_range_start;
|
||||||
|
CORE_ADDR *step_range_end;
|
||||||
|
CORE_ADDR *step_frame_address;
|
||||||
|
int *handling_longjmp;
|
||||||
|
int *another_trap;
|
||||||
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
/* If we can't find the thread, then we're debugging a single threaded
|
||||||
|
process. No need to do anything in that case. */
|
||||||
|
tp = find_thread_id (pid_to_thread_id (pid));
|
||||||
|
if (tp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*prev_pc = tp->prev_pc;
|
||||||
|
*prev_func_start = tp->prev_func_start;
|
||||||
|
*prev_func_name = tp->prev_func_name;
|
||||||
|
*step_resume_breakpoint = tp->step_resume_breakpoint;
|
||||||
|
*step_range_start = tp->step_range_start;
|
||||||
|
*step_range_end = tp->step_range_end;
|
||||||
|
*step_frame_address = tp->step_frame_address;
|
||||||
|
*through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
|
||||||
|
*handling_longjmp = tp->handling_longjmp;
|
||||||
|
*trap_expected = tp->trap_expected;
|
||||||
|
*another_trap = tp->another_trap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save infrun state for the thread PID. */
|
||||||
|
|
||||||
|
void save_infrun_state (pid, prev_pc, prev_func_start, prev_func_name,
|
||||||
|
trap_expected, step_resume_breakpoint,
|
||||||
|
through_sigtramp_breakpoint, step_range_start,
|
||||||
|
step_range_end, step_frame_address,
|
||||||
|
handling_longjmp, another_trap)
|
||||||
|
int pid;
|
||||||
|
CORE_ADDR prev_pc;
|
||||||
|
CORE_ADDR prev_func_start;
|
||||||
|
char *prev_func_name;
|
||||||
|
int trap_expected;
|
||||||
|
struct breakpoint *step_resume_breakpoint;
|
||||||
|
struct breakpoint *through_sigtramp_breakpoint;
|
||||||
|
CORE_ADDR step_range_start;
|
||||||
|
CORE_ADDR step_range_end;
|
||||||
|
CORE_ADDR step_frame_address;
|
||||||
|
int handling_longjmp;
|
||||||
|
int another_trap;
|
||||||
|
{
|
||||||
|
struct thread_info *tp;
|
||||||
|
|
||||||
|
/* If we can't find the thread, then we're debugging a single-threaded
|
||||||
|
process. Nothing to do in that case. */
|
||||||
|
tp = find_thread_id (pid_to_thread_id (pid));
|
||||||
|
if (tp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
tp->prev_pc = prev_pc;
|
||||||
|
tp->prev_func_start = prev_func_start;
|
||||||
|
tp->prev_func_name = prev_func_name;
|
||||||
|
tp->step_resume_breakpoint = step_resume_breakpoint;
|
||||||
|
tp->step_range_start = step_range_start;
|
||||||
|
tp->step_range_end = step_range_end;
|
||||||
|
tp->step_frame_address = step_frame_address;
|
||||||
|
tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;
|
||||||
|
tp->handling_longjmp = handling_longjmp;
|
||||||
|
tp->trap_expected = trap_expected;
|
||||||
|
tp->another_trap = another_trap;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prune_threads ()
|
prune_threads ()
|
||||||
{
|
{
|
||||||
|
10
gdb/thread.h
10
gdb/thread.h
@ -33,4 +33,14 @@ extern int pid_to_thread_id PARAMS ((int pid));
|
|||||||
|
|
||||||
extern int valid_thread_id PARAMS ((int thread));
|
extern int valid_thread_id PARAMS ((int thread));
|
||||||
|
|
||||||
|
extern void load_infrun_state PARAMS ((int, CORE_ADDR *, CORE_ADDR *, char **,
|
||||||
|
int *, struct breakpoint **,
|
||||||
|
struct breakpoint **, CORE_ADDR *,
|
||||||
|
CORE_ADDR *, CORE_ADDR *, int *, int *));
|
||||||
|
|
||||||
|
extern void save_infrun_state PARAMS ((int, CORE_ADDR, CORE_ADDR, char *,
|
||||||
|
int, struct breakpoint *,
|
||||||
|
struct breakpoint *, CORE_ADDR,
|
||||||
|
CORE_ADDR, CORE_ADDR, int, int));
|
||||||
|
|
||||||
#endif /* THREAD_H */
|
#endif /* THREAD_H */
|
||||||
|
Reference in New Issue
Block a user