* 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:
Jeff Law
1995-07-04 17:48:37 +00:00
parent 7158d2b1a3
commit 88a294b1b7
3 changed files with 125 additions and 0 deletions

View File

@ -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

View File

@ -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 ()
{ {

View File

@ -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 */