From: Jeff Law Date: Tue, 4 Jul 1995 17:48:37 +0000 (+0000) Subject: * infrun.c (wait_for_inferior): When switching from one thread to X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=88a294b1b7144dba23e36f9797772d9208995f8d;p=binutils-gdb.git * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2ff3c3f8aa5..2e24ebc9124 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ Tue Jul 4 10:30:22 1995 Jeffrey A. Law + * 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 wrong thread, make sure to write the fixed PC value into the thread that stopped. Restart all threads after single stepping over a diff --git a/gdb/thread.c b/gdb/thread.c index 0f6e67cb68c..2e892742f18 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -42,6 +42,17 @@ struct thread_info struct thread_info *next; int pid; /* Actual process id */ 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; @@ -83,6 +94,17 @@ add_thread (pid) tp->pid = pid; 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; thread_list = tp; } @@ -139,6 +161,88 @@ in_thread_list (pid) 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 prune_threads () { diff --git a/gdb/thread.h b/gdb/thread.h index 2ec94fc5c5e..1316b7ab549 100644 --- a/gdb/thread.h +++ b/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 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 */