[PATCH 3/3] Per-inferior thread list, thread ranges/iterators, down with ALL_THREADS, etc.

Pedro Alves palves@redhat.com
Tue Oct 2 13:21:00 GMT 2018


On 10/01/2018 05:33 PM, John Baldwin wrote:
> On 10/1/18 3:32 AM, Pedro Alves wrote:
>> As preparation for multi-target, this patch makes each inferior have
>> its own thread list.
> 
> The BSD-related bits all look fine to me.  Do you have an existing branch
> for this on github that I can pull down to do some simple run-time testing?

I've pushed it now to users/palves/per-inf-thread-list on sourceware.org.

>> As for the init_thread_list calls sprinkled around, they're all
>> eliminated by this patch, and a new, central call is added to
>> inferior_appeared.  Note how also related to that, there's a call to
>> init_wait_for_inferior in remote.c that is eliminated.
>> init_wait_for_inferior is currently responsible for discarding skipped
>> inline frames, which had to be moved elsewhere.  Given that nowadays
>> we always have a thread even for single-threaded processes, the
>> natural place is to delete a frame's inline frame info when we delete
>> the thread.  I.e., from clear_thread_inferior_resources.
> 
> This brings up another question I have.  I have out-of-tree patches to add
> FreeBSD kernel-awareness (there's a mixture of authors and many of the
> kernel-specific bits are BSD licensed, so I can't upstream it as is, though
> at some point I might be able to upstream portions of it).  One of the changes
> in this branch is that I have a kernel target similar to bsd-kvm.c but with
> awareness of threads (so it creates a GDB thread for each kernel thread in
> the kernel image being examined).  Right now this uses init_thread_list
> (ugh).  What is the right thing to do?  Should it instead be creating a
> new inferior to represent the kernel and its set of threads?

What does it use init_thread_list for?  Maybe the call you're thinking
can just go away?

With multi-target, you should be able to create an inferior for
the kernel image, using that bsd-kvm-like target.  And simultaneously,
create other inferiors bound to the regular ptrace target.  And debug
all at the same time, if you find it useful.

But just switching inferior 1 from the ptrace target to the
kernel target I'd think would be done with "kill" to get rid
of the ptrace process, and then do "target kernel" (or whatever
it's spelled).  This is just like switching inferior 1 from
the native target to "target remote".  And that should continue
working unmodified.

> A somewhat related question is one thing I haven't yet solved which is
> how to "stack" kernel threads on top of a remote target that presents each
> CPU as a thread to GDB (e.g. the GDB stub in qemu, or the one I'm working on
> in FreeBSD's hypervisor).  I still don't quite know how to think about
> solving that, but that is a bit more of an ambitious change I suspect.

Yeah, better and more generic support for such a use case has been a part
of the community's wish list for a long while, for all sorts of similar
cases: kernel debugging, userspace threading libraries, Go goroutines etc.

Basically, you could think of it as the remote target presenting a
process_stratum layer with its own set of threads, and then the logical
kernel threads handled by a thread_stratum layer.  The current ugliness relates
to the fact that there's no clean way to get the process_stratum threads
out of view, at least not without the target layers coordinating in some
promiscuous fashion.  Another related problem is of course that both target
layers would be competing for the same single thread list.

The ravenscar target would be a current example of a thread_stratum target
that can sit on top of the remote target, today.  I don't know whether
that supports SMP at the "remote" level, it may be that it assumes
that there's only ever one "bare-metal" thread, which simplifies
things.

Then there's the Solaris port, which adds both LWPs and threads to the same
thread list, so if you do "info threads", given that Solaris is 1:1 nowadays,
you see each thread twice...  Made a bit more sense back when Solaris
was M:N.  dbx instead has separate "info threads" and "info lwp"-like commands:

 https://docs.oracle.com/cd/E37069_01/html/E37078/gevbl.html

I guess a better fit for GDB, if you want to support seamlessly flipping
between kernel-layer "views",  may be to have a knob to switch between
the "modes/views/target-layers" instead, and keep most of GDB thinking
in terms of "threads".

At the internals level, I am not exactly sure how it'd be implemented, but
I could imagine making the inferior have a thread list per target stratum,
per example.  There seems to be so many ramifications from the user
visible level level down to run control levels, that it's hard to
come up with a solid plan without spending some time prototyping
something, and inevitably throwing away a number of such prototypes
along the process...  That's what happened (or is happening) with
multi-target too.

Also, there's no current way to for example write the thread_stratum layer in
Python, you'd have to embed the kernel-specific knowledge inside GDB, in C++.
That's what the Linux kernel debugging patches were doing/proposing, I believe.
I don't have a problem with it, though some sort of Python layer would be
ideal, IMHO.

Thanks,
Pedro Alves



More information about the Gdb-patches mailing list