When creating a stack trace we should switch between the goroutine
stack and the system stack (where cgo code is executed) as appropriate
to reconstruct the logical stacktrace.
Goroutines that are currently executing on the system stack will have
the SystemStack flag set, frames of the goroutine stack will have a
negative FrameOffset (like always) and frames of the system stack will
have a positive FrameOffset (which is actually just the CFA value for
the frame).
Updates #935
StepBreakpoints are set on CALL instructions, when they are hit we
disassemble the current instruction, figure out the destination address
and set a breakpoint after the prologue of the called function.
In order to disassemble the current instruction we disassemble the area
of memory starting from PC and going to PC+15 (because 15 bytes is the
maximum length of one instruction on AMD64). This means that we won't
just disassemble one instruction but also a few instructions following
it ending with one truncated instruction.
This usually works fine but sometimes the disassembler will panic with
an array out of bounds error when trying to disassemble a truncated
instruction. To avoid this problem this commit changes the funciton
disassemble to take one extra parameter, singleInstr, when singleInstr
is set disassemble will quit after disassembling a single instruction.
Conditional breakpoints with unmet conditions would cause next and step
to skip the line.
This breakpoint changes the Kind field of proc.Breakpoint from a single
value to a bit field, each breakpoint object can represent
simultaneously a user breakpoint and one internal breakpoint (of which
we have several different kinds).
The breakpoint condition for internal breakpoints is stored in the new
internalCond field of proc.Breakpoint so that it will not conflict with
user specified conditions.
The breakpoint setting code is changed to allow overlapping one
internal breakpoint on a user breakpoint, or a user breakpoint on an
existing internal breakpoint. All other combinations are rejected. The
breakpoint clearing code is changed to clear the UserBreakpoint bit and
only remove the phisical breakpoint if no other bits are set in the
Kind field. ClearInternalBreakpoints does the same thing but clearing
all bits that aren't the UserBreakpoint bit.
Fixes#844
Move some duplicate code, related to breakpoints, that was in both
backends into a single place.
This is in preparation to solve issue #844 (conditional breakpoints
make step and next fail) which will make this common breakpoint code
more complicated.
Instead of only tracking a few cherrypicked registers in stack.go track
all DWARF registers.
This is needed for cgo code and for the locationlists emitted by go in
1.10:
* The debug_frame sections emitted by C compilers can not be used
without tracking all registers
* the loclists emitted by go1.10 need all registers of a frame to be
interpreted.
1. Use a slice instead of a map to access standard and extended opcodes
(reduces BenchmarkStateMachine from ~12ms/op to ~7ms/op)
2. Cache StateMachine values for the entry point of functions.
gosymtab and gopclntab only contain informations about go code, linked
C code isn't there, we should use debug_line instead to also cover C.
Updates #935
On macOS we can also stop when we receive a signal,
propagate this reason upwards to the client.
Also clear internal breakpoints after an unrecovered-panic since they
can not be reached anymore.
Fixes#872
Splits out type parsing and go-specific Type hierarchy from
x/debug/dwarf, replace x/debug/dwarf with debug/dwarf everywhere,
remove x/debug/dwarf from vendoring.
Instead of panicing for sending on a closed channel, detect that the
process has exited and return a proper error message.
This patch also cleans up some spots where the Pid is omitted from the
error.
Fixes#920
* proc: fix interaction of RequestManualStop and conditional breakpoints
A conditional breakpoint that is hit but has the condition evaluate to
false can block a RequestManualStop from working. If the conditional
breakpoint is set on an instruction that is executed very frequently by
multiple goroutines (or many conditional breakpoints are set) it could
prevent all calls to RequestManualStop from working.
This commit fixes the problem by changing proc.Continue to exit
unconditionally after a RequestManualStop is called.
* proc/gdbserial: fix ContinueOnce getting stuck on macOS
Fixes#902
* Fix various issues detected by megacheck
I've ran honnef.co/go/tools/cmd/megacheck and fixed a few of the
things that came up there.
* Cleanup using Gogland
When a Go program is externally linked, the external linker is
responsible for picking the TLS offset. It records its decision in the
runtime.tlsg symbol. Read the offset from that rather than guessing -16.
This implementation causes a regression: 1.4 and earlier will no longer
work.
Before this commit our temp breakpoints only checked that we would stay
on the same goroutine.
However this isn't enough for recursive functions we must check that we
stay on the same goroutine AND on the same stack frame (or, in the case
of the StepOut breakpoint, the previous stack frame).
This commit:
1. adds a new synthetic variable runtime.frameoff that returns the
offset of the current frame from the base of the call stack.
This is similar to runtime.curg
2. Changes the condition used for breakpoints on the lines of the
current function to check that runtime.frameoff hasn't changed.
3. Changes the condition used for breakpoints on the return address to
check that runtime.frameoff corresponds to the previous frame in the
stack.
4. All other temporary breakpoints (the step-into breakpoints and defer
breakpoints) remain unchanged.
Fixes#828
- moved target.Interface into proc as proc.Process
- rename proc.IThread to proc.Thread
- replaced interfaces DisassembleInfo, Continuable and
EvalScopeConvertible with Process.
- removed superfluous Gdbserver prefix from types in the gdbserial
backend.
- removed superfluous Core prefix from types in the core backend.
* proc: Refactor stackIterator to use memoryReadWriter and BinaryInfo
* proc: refactor EvalScope to use memoryReadWriter and BinaryInfo
* proc: refactor Disassemble to use memoryReadWriter and BinaryInfo
* proc: refactor BinaryInfo part of proc.Process to own type
The data structures and associated code used by proc.Process
to implement target.BinaryInfo will also be useful to support a
backend for examining core dumps, split this part of proc.Process
to a different type.
* proc: compile support for all executable formats unconditionally
So far we only compiled in support for loading the executable format
supported by the host operating system.
Once support for core files is introduced it is however useful to
support loading in all executable formats, there is no reason why it
shouldn't be possible to examine a linux coredump on windows, or
viceversa.
* proc: bugfix: do not resume threads on detach if killing
* Replace BinaryInfo interface with BinInfo() method returning proc.BinaryInfo
Detach did not work for processes we attach to via PID.
Linux: we were only detaching from the main thread, all threads are
detached independently
Windows: we must resume all threads before detaching.
macOS: still broken.
Updates #772
The rest of the code uses Detach to "close" a proc.Process, the tests
should do the same.
Any cleanup that proc.Process needs to do can then be put inside Detach
and the tests will run it.