Step disassembles the current instruction, if it is a CALL sets a
temp breakpoint inside the called function, after the prologue and
calls Continue.
Fixes#332
- Unlike FunctionEntryToFirstLine can skip the prologue on functions
that are defined on a single line, either because they weren't
formatted or because they were autogenerated
- Can skip the prologue on most functions when setting a breakpoint
with the filename:line syntax
Fixes#396
1. A running goroutine is by definition not parked waiting for a
chan recv
2. The FDE end address is intended to be exclusive, the code
interpreted as inclusive and sometimes ended up setting a breakpoint
on a function other than the current one.
Past the maximum recursion depth maps shouldn't be loaded at all,
adding map children and not loading them breaks assumptions in
the prettyprinter.
Fixes#406
If uninitialized memory is read loadArrayValues could try to call
cacheMemory with a negative size, which could cause a 'makeslice:
len out of range' panic.
Fixes#354 (partial)
Typedefs that resolve to slices are not recorded in DWARF as typedefs
but instead as structs in a way that there is no way to know they
are really slices using debug/dwarf.
Using golang.org/x/debug/dwarf instead this problem is solved and
as a bonus some types are printed with a nicer names: (struct string
→ string, struct []int → []int, etc)
Fixes#356 and #293
Instead of the `step` command single stepping every thread, instead only
step the "current" thread. This fixes a few issues surrounding single
stepping, and simplifies the logic. The original concerns around only
stepping a single thread (with regard to coordination) are invalid and
generally non-issues.
Location specifiers starting with '*' can be followed by any
expression supported by the evaluator.
The expression should evaluate to either an integer (which will be
interpreted as an address) or to a function pointer (which will be
dereferenced to get the function's entry point).
Prefetch the entire memory of structs and arrays and cache it instead
of issuing readMemory calls only when we get down to primitive types.
This reduces the number of system calls to ptrace that variables makes.
Improves performance in general, greatly improving it in some
particular cases (involving large structs).
Benchmarks without prefetching:
BenchmarkArray-4 10 132189944 ns/op 0.06 MB/s
BenchmarkArrayPointer-4 5 202538503 ns/op 0.04 MB/s
BenchmarkMap-4 500 3804336 ns/op 0.27 MB/s
BenchmarkGoroutinesInfo-4 10 126397104 ns/op
BenchmarkLocalVariables-4 500 2494846 ns/op
Benchmarks with prefetching:
BenchmarkArray-4 200 10719087 ns/op 0.76 MB/s
BenchmarkArrayPointer-4 100 11931326 ns/op 0.73 MB/s
BenchmarkMap-4 1000 1466479 ns/op 0.70 MB/s
BenchmarkGoroutinesInfo-4 10 103407004 ns/op
BenchmarkLocalVariables-4 1000 1530395 ns/op
Improvement factors:
BenchmarkArray 12.33x
BenchmarkArrayPointer 16.97x
BenchmarkMap 2.59x
BenchmarkGoroutinesInfo 1.22x
BenchmarkLocalVariables 1.63x
Sometimes after PtraceSingleStep the thread does not advance of a
single instruction but is, instead, blocked immediately by a SIGSTOP
Made singleStep repeat the process until a SIGTRAP is observed.
Unsure where the SIGSTOP comes from.
resume loops in continueOnce moved to a OS specific resume function,
this makes the problem easier to deal with and seems to be more
appropriate to a windows port given what transpired from discussion
of Pull Request #276
Next sets its temporary breakpoints with the condition that they
must only activate on the current goroutine, and then calls Continue
When Continue encounters a temporary breakpoint it clears all
the breakpoint.
User visible changes: breakpoints that get hit while executing Next
are not ignored.
This commit does not implement full conditional breakpoints
functionality, the only condition that can be set is on the
goroutine id.
Fixes race conditions in Next affecting TestNextConcurrent.
Breakpoints are skipped either because:
1. when multiple breakpoints are hit simultaneously only one is
processed
2. a thread hits a breakpoint while another thread is being
singlestepped over the breakpoint.
Additionally fixed a race condition between Continue and tracee
termination.
The concrete type of an interface only contains the abbreviated
package name, we must construct a map from package names to package
paths to be able to resolve the concrete type of an interface.
Supported operators:
- All (binary and unary) operators between basic types except <-,
++ and -- (includes & to take the address of an expression)
- Comparison operators between supported compound types
- Typecast of integer constants into pointer types
- struct members
- indexing of arrays, slices and strings
- slicing of arrays, slices and strings
- pointer dereferencing
- true, false and nil constants
Implements #116, #117 and #251
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)
Embedded structs are encoded in DWARF as fields with
package-qualified names. They define an anonymous field
on the struct with the non-qualified name, as well as
promoted fields for each field of the embedded struct so
long as these are not shadowed by fields of the containing
struct.
Fixes#220.
The 'source' command reads the file specified as argument and executes
it as a list of delve commands.
Additionally a flag '--init' can be passed to delve specifying a file
containing a list of commands to execute on startup.
Issue #96
g.SP refers to the frame the goroutine was in the last time it was
scheduled out. Instead of calling proc.(*Process).stacktrace directly
we should call proc.(*Process).GoroutineStacktrace that substitutes
fresh values retrieved from thread registers when necessary.
This bug leads to occasional problems with `next`.
Refactored variables.go to separate calculation of a variable's address from
reading its value. This change is useful to implement the 'set' command
as well as the evaluation of more complex expressions (in the future).
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
gopc is the instruction of the `go` command that spawned this goroutine.
What we really want (unless we can get the PC from the thread) is the
value of sched.pc which is the value of the PC at the time it was
parked.
`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.