* proc: support new Go 1.17 panic/defer mechanism
Go 1.17 will create wrappers for deferred calls that take arguments.
Change defer reading code so that wrappers are automatically unwrapped.
Also the deferred function is called directly by runtime.gopanic, without going through runtime.callN which means that sometimes when a panic happens the stack is either:
0. deferred function call
1. deferred call wrapper
2. runtime.gopanic
or:
0. deferred function call
1. runtime.gopanic
instead of always being:
0. deferred function call
1. runtime.callN
2. runtime.gopanic
the isPanicCall check is changed accordingly.
* test: miscellaneous minor test fixes for Go 1.17
* proc: resolve inlined calls when stepping out of runtime.breakpoint
Calls to runtime.Breakpoint are inlined in Go 1.17 when inlining is
enabled, resolve inlined calls in stepInstructionOut.
* proc: add support for debugCallV2 with regabi
This change adds support for the new debug call protocol which had to
change for the new register ABI introduced in Go 1.17.
Summary of changes:
- Abstracts over the debug call version depending on the Go version
found in the binary.
- Uses R12 instead of RAX as the debug protocol register when the binary
is from Go 1.17 or later.
- Creates a variable directly from the DWARF entry for function
arguments to support passing arguments however the ABI expects.
- Computes a very conservative stack frame size for the call when
injecting a call into a Go process whose version is >=1.17.
Co-authored-by: Michael Anthony Knyszek <mknyszek@google.com>
Co-authored-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
* TeamCity: enable tests on go-tip
* goversion: version compatibility bump
* TeamCity: fix go-tip builds on macOS/arm64
Co-authored-by: Michael Anthony Knyszek <mknyszek@google.com>
We told clients that further loading of variables can be done by
specifying a type cast using the address of a variable that we
returned.
This does not work for registerized variables (or, in general,
variables that have a complex location expression) because we don't
give them unique addresses and we throw away the compositeMemory object
we made to read them.
This commit changes proc so that:
1. variables with location expression divided in pieces do get a unique
memory address
2. the compositeMemory object is saved somewhere
3. when an integer is cast back into a pointer type we look through our
saved compositeMemory objects to see if there is one that covers the
specified address and use it.
The unique memory addresses we generate have the MSB set to 1, as
specified by the Intel 86x64 manual addresses in this form are reserved
for kernel memory (which we can not read anyway) so we are guaranteed
to never generate a fake memory address that overlaps a real memory
address of the application.
The unfortunate side effect of this is that it will break clients that
do not deserialize the address to a 64bit integer. This practice is
contrary to how we defined our types and contrary to the specification
of the JSON format, as of json.org, however it is also fairly common,
due to javascript itself having only 53bit integers.
We could come up with a new mechanism but then even more old clients
would have to be changed.
Adds filtering and grouping to the goroutines command.
The current implementation of the goroutines command is modeled after
the threads command of gdb. It works well for programs that have up to
a couple dozen goroutines but becomes unusable quickly after that.
This commit adds the ability to filter and group goroutines by several
different properties, allowing a better debugging experience on
programs that have hundreds or thousands of goroutines.
We can get the throw reason by looking at the argument "s" in runtime.throw. This is not currently working in Go 1.16 or Go 1.17 (see golang/go#46425), but does work in Go 1.15 and Go 1.14
If the base address isn't set then indexing and slicing will not work.
Large floating point registers already had the base set but small
general purpose registers did not.
Adds DWARF register number and support for AVX-512 registers.
Changes proc/gdbserial so that the 'g' and 'G' commands are never used
with debugserver since they seem to corrupt the thread state when used
on AVX-512 capable hardware.
Also changes TestClientServer_FpRegisters to be simpler and more
resilient to changes to the Go runtime.
Fixes#2479
* dap: use larger variable load limits in 'repl', 'variables' context
When evaluate requests are triggered in the context of 'repl'
(DEBUG CONSOLE in VSCode) or 'variables' (copy values from VARIABLES
section in VSCode), they are the result of human action and have
more rooms to display. So it is not too bad to apply longer limits.
Variable auto-loading for strings or arrays is nice but currently
it's unclear to me how this should be integrated in the DEBUG
CONSOLE or with the Copy Value feature. Until we have better ideas
and tools, let's go with these larger limits.
Unfortunately, the "Copy Value" from WATCH section triggers evaluate
requests with "watch" context and we don't want to load large data
automatically for "watch". So, users who want to query a large value
should first copy the expression to DEBUG CONSOLE and evaluate it.
Not ideal but not the end of the world either.
Updates golang/vscode-go#1318
* dap: apply large limit only to the string type result
* dap: move string reload logic to convertVariable* where other reload logic is
Currently we are thinking string reload for evaluation as a temporary
workaround until we figure out an intutitive way to present long strings.
So, I hope moving this logic near other reload logic may be better.
And, use the address based expression when reloading - when handling the
function return values, we may not have an expression to use.
* dap: make deep source check happy
* dap: move string reevaluation logic back to onEvaluateRequest
Reloading string variables is tricky if they are in registers.
We don't attempt to reload them but for clarity, move this up
to the onEvaluateRequest handler.
For function call, use a generous limit for string load
since the results are volatile.
* dap: check variable isn't affected by evaluate in other context
* dap: handle SetVariable requests
The handler invokes debugger.SetVariableInScope, except for
string type variables. For which, we rely on the `call` command.
Moved the call expression handling logic to the new `doCall`
function, so it can be reused by the SetVariable requenst
handler.
With this PR, every successful SetVariable request triggers
a StoppedEvent - that's a hack to reset the variablesHandle
map internally and notify the client of this change. It will
be nice if we can just update cached data corresponding to
the updated variable. But I cannot find an easy and safe way
to achieve this yet.
Also fixed a small bug in the call expression evaluation -
Previously, dlv dap returned an error "Unable to evaluate
expression: call stopped" if the call expression is for
variable assignment. (e.g. "call animal = "rabbit").
* dap: address comments from aarzilli
resetHandlesForStop & sendStoppedEvent unconditionally after
call command is left as a TODO - This is an existing code path
(just refactored) and an preexisting bug. Fixing it here
requires updates in TestEvaluateCallRequest and I prefer
addressing it in a separate cl.
Disabled call injection testing on arm64. Separated TestSetVariable
into two, one that doesn't involve call injection and another that
may involve call injection.
Fixed variableByName by removing unnecessary recursion.
* dap: address polina's comments
- removed the hard reset for every variable set
- added tests for various variable types
- added tests that involves interrupted function calls. (breakpoint/panic)
And,
- changed to utilize EvalVariableInScope to access the variable instead
of searching the children by name.
- changed to utilize evaluate requests when verifying whether the variable
is changed as expected in testing. Since now we avoid resetting the variable
handles after variable reset, either we need to trigger scope changes
explicitly, or stop depending on the variables request.
* dap: address comments
- Discuss the problem around the current doCall implementation
and the implication.
- Refine the description on how VS Code handles after setVariable
and evaluate request (there could be followup scopes/evaluate requests).
- Use the explicit line numbers for breakpoints in the SetVariable tests.
- Do not use errors.Is - we could've used golang.org/x/xerrors polyfill
but that's an additional dependency, and we will remove this check once
tests that depend on old behavior are fixed.
* dap: remove errTerminated and adjust the test
* dap: evaluate in the outer frame, instead of advancing to the next bp
Adds the low-level support for watchpoints (aka data breakpoints) to
the native linux/amd64 backend.
Does not add user interface or functioning support for watchpoints
on stack variables.
Updates #279
* Truncate long compound map keys and use address suffix only for those
* Remove test typo that causes failures
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* Adds toggle command
Also adds two rpc2 tests for testing the new functionality
* Removes Debuggers' ToggleBreakpoint method
rpc2's ToggleBreakpoint now calls AmendBreakpoint
Refactors the ClearBreakpoint to avoid a lock.
* service/dap: support auto-loading of unloaded interfaces
* Make DeepSource happy
* Don't set reference if data failed to auto-load
* Use frame-less expressions
* Refine interface recursion capping test case
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* DAP test for github.com/golang/vscode-go/issues/1056
* DAP test for github.com/golang/vscode-go/issues/884
* DAP test for github.com/golang/vscode-go/issues/851
* DAP test for github.com/golang/vscode-go/issues/1053
* DAP test for github.com/golang/vscode-go/issues/1054
* Make DeepSource happy
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
Both structMember and findMethod implemented a depth-first search in
embedded fields but the Go specification requires a breadth-first
search. They also allowed promotion of fields in the concrete type of
embedded interfaces even though this is not allowed by Go.
Furthermore they both lacked protection from infinite recursion
when a type embeds itself and the user requests a non-existent field.
Fixes#2316
Add a helper method for collecting line table file references that
does the correct thing for DWARF 5 vs DWARF 4 (in the latter case you
have an implicit 0 entry which is the comp dir, whereas in the former
case you do not). This is to avoid out-of-bounds errors when examining
the file table section of a DWARF 5 compilation unit's line table.
Included is a new linux/amd-only test that includes a precompiled C
object file with a DWARF-5 section that triggers the bug in question.
Fixes#2319
evalFunctionCall needs to remove the breakpoint from the current thread
after starting the function call injection, otherwise Continue will
think that the thread is stopped at a breakpoint and return to the user
instead of continuing the call injection.
1. Forward stdin/stdout/stderr to the target process when in foreground
mode instead of always forwarding the current tty (issue #1964)
2. When redirecting a file descriptor make sure to also specify
something for all three otherwise debugserver will misbehave (either
exit on launch or run but giving the target process a closed file
descriptor).
Fixes#1964
The test needs to set a breakpoint on main.CallFn after the prologue,
on linux/386 this function does not have any instruction after the
prologue on the function header line because it doesn't need to
allocate space for local variables. Change the fixture so that this
isn't a problem.
This bug results on the test failing a small percentage of the time.
Co-authored-by: a <a@kra>
Adds features to support default file descriptor redirects for the
target process:
1. A new command line flag '--redirect' and '-r' are added to specify
file redirects for the target process
2. New syntax is added to the 'restart' command to specify file
redirects.
3. Interactive instances will check if stdin/stdout and stderr are
terminals and print a helpful error message if they aren't.
An internal breakpoint condition shouldn't ever error:
* use a ThreadContext to evaluate conditions if a goroutine isn't
available
* evaluate runtime.curg to a fake g variable containing only
`goid == 0` when there is no current goroutine
Fixes#2113
Recent changes to the way registers are handled broke reporting of AVX
registers (i.e. YMMx). This change restores the functionality by:
- concatenating the higher half of the YMMx registers to their
corresponding XMMx lower half (YMMx registers do not have an
independent DWARF register number)
- modifying the formatSSEReg function to handle them when they are
present.
Fixes#2033
* Initial support for scopes and variables requests
* Add detailed variables test
* Address review comments
* Fix typo and redudant escaped characters
* Bug fix for uninitialized interfaces; no refs needed for 0-size vars
* Minor cosmetic tweaks
* Add incomplete loading test
* Make DeepSource happy
* Remove unnecessary t.Helper() calls
* Update broken test after merge
* Add missing return
* Rework test harness to abort testvariables2 before stack overflow
* Remove accidentally duplicated disconnet
* Test for invalid interface type with regex
* Drop testvariables3, clean up and test unreadable case
* Respond to review comments
* Make expectVar test helper less fragile
* Make DeepSource happy
* Use proc.LoadConfig directly
* Adjust test to avoid var count discrepency between Go 1.15 and earlier
* Make compound keys in a map unique for correct display
* Remove locals num check that will break if more vars are added
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* proc: start variable visibility one line after their decl line
In most cases variables shouldn't be visible on their declaration line
because they won't be initialized there.
Function arguments are treated as an exception.
This fix is only applied to programs compiled with Go 1.15 or later as
previous versions of Go did not report the correct declaration line for
variables captured by closures.
Fixes#1134
* proc: silence go vet error
* Makefile: enable PIE tests on windows/Go 1.15
* core: support core files for PIEs on windows
* goversion: add Go 1.15 to supported versions
* proc: fix function call injection for Go 1.15
Go 1.15 changed the call injection protocol so that the runtime will
execute the injected call on a different (new) goroutine.
This commit changes the function call support in delve to:
1. correctly track down the call injection state after the runtime
switches to a different goroutine.
2. correctly perform the escapeCheck when stack values can come from
multiple goroutine stacks.
* proc: miscellaneous fixed for call injection under macOS with go 1.15
- create copy of SP in debugCallAXCompleteCall case because the code
used to assume that regs doesn't change
- fix automatic address calculation for function arguments when an
argument has a spurious DW_OP_piece at entry
The file:line information for the entrypoint is more acccurate than the
file:line information at a return point, which could be affected by a
compiler bug.
Fixes#2086
On platforms other than macOS this doesn't matter but on macOS a
segmentation fault will cause ContinueOnce to return an error, before
returning it we should still fix the current thread and selected
goroutine values.
Fixes#2078
* dwarf/line: implement DW_LNE_set_discriminator
We don't use the discriminator field in any way but we need to at least
parse it to support debub_line programs that use it.
* dwarf/line: support parsing DWARF4 debug_line sections
There is an extra field maximum_operations_per_instruction that is used
for VLIW CPUs. We don't support this feature but we have to at least
parse the field to not crash.
Under some circumstances (methods with non-pointer receivers or from
embedded fields called through an interface) the compiler will
autogenerate wrapper functions.
This commit changes next, step and stepout to skip all autogenerated
wrappers.
Fixes#1908
Implement debugging function for 386 on linux with reference to AMD64.
There are a few remaining problems that need to be solved in another time.
1. The stacktrace of cgo are not exactly as expected.
2. Not implement `core` for now.
3. Not implement `call` for now. Can't not find `runtime·debugCallV1` or
similar function in $GOROOT/src/runtime/asm_386.s.
Update #20
* Fixed DirIdx (index starts at one)
I am using the elf to load C++ based elf and there the index starts at one and not zero, hence the minor fix.
* Added test
* Added proper test for c-generated elf & replaced index offset by adding build dir
* Changed other IncludeDir test
* Format fix & replace print with actual test
* Format fixes @derekparker requested.
Removes the restriction that the DWARF type for the receiver of a method
must be a TypeDef. This seems reasonable in practice, but it turns out
Go DWARF does not consider
```
type X int
```
to be a typedef. This patch also allows for calling a method where the
receiver is not used or passed in, such as:
```
func (_ X) Method() { println("why") }
```
According to #1800#1584#1038, `dlv` should enable the user to dive into
memory. User can print binary data in specific memory address range.
But not support for sepecific variable name or structures temporarily.(Because
I have no idea that modify `print` command.)
Close#1584.
* proc: separate amd64-arch code
separate amd64 code about stacktrace, so we can add arm64 stacktrace code.
* proc: implemente stacktrace of arm64
* delve now can use stack, frame commands on arm64-arch debug.
Co-authored-by: tykcd996 <tang.yuke@zte.com.cn>
Co-authored-by: hengwu0 <wu.heng@zte.com.cn>
* test: remove skip-code of stacktrace on arm64
* add LR DWARF register and remove skip-code for fixed tests
* proc: fix the Continue command after the hardcoded breakpoint on arm64
Arm64 use hardware breakpoint, and it will not set PC to the next instruction like amd64. We should move PC in both runtime.breakpoints and hardcoded breakpoints(probably cgo).
* proc: implement cgo stacktrace on arm64
* proc: combine amd64_stack.go and arm64_stack.go file
* proc: reorganize the stacktrace code
* move SwitchStack function arch-related
* fix Continue command after manual stop on arm64
* add timeout flag to make.go to enable infinite timeouts
Co-authored-by: aarzilli <alessandro.arzilli@gmail.com>
Co-authored-by: hengwu0 <wu.heng@zte.com.cn>
Co-authored-by: tykcd996 <56993522+tykcd996@users.noreply.github.com>
Co-authored-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
Due to a bug in the Go compiler midstack inlined calls do not report
their ranges correctly. We can't check if an address is in the range of
a DIE by simply looking at that DIE's range, we should also recursively
check the DIE's children's ranges.
Also fixes the way stacktraces of midstack inlined calls are reported
(they used to be inverted, with the deepest inlined stack frame
reported last).
Fixes#1795