aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdbserver')
-rw-r--r--gdbserver/gdbthread.h1
-rw-r--r--gdbserver/inferiors.cc26
-rw-r--r--gdbserver/server.cc4
-rw-r--r--gdbserver/target.cc44
-rw-r--r--gdbserver/target.h15
5 files changed, 79 insertions, 11 deletions
diff --git a/gdbserver/gdbthread.h b/gdbserver/gdbthread.h
index 10ae1cb..8b897e7 100644
--- a/gdbserver/gdbthread.h
+++ b/gdbserver/gdbthread.h
@@ -252,6 +252,7 @@ public:
private:
bool m_dont_restore = false;
+ process_info *m_process;
thread_info *m_thread;
};
diff --git a/gdbserver/inferiors.cc b/gdbserver/inferiors.cc
index 678d93c..3d0a8b0 100644
--- a/gdbserver/inferiors.cc
+++ b/gdbserver/inferiors.cc
@@ -26,6 +26,11 @@
std::list<process_info *> all_processes;
std::list<thread_info *> all_threads;
+/* The current process. */
+static process_info *current_process_;
+
+/* The current thread. This is either a thread of CURRENT_PROCESS, or
+ NULL. */
struct thread_info *current_thread;
/* The current working directory used to start the inferior.
@@ -130,6 +135,7 @@ clear_inferiors (void)
clear_dlls ();
switch_to_thread (nullptr);
+ current_process_ = nullptr;
}
struct process_info *
@@ -153,6 +159,8 @@ remove_process (struct process_info *process)
free_all_breakpoints (process);
gdb_assert (find_thread_process (process) == NULL);
all_processes.remove (process);
+ if (current_process () == process)
+ switch_to_process (nullptr);
delete process;
}
@@ -205,8 +213,7 @@ get_thread_process (const struct thread_info *thread)
struct process_info *
current_process (void)
{
- gdb_assert (current_thread != NULL);
- return get_thread_process (current_thread);
+ return current_process_;
}
/* See gdbsupport/common-gdbthread.h. */
@@ -223,6 +230,10 @@ switch_to_thread (process_stratum_target *ops, ptid_t ptid)
void
switch_to_thread (thread_info *thread)
{
+ if (thread != nullptr)
+ current_process_ = get_thread_process (thread);
+ else
+ current_process_ = nullptr;
current_thread = thread;
}
@@ -231,9 +242,8 @@ switch_to_thread (thread_info *thread)
void
switch_to_process (process_info *proc)
{
- int pid = pid_of (proc);
-
- switch_to_thread (find_any_thread_of_pid (pid));
+ current_process_ = proc;
+ current_thread = nullptr;
}
/* See gdbsupport/common-inferior.h. */
@@ -254,6 +264,7 @@ set_inferior_cwd (std::string cwd)
scoped_restore_current_thread::scoped_restore_current_thread ()
{
+ m_process = current_process_;
m_thread = current_thread;
}
@@ -262,5 +273,8 @@ scoped_restore_current_thread::~scoped_restore_current_thread ()
if (m_dont_restore)
return;
- switch_to_thread (m_thread);
+ if (m_thread != nullptr)
+ switch_to_thread (m_thread);
+ else
+ switch_to_process (m_process);
}
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index 33c4271..f9c02a9 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -1067,7 +1067,7 @@ gdb_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
/* (assume no half-trace half-real blocks for now) */
}
- if (set_desired_thread ())
+ if (set_desired_process ())
res = read_inferior_memory (memaddr, myaddr, len);
else
res = 1;
@@ -1088,7 +1088,7 @@ gdb_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
int ret;
- if (set_desired_thread ())
+ if (set_desired_process ())
ret = target_write_memory (memaddr, myaddr, len);
else
ret = EIO;
diff --git a/gdbserver/target.cc b/gdbserver/target.cc
index 8832423..adcfe6e 100644
--- a/gdbserver/target.cc
+++ b/gdbserver/target.cc
@@ -29,16 +29,56 @@
process_stratum_target *the_target;
-int
+/* See target.h. */
+
+bool
set_desired_thread ()
{
client_state &cs = get_client_state ();
thread_info *found = find_thread_ptid (cs.general_thread);
- switch_to_thread (found);
+ if (found == nullptr)
+ {
+ process_info *proc = find_process_pid (cs.general_thread.pid ());
+ if (proc == nullptr)
+ {
+ threads_debug_printf
+ ("did not find thread nor process for general_thread %s",
+ cs.general_thread.to_string ().c_str ());
+ }
+ else
+ {
+ threads_debug_printf
+ ("did not find thread for general_thread %s, but found process",
+ cs.general_thread.to_string ().c_str ());
+ }
+ switch_to_process (proc);
+ }
+ else
+ switch_to_thread (found);
+
return (current_thread != NULL);
}
+/* See target.h. */
+
+bool
+set_desired_process ()
+{
+ client_state &cs = get_client_state ();
+
+ process_info *proc = find_process_pid (cs.general_thread.pid ());
+ if (proc == nullptr)
+ {
+ threads_debug_printf
+ ("did not find process for general_thread %s",
+ cs.general_thread.to_string ().c_str ());
+ }
+ switch_to_process (proc);
+
+ return proc != nullptr;
+}
+
int
read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
diff --git a/gdbserver/target.h b/gdbserver/target.h
index f3172e2..6c536a3 100644
--- a/gdbserver/target.h
+++ b/gdbserver/target.h
@@ -699,7 +699,20 @@ target_thread_pending_child (thread_info *thread)
int read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len);
-int set_desired_thread ();
+/* Set GDBserver's current thread to the thread the client requested
+ via Hg. Also switches the current process to the requested
+ process. If the requested thread is not found in the thread list,
+ then the current thread is set to NULL. Likewise, if the requested
+ process is not found in the process list, then the current process
+ is set to NULL. Returns true if the requested thread was found,
+ false otherwise. */
+
+bool set_desired_thread ();
+
+/* Set GDBserver's current process to the process the client requested
+ via Hg. The current thread is set to NULL. */
+
+bool set_desired_process ();
std::string target_pid_to_str (ptid_t);