diff options
author | Pedro Alves <pedro@palves.net> | 2022-03-29 12:57:17 +0100 |
---|---|---|
committer | Pedro Alves <pedro@palves.net> | 2022-04-14 20:21:11 +0100 |
commit | 330d63093c562a4b221835832c5e4f767dc623c3 (patch) | |
tree | 7cb6c98e4368442fe7a3e7a047c35150218b2dfa /gdbserver | |
parent | 1a7c41d5ece7d0d1aa77d8019ee46f03181854fa (diff) | |
download | gdb-330d63093c562a4b221835832c5e4f767dc623c3.zip gdb-330d63093c562a4b221835832c5e4f767dc623c3.tar.gz gdb-330d63093c562a4b221835832c5e4f767dc623c3.tar.bz2 |
gdbserver/qXfer::threads, prepare_to_access_memory=>target_pause_all
handle_qxfer_threads_proper needs to pause all threads even if the
target can read memory when threads are running, so use
target_pause_all instead, which is what the Linux implementation of
prepare_to_access_memory uses. (Only Linux implements this hook.)
A following patch will make the Linux backend be able to access memory
when threads are running, and thus will also make
prepare_to_access_memory do nothing, which would cause testsuite
regressions without this change.
Change-Id: I127fec7246b7c45b60dfa7341e781606bf54b5da
Diffstat (limited to 'gdbserver')
-rw-r--r-- | gdbserver/server.cc | 51 |
1 files changed, 16 insertions, 35 deletions
diff --git a/gdbserver/server.cc b/gdbserver/server.cc index 9f52d6e..e43a40a 100644 --- a/gdbserver/server.cc +++ b/gdbserver/server.cc @@ -1691,47 +1691,28 @@ handle_qxfer_threads_worker (thread_info *thread, struct buffer *buffer) static bool handle_qxfer_threads_proper (struct buffer *buffer) { - client_state &cs = get_client_state (); - - scoped_restore_current_thread restore_thread; - scoped_restore save_current_general_thread - = make_scoped_restore (&cs.general_thread); - buffer_grow_str (buffer, "<threads>\n"); - process_info *error_proc = find_process ([&] (process_info *process) - { - /* The target may need to access memory and registers (e.g. via - libthread_db) to fetch thread properties. Prepare for memory - access here, so that we potentially pause threads just once - for all accesses. Note that even if someday we stop needing - to pause threads to access memory, we will need to be able to - access registers, or other ptrace accesses like - PTRACE_GET_THREAD_AREA. */ - - /* Need to switch to each process in turn, because - prepare_to_access_memory prepares for an access in the - current process pointed to by general_thread. */ - switch_to_process (process); - cs.general_thread = current_thread->id; - - int res = prepare_to_access_memory (); - if (res == 0) - { - for_each_thread (process->pid, [&] (thread_info *thread) - { - handle_qxfer_threads_worker (thread, buffer); - }); + /* The target may need to access memory and registers (e.g. via + libthread_db) to fetch thread properties. Even if don't need to + stop threads to access memory, we still will need to be able to + access registers, and other ptrace accesses like + PTRACE_GET_THREAD_AREA that require a paused thread. Pause all + threads here, so that we pause each thread at most once for all + accesses. */ + if (non_stop) + target_pause_all (true); - done_accessing_memory (); - return false; - } - else - return true; + for_each_thread ([&] (thread_info *thread) + { + handle_qxfer_threads_worker (thread, buffer); }); + if (non_stop) + target_unpause_all (true); + buffer_grow_str0 (buffer, "</threads>\n"); - return error_proc == nullptr; + return true; } /* Handle qXfer:threads:read. */ |