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.
additionally fixes a bug when Detach is called on an exiting/exited thread: dbp.CurrentThread could point to a thread that has already been removed from dbp.Threads by trapWait which will lead to a nil pointer dereference caused proc.Process.clearBreakpoint getting nil from dbp.Threads[tid]
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.