aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorJeff Law <law@redhat.com>1995-07-04 17:48:37 +0000
committerJeff Law <law@redhat.com>1995-07-04 17:48:37 +0000
commit88a294b1b7144dba23e36f9797772d9208995f8d (patch)
treeb5768971fd24f58ca2a1424550d925ec151bd5a9 /gdb
parent7158d2b1a33bdb747c3310f5fe5884dec8e31a72 (diff)
downloadgdb-88a294b1b7144dba23e36f9797772d9208995f8d.zip
gdb-88a294b1b7144dba23e36f9797772d9208995f8d.tar.gz
gdb-88a294b1b7144dba23e36f9797772d9208995f8d.tar.bz2
* 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.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/thread.c104
-rw-r--r--gdb/thread.h10
3 files changed, 125 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2ff3c3f..2e24ebc 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,16 @@
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
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 0f6e67c..2e89274 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 2ec94fc..1316b7a 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 */