Only use software breakpoints for now. The reasoning is because it
complicates the code without justification, and is only supported on
Linux. Eventually, once watchpoints are properly implemented we will
revive some of this code. Also, if it is ever necessary to actually set
a hw breakpoint we can revive that code as well.
All future versions of this code will include support for OSX before
being merged back in.
This patch aims to improve how Delve tracks the current goroutine,
especially in very highly parallel programs. The main spirit of this
patch is to ensure that even in situations where the goroutine we care
about is not executing (common for len(g) > len(m)) we still end up back
on that goroutine as a result of executing the 'next' command.
We accomplish this by tracking our original goroutine id, and any time a
breakpoint is hit or a threads stops, we examine the stopped threads and
see if any are executing the goroutine we care about. If not, we set
'next' breakpoint for them again and continue them. This is done so that
one of those threads can eventually pick up the goroutine we care about
and begin executing it again.
We're not dealing with a debugged process having its own controlling
terminal at this point, so no need to make the new process a session
leader. Simply making the process a group leader will suffice for our
purposes at the moment.
Instead of fighting against the normal flow, just signal a SIGTRAP and
let the existing flow handle it, as long as we set the halt flag
correctly the system should halt.
For hardware breakpoints we have to set them on every thread. It could
be the case that another thread is running. Stop it first, set the
breakpoint, then continue it.
Previously either the terminal client or the debugger service would
either lock main goroutine to a thread or provide a locked goroutine to
run _all_ DebuggedProcess functions in. This is unnecessary because only
ptrace functions need to be run from the same thread that originated the
PT_ATTACH request.
Here we use a specific thread-locked goroutine to service any ptrace
request. That goroutine is also responsible for the initial spawning /
attaching of the process, since it must be responsible for the PT_ATTACH
request.