Instead of trying to be clever and make an 'educated guess' as to where
the flow of control may go next, simple do the more naive, yet correct,
approach of setting a breakpoint everywhere we can in the function and
seeing where we end up. On top of this we were already setting a
breakpoint at the return address and deferred functions, so that remains
the same.
This removes a lot of gnarly, hard to maintain code and takes all the
guesswork out of this command.
Fixes#281
Three locations are returned for goroutines: its current location,
its current location excluding unexported runtime functions and
the location of its go instruction.
The command 'goroutines' takes a new parameter to select which
location to print (defaulting to current location w/o runtime)
Instead of using PTRACE_DETACH to inject SIGINT into the tracee use
sys.Kill directly: PTRACE_DETACH is allowed to ignore its signal
argument if the tracee isn't in signal-delivery-stop status.
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.
Use proc.(*Process).FindGoroutine in proc.(*Process).SwitchGoroutine and
debugger.(*Debugger).Stacktrace. That method did not exist when those
were originally written.
Some of the goroutines stored in runtime.allg are in the dead state and
should not be displayed. The state is determined by the 'g.atomicstatus'
member.
The GoroutineInfo method can be slow if there are many goroutines. This
patch caches the results during a halt so they are not needlessly
recomputed.
Fixes#234
`next` would hang in highly parallel programs, causing test flickers and
unexpected behavior. This patch fixes it by examining all stopped
threads whenever Delve gets a notification, instead of just the thread
that caused the stop.
Support multiple file / directory tables for multiple compilation units.
- added a type DebugLines that can hold number of DebugLineInfo
- added a supporting attribute to DebugLineInfo called 'Lookup' which is to be
used to quickly lookup if file exists in FileNames slice
- added supporting methods to lookup and return corresponding DebugLineInfo
- changed the debug_line parsing behavior to read all the available tables and
push them to DebugLines
- since Process.lineInfo is now a slice, it was breaking AllPCsBetween as well
- updated that function's definition to accept a new filename parameter to be
able to extract related DebugLineInfo
- updated calls to AllPCsBetween
- fixed tests that were broken due to attribute type change in Process
- updated _fixtures/cgotest program to include stdio.h, so that it updates
.debug_line header
- added a test to check 'next' in a cgo binary
- OSX - 1.4 does not support cgo, handle that in new testcase
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.
Breakpoints, tracepoints, etc.. take a location spec as input. This
patch improves the expressiveness of that API. It allows:
* Breakpoint at line
* Breakpoint at function (handling package / receiver smoothing)
* Breakpoint at address
* Breakpoint at file:line
* Setting breakpoint based off regexp
the entry point of a function is the beginning of the prologue, which can be run multiple times for each invocation of a function if the stack needs to be expanded or the scheduler needs to be run.
Also, reorganizes some code.
Initially, the `proc` package emitted a lot of output. Now, that should
not be the case. The `proc` package should never print, for any reason.
That should be handled by clients.
We do not need to verify a current breakpoint, nor do a redundant check
on whether we have been asked to manually halt. Assume trapWait has done
its due diligence and stop the world once it returns.
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.
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]
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.