Age | Commit message (Collapse) | Author | Files | Lines |
|
Remove the 'struct' keyword in occurrences of 'struct thread_info'.
This is a code clean-up.
Tested by rebuilding.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
In the spirit of encapsulation, I'm looking to remove the need for
external code to access the "ptid -> thread" map of process_info, making
it an internal implementation detail. The only remaining use is in
function clear_inferiors, and it led me down this rabbit hole:
- clear_inferiors is really only used by the Windows port and doesn't
really make sense in the grand scheme of things, I think (when would
you want to remove all threads of all processes, without removing
those processes?)
- ok, so let's remove clear_inferiors and inline the code where it's
called, in function win32_clear_inferiors
- the Windows port does not support multi-process, so it's not really
necessary to loop over all processes like this:
for_each_process ([] (process_info *process)
{
process->thread_list ().clear ();
process->thread_map ().clear ();
});
We could just do:
current_process ()->thread_list ().clear ();
current_process ()->thread_map ().clear ();
(or pass down the process from the caller, but it's not important
right now)
- so, the code that we've inlined in win32_clear_inferiors does 3
things:
- clear the process' thread list and map (which deletes the
thread_info objects)
- clear the dll list, which just basically frees some objects
- switch to no current process / no current thread
- let's now look at where this win32_clear_inferiors function is used:
- in win32_process_target::kill, where the process is removed just
after
- in win32_process_target::detach, where the process is removed
just after
- in win32_process_target::wait, when handling a process exit.
After this returns, we could be in handle_target_event (if async)
or resume (if sync), both in `server.cc`. In both of these
cases, target_mourn_inferior gets called, we end up in
win32_process_target::mourn, which removes the process
- in all 3 cases above, we end up removing the process, which takes
care of the 3 actions listed above:
- the thread list and map get cleared when the process gets
destroyed
- same with the dll list
- remove_process switches to no current process / current thread
if the process being removed is the current one
- I conclude that it's probably unnecessary to do the cleanup in
win32_clear_inferiors, because it's going to get done right after
anyway.
Therefore, this patch does:
- remove clear_inferiors, remove the call in win32_clear_inferiors
- remove clear_dlls, which is now unused
- remove process_info::thread_map, which is now unused
- rename win32_clear_inferiors to win32_clear_process, which seems more
accurate
win32_clear_inferiors also does:
for_each_thread (delete_thread_info);
which also makes sure to delete all threads, but it also deletes the
Windows private data object (windows_thread_info), so I'll leave this
one there for now. But if we could make the thread private data
destruction automatic, on thread destruction, it could be removed, I
think.
There should be no user-visible change with this patch. Of course,
operations don't happen in the same order as before, so there might be
some important detail I'm missing. I'm only able to build-test this, if
someone could give it a test run on Windows, it would be appreciated.
Change-Id: I4a560affe763a2c965a97754cc02f3083dbe6fbf
|
|
Add an overload of `process_info::find_thread` that finds a thread by
ptid. Use it in two spots.
Change-Id: I2b7fb819bf4f83f7bd37f8641c38e878119b3814
|
|
Make the field private, change the free function to be a method.
Change-Id: I05010e7d1bd58ce3895802eb263c029528427758
Approved-By: Tom Tromey <tom@tromey.com>
|
|
thread_info
Make the field private, change the free functions to be methods.
Change-Id: Ifd8ed2775dddefc73a0e00126182e1db02688af4
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This function doesn't seem so useful. Use `thread_info::id` directly.
Change-Id: I158cd06a752badd30f68424e329aa42d275e43b7
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
Remove the `get_thread_process` function, use `thread_info::process`
instead.
In `server.cc`, use `current_process ()` instead of going through the
current thread.
Change-Id: Ifc61d65852e392d154b854a45d45df584ab3922e
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
Same idea as the previous patch, but for `remove_thread`.
Change-Id: I7e227655be5fcf29a3256e8389eb32051f27882d
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
Since thread_info objects are now basically children of process_info
objects, I think that makes sense.
Change-Id: I7f0a67b921b468e512851cb2f36015d1003412d7
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
In a few spots, we need to get to a process from a thread. Having a
backlink from thread to process is cheap and makes the operation
trivial, add it.
Change-Id: I8a94b2919494b1dcaf954de2246386794308aa82
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
Remove this overload, prefer to use `process_info::for_each_thread`. In
many instances, the `process_info` is already available, so this saves a
map lookup. In other instances, add the `process_info` lookup at the
call site.
In `linux-arm-low.cc` and `win32-i386-low.cc`, use `current_process ()`
instead of `current_thread->id.pid ()`. I presume that if
`current_process ()` and `current_thread` don't match, it's a bug
orthogonal to this change.
Change-Id: I751ed497cb1f313cf937b35125151bee9316fc51
Reviewed-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
|
|
Replace the servers global thread list with a process specific thread
list and a ptid -> thread map similar to 'inferior::ptid_thread_map' on
GDB side. Optimize the 'find_thread' and 'find_thread_ptid' functions
to use std::unordered_map::find for faster lookup of threads without
iterating over all processes and threads, if applicable. This becomes
important when debugging applications with a large thread count, e.g.,
in the context of GPU debugging.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
This patch replaces the 'std::list' type of 'all_processes' and
'all_threads' with the more lightweight 'owning_intrusive_list'
type.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
clangd reports gdbsupport/common-gdbthread.h as unused in gdbthread.h,
which seems right, so remove it. Add it to two files that need it, but
were relying on the now-removed include.
Change-Id: I12916a044d0b15f346c4ad0e6527ce99a6d460e4
|
|
Remove the templated versions of 'find_thread', 'for_each_thread' and
'find_thread_in_random' and replace the template function argument with
'gdb::function_view'. The usage of 'gdb::function_view' produces less
cryptic messages on errors and documents well the types of the
parameters taken by the callback and its return type.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
Now that defs.h, server.h and common-defs.h are included via the
`-include` option, it is no longer necessary for source files to include
them. Remove all the inclusions of these files I could find. Update
the generation scripts where relevant.
Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837
Approved-By: Pedro Alves <pedro@palves.net>
|
|
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
|
|
This commit is the result of running the gdb/copyright.py script,
which automated the update of the copyright year range for all
source files managed by the GDB project to be updated to include
year 2023.
|
|
The recent commit 421490af33bf ("gdbserver/linux: Access memory even
if threads are running") caused a regression in
gdb.threads/access-mem-running-thread-exit.exp with gdbserver, which I
somehow missed. Like so:
(gdb) print global_var
Cannot access memory at address 0x555555558010
(gdb) FAIL: gdb.threads/access-mem-running-thread-exit.exp: non-stop: access mem (print global_var after writing, inf=2, iter=1)
The problem starts with GDB telling GDBserver to select a thread, via
the Hg packet, which GDBserver complies with, then that thread exits,
and GDB, without knowing the thread is gone, tries to write to memory,
through the context of the previously selected Hg thread.
GDBserver's GDB-facing memory access routines, gdb_read_memory and
gdb_write_memory, call set_desired_thread to make GDBserver re-select
the thread that GDB has selected with the Hg packet. Since the thread
is gone, set_desired_thread returns false, and the memory access
fails.
Now, to access memory, it doesn't really matter which thread is
selected. All we should need is the target process. Even if the
thread that GDB previously selected is gone, and GDB does not yet know
about that exit, it shouldn't matter, GDBserver should still know
which process that thread belonged to.
Fix this by making GDBserver track the current process separately,
like GDB also does. Add a new set_desired_process routine that is
similar to set_desired_thread, but just sets the current process,
leaving the current thread as NULL. Use it in the GDB-facing memory
read and write routines, to avoid failing if the selected thread is
gone, but the process is still around.
Change-Id: I4ff97cb6f42558efbed224b30d5c71f6112d44cd
|
|
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.
For the avoidance of doubt, all changes in this commits were
performed by the script.
|
|
Replace the direct assignments to current_thread with
switch_to_thread. Use scoped_restore_current_thread when appropriate.
There is one instance remaining in linux-low.cc's wait_for_sigstop.
This will be handled in a separate patch.
Regression-tested on X86-64 Linux using the native-gdbserver and
native-extended-gdbserver board files.
|
|
Introduce a class for restoring the current thread and a function to
switch to the given thread. This is a preparation for a refactoring
that aims to remove direct assignments to 'current_thread'.
|
|
Add a constructor and a destructor. The constructor takes care of the
initialization that happened in add_thread, while the destructor takes
care of the freeing that happened in free_one_thread. This is needed to
make target_waitstatus non-POD, as thread_info contains a member of that
type.
Change-Id: I1db321b4de9dd233ede0d5c101950f1d6f1d13b7
|
|
Same idea as the previous patch, but for m_cwd.
To keep things consistent across the board, change get_inferior_cwd as
well, which is shared with GDBserver. So update the related GDBserver
code too.
Change-Id: Ia2c047fda738d45f3d18bc999eb67ceb8400ce4e
|
|
The declaration of set_inferior_cwd is currently shared between gdb and
gdbserver, in gdbsupport/common-inferior.h. It doesn't need to be, as
set_inferior_cwd is not called from common code. Only get_inferior_cwd
needs to.
The motivation for this is that a future patch will change the prototype
of set_inferior_cwd in gdb, and I don't want to change it for gdbserver
unnecessarily. I see this as a good cleanup in any case, to reduce to
just the essential what is shared between GDB and GDBserver.
Change-Id: I3127d27d078f0503ebf5ccc6fddf14f212426a73
|
|
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.
|
|
PR gdb/26742 points out some undefined behavior in gdbserver. The bug
is that remove_thread does:
free_one_thread (thread);
if (current_thread == thread)
current_thread = NULL;
However, the equality check is undefined, because "thread" has already
been freed.
This patch fixes the bug by moving the check earlier.
Tested on x86-64 Fedora 32.
2020-10-20 Tom Tromey <tromey@adacore.com>
PR gdb/26742:
* inferiors.cc (remove_thread): Clear current_thread before
freeing the thread.
|
|
On some systems, the gdb.multi/multi-target.exp testcase occasionally
fails like so:
Running src/gdb/testsuite/gdb.multi/multi-target.exp ...
FAIL: gdb.multi/multi-target.exp: info-inferiors: multi_process=on: inferior 1: info connections
FAIL: gdb.multi/multi-target.exp: info-inferiors: multi_process=on: inferior 1: info inferiors
FAIL: gdb.multi/multi-target.exp: info-inferiors: multi_process=on: inferior 2: info connections
FAIL: gdb.multi/multi-target.exp: info-inferiors: multi_process=on: inferior 2: info inferiors
FAIL: gdb.multi/multi-target.exp: info-inferiors: multi_process=on: inferior 3: inferior 3
... many more cascading fails.
The problem starts when the testcase runs an inferior against GDBserver:
(gdb) run
Starting program: build/gdb/testsuite/outputs/gdb.multi/multi-target/multi-target
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /lib64/ld-linux-x86-64.so.2 from remote target...
Reading /lib64/ld-2.31.so from remote target...
Reading /lib64/.debug/ld-2.31.so from remote target...
Reading /usr/lib/debug//lib64/ld-2.31.so from remote target...
Reading /usr/lib/debug/lib64//ld-2.31.so from remote target...
Reading target:/usr/lib/debug/lib64//ld-2.31.so from remote target...
Reading /lib/x86_64-linux-gnu/libpthread.so.0 from remote target...
Reading /lib/x86_64-linux-gnu/libc.so.6 from remote target...
Reading /lib/x86_64-linux-gnu/libc-2.31.so from remote target...
Reading /lib/x86_64-linux-gnu/.debug/libc-2.31.so from remote target...
Reading /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.31.so from remote target...
Reading /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.31.so from remote target...
Remote connection closed
...
Note the "Remote connection closed" message. That means GDBserver
exited abruptly.
I traced it down to the fact that GDB fetches the thread list from
GDBserver while the main thread of the process is still running. On
my main system where I wrote the testcase, I have not observed the
failure because it is slow enough that the thread stops before
GDBserver fetches the thread list in the problem scenario which I'll
describe below.
With some --remote-debug logging from GDBserver side, we see the last
packets before the connection closes:
...
getpkt ("vCont;c"); [no ack sent]
putpkt ("$OK#9a"); [noack mode]
getpkt ("Tp10f9a.10f9a"); [no ack sent]
putpkt ("$OK#9a"); [noack mode]
getpkt ("Hgp0.0"); [no ack sent]
putpkt ("$OK#9a"); [noack mode]
getpkt ("qXfer:threads:read::0,1000"); [no ack sent]
Note the vCont;c , which sets the program running, and then a
qXfer:threads:read packet at the end.
The problem happens when the thread list refresh (qXfer:threads:read)
is sent just while the main thread is running and it still hasn't
initialized its libpthread id internally. In that state, the main
thread's lwp will remain with the thread_known flag clear. See in
find_one_thread:
/* If the new thread ID is zero, a final thread ID will be available
later. Do not enable thread debugging yet. */
if (ti.ti_tid == 0)
return 0;
Now, back in server.cc, to handle the qXfer:threads:read, we reach
handle_qxfer_threads -> handle_qxfer_threads_proper, and the latter
then calls handle_qxfer_threads_worker for each known thread. In
handle_qxfer_threads_worker, we call target_thread_handle. This ends
up in thread_db_thread_handle, here:
if (!lwp->thread_known && !find_one_thread (thread->id))
return false;
Since the thread ID isn't known yet, we call find_one_thread. This
calls into libthread_db.so, which accesses memory. Because the
current thread is running, that fails and we throw an error, here:
/* Get information about this thread. */
err = thread_db->td_ta_map_lwp2thr_p (thread_db->thread_agent, lwpid, &th);
if (err != TD_OK)
error ("Cannot get thread handle for LWP %d: %s",
lwpid, thread_db_err_str (err));
The current design is that whenever GDB-facing packets/requests need
to accesses memory, server.cc is supposed to prepare the target for
the access. See gdb_read_memory / gdb_write_memory. This preparation
means pausing threads if in non-stop mode (someday we could lift this
requirement, but we will still need to pause to access registers or do
other related ptrace accesses like PTRACE_GET_THREAD_AREA). Note that
the multi-target.exp testcase forces "maint set target-non-stop on".
So the fix here is to prepare the target to access memory when
handling qXfer:threads:read too.
gdbserver/ChangeLog:
* inferiors.cc (switch_to_process): New, moved here from
thread-db.cc, and made extern.
* inferiors.h (switch_to_process): Declare.
* server.cc: Include "gdbsupport/scoped_restore.h".
(handle_qxfer_threads_proper): Now returns bool. Prepare to
access memory around target calls.
(handle_qxfer_threads): Handle errors.
* thread-db.cc (switch_to_process): Moved to inferiors.cc.
|
|
For the same reasons outlined in the previous patch, this patch renames
gdbserver source files to .cc.
I have moved the "-x c++" switch to only those rules that require it.
gdbserver/ChangeLog:
* Makefile.in: Rename source files from .c to .cc.
* %.c: Rename to %.cc.
* configure.ac: Rename server.c to server.cc.
* configure: Re-generate.
|