TODO:
- Fixing software breakpoints support,
Fixed!
267->596 of succeeded tests out of 1200+ - please scroll for details.
- Special Registers (Floating Point..) reading/writing,
- Unless it will be too closely related to develop threads - Hardware
watchpoints support in line with the Linux amd64 code,
As of today the number of passing tests has been degraded. This has been
caused due the fact that LLDB endeavors to set breakpoints in every
process (on the "_start" symbol) - this blocks tracing or simulating
tracing of any process.
This is necessary so that we can read the list shared libraries loaded
by the process and set any breakpoints in them. Note that currently
(at least on Linux) we are doing it actually too late -- at this point
the constructors in the shared libraries have already executed, so we
cannot set breakpoints or debug the initialization code. I haven't yet
investigated how to fix this.
I see.
It's interesting use-case; Right now I'm not sure how properly address it.
Thank you for your insight.
We will need to discuss this in detail. I am not sure removing the
NativeThreadNetBSD class completely will is a worthwhile goal, but we
can certainly work towards making it's parent class dumber, and remove
operations that don't make sense for all users. If e.g. your
watchpoints are per-process, then we can pipe watchpoint setting code
through NativeProcessProtocol, and NativeProcessNetBSD will implement
that directly, while the linux version will delegate to the thread.
However, even in your process model each thread has a separate set of
registers, so I think it makes sense to keep the register manipulation
code there.
I put all the threading potential challenges, each one will need to be
discussed. Refactoring is by definition cost and should be reduced to
minimum, while getting proper support on the platform. I think
Our watchpoints (debug registers) are per-thread (LWP) only.
- Support in the current thread function "0" (or "-1" according to the
GDB Remote protocol) to mark that the whole process was interrupted/no
primary thread (from a tracer point of view)
Teaching all parts of the debugger (server is not enough, I think you
would have to make a lot of client changes as well) about
whole-process events might be a big task.
I think long term this might be useful. I noted in the GDB Remote
specification that this protocol is embeddable into simulators and
low-level kernel APIs without regular threads, however it's not urgently
needed to get aboard for standard user-level debugging facilities; while
it will be useful in the general set of capabilities in future.
I wondering whether you
wouldn't make more progress if you just fudged this and always
attributed these events to the primary thread. I think we would be in
a better position to design this properly once most of the debugger
functionality was operational for you.
Agreed.
This is why the initial goal of mine is to get as far as possible
without touching the generic subsystems and get basic threading support.
What kind of per-process events
are we talking about here?
I'm mostly thinking about ResumeActions - to resume the whole process,
while being able single-stepping desired thread(s).
(We also offer PT_SYSCALL feature, but it's not needed right now in LLDB).
Is there anything more here than a signal
directed at the whole process?
single-stepping
resume thread
suspend thread
I'm evaluating FreeBSD-like API PT_SETSTEP/PT_CLEARSTEP for NetBSD. It
marks a thread for single-stepping. This code is needed to allow us to
combine PT_SYSCALL & PT_STEP and PT_STEP & emit signal.
I was thinking about ResumeActions marking which thread to
resume/suspend/singlestep, whether to emit a signal (one per global
PT_CONTINUE[/PT_SYSCALL]) and whether to resume the whole thread.
To some certain point it might be kludged with single-thread model for
basic debugging.
I imagined a possible flow of ResumeAction calls like:
[Generic/Native framework knows upfront the image of threads within
debuggee]
- Resume Thread 2 (PT_RESUME)
- Suspend Thread 3 (PT_SUSPEND)
- Set single-step Thread 2 (PT_SETSTEP)
- Set single-step Thread 4 (PT_SETSTEP)
- Clear single-step Thread 5 (PT_CLEARSTEP)
- Resume & emit signal SIGIO (PT_CONTINUE)
In other words: setting properties on threads and pushing the
PT_CONTINUE button at the end.
AFAICT, most of the stop reasons
(breakpoint, watchpoint, single step, ...) are still linked to a
specific thread even in your process model. I think you could get to a
point where lldb is very useful even without getting these events
"correct".
I was thinking for example about this change (it's not following the
real function name nor the prototype):
GetStoppedReason(Thread) -> GetStoppedReason(Process,Thread)
The Linux code would easily route it to desired thread and (Net)BSD
return immediately the requested data. The need to have these functions
in NativeThread (enforced by the framework) is the only purpose I keep
them there, while there is global stopped reason on NetBSD (per-process).
cheers,
pl
Thank you for your response.
Last but not the least after getting software breakpoints to work the
obligatory Test Summary diff between:
http://netbsd.org/~kamil/lldb/check-lldb-r296360-2017-02-28.txt
and
http://netbsd.org/~kamil/lldb/check-lldb-r296360-2017-03-16.txt
(pkgsrc-wip/lldb-netbsd git rev. 2c9c8e7b56d)