aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-low.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2003-10-13 16:17:21 +0000
committerDaniel Jacobowitz <drow@false.org>2003-10-13 16:17:21 +0000
commit64386c31df79fa199254c3099a9ca70b9bd2839e (patch)
treeeeefbc5d37bb7e0217db49787e6988afe18cbb23 /gdb/gdbserver/linux-low.c
parent86d30acc85894c68f2b6f6875a5650bfabfc72f1 (diff)
downloadgdb-64386c31df79fa199254c3099a9ca70b9bd2839e.zip
gdb-64386c31df79fa199254c3099a9ca70b9bd2839e.tar.gz
gdb-64386c31df79fa199254c3099a9ca70b9bd2839e.tar.bz2
* linux-low.c (linux_resume): Take a struct thread_resume *
argument. (linux_wait): Update call. (resume_ptr): New static variable. (linux_continue_one_thread): Renamed from linux_continue_one_process. Use resume_ptr. (linux_resume): Use linux_continue_one_thread. * server.c (handle_v_cont, handle_v_requests): New functions. (myresume): New function. (main): Handle 'v' case. * target.h (struct thread_resume): New type. (struct target_ops): Change argument of "resume" to struct thread_resume *. (myresume): Delete macro.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r--gdb/gdbserver/linux-low.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 55c187c..68b3f65 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -52,7 +52,7 @@ int using_threads;
static void linux_resume_one_process (struct inferior_list_entry *entry,
int step, int signal);
-static void linux_resume (int step, int signal);
+static void linux_resume (struct thread_resume *resume_info);
static void stop_all_processes (void);
static int linux_wait_for_event (struct thread_info *child);
@@ -652,7 +652,12 @@ retry:
/* No stepping, no signal - unless one is pending already, of course. */
if (child == NULL)
- linux_resume (0, 0);
+ {
+ struct thread_resume resume_info;
+ resume_info.thread = -1;
+ resume_info.step = resume_info.sig = resume_info.leave_stopped = 0;
+ linux_resume (&resume_info);
+ }
}
enable_async_io ();
@@ -868,33 +873,48 @@ linux_resume_one_process (struct inferior_list_entry *entry,
perror_with_name ("ptrace");
}
-/* This function is called once per process other than the first
- one. The first process we are told the signal to continue
- with, and whether to step or continue; for all others, any
- existing signals will be marked in status_pending_p to be
- reported momentarily, and we preserve the stepping flag. */
+static struct thread_resume *resume_ptr;
+
+/* This function is called once per thread. We look up the thread
+ in RESUME_PTR, which will tell us whether to resume, step, or leave
+ the thread stopped; and what signal, if any, it should be sent.
+ For threads which we aren't explicitly told otherwise, we preserve
+ the stepping flag; this is used for stepping over gdbserver-placed
+ breakpoints. If the thread has a status pending, it may not actually
+ be resumed. */
static void
-linux_continue_one_process (struct inferior_list_entry *entry)
+linux_continue_one_thread (struct inferior_list_entry *entry)
{
struct process_info *process;
+ struct thread_info *thread;
+ int ndx, step;
+
+ thread = (struct thread_info *) entry;
+ process = get_thread_process (thread);
+
+ ndx = 0;
+ while (resume_ptr[ndx].thread != -1 && resume_ptr[ndx].thread != entry->id)
+ ndx++;
+
+ if (resume_ptr[ndx].leave_stopped)
+ return;
+
+ if (resume_ptr[ndx].thread == -1)
+ step = process->stepping || resume_ptr[ndx].step;
+ else
+ step = resume_ptr[ndx].step;
- process = (struct process_info *) entry;
- linux_resume_one_process (entry, process->stepping, 0);
+ linux_resume_one_process (&process->head, step, resume_ptr[ndx].sig);
}
static void
-linux_resume (int step, int signal)
+linux_resume (struct thread_resume *resume_info)
{
- struct process_info *process;
-
- process = get_thread_process (current_inferior);
-
- /* If the current process has a status pending, this signal will
- be enqueued and sent later. */
- linux_resume_one_process (&process->head, step, signal);
+ /* Yes, this is quadratic. If it ever becomes a problem then it's
+ fairly easy to fix. Yes, the use of a global here is rather ugly. */
- if (cont_thread == 0 || cont_thread == -1)
- for_each_inferior (&all_processes, linux_continue_one_process);
+ resume_ptr = resume_info;
+ for_each_inferior (&all_threads, linux_continue_one_thread);
}
#ifdef HAVE_LINUX_USRREGS