* Upgrade FreeBSD version
* proc: fixes concerning call injection on freebsd and rr
On FreeBSD it seems we have problems restoring and setting floating
point registers, since at least restoring is necessary for call
injection to function properly fully disable call injection on FreeBSD.
On rr the same problem exists, however due to the fact that we are
acting on a recording and ending a diversion will restore register
values anyway simply disable the floatsum test.
See also: https://github.com/rr-debugger/rr/issues/3208
Updates #3001
* _scripts/test_linux.sh,_scripts/test_windows.ps1: always return exit code 0 when testing on tip
Same as what we do for test_mac.sh
* proc: support function call injection on arm64
Support function call injection on arm64 with go1.19
Moves breakpoindIDCounter out of BreakpointsMap and into
service/debugger.Debuggger to simplify proc.Target's API and aid with
implementing fork follow mode, where we'll have to debug multiple
processes simultaneously.
* service: Implement BuildID
Parse the BuildID of executables and provides it over the RPC
service.
Signed-off-by: Morten Linderud <morten@linderud.pw>
* command: Support debuinfod for file listing
Signed-off-by: Morten Linderud <morten@linderud.pw>
* debuginfod: create debuginfod package for common code
We remove the duplicated code and provide our a new debuginfod package.
Signed-off-by: Morten Linderud <morten@linderud.pw>
* starlark: Workaround for 'build_i_d'
Signed-off-by: Morten Linderud <morten@linderud.pw>
* command: Ensure we only overwrite path when one has been found
Signed-off-by: Morten Linderud <morten@linderud.pw>
* bininfo: Inline parseBuildID
Signed-off-by: Morten Linderud <morten@linderud.pw>
This is a partial revert of PR #2660.
Some users develop in environments where execution of binaries
in temp directory is prohibited or undesirable. Moreover, the
current implementation creates binaries with random names
and that made it more difficult to set up firewall exclusion
rules. Revert it and always use the default debug output name.
(The debug binary will be created in the delve's working directory
and an editor does not have any promise on working directory
unless user specifies it through dlvCwd. So users still need to
chase them unless they set the exclusion rule purely based on
the file base name).
Fixesgolang/vscode-go#1955
1. change ExpectOutputEventProcessExited to accept -1 exit status, this
is a real problem on linux but we don't know how to fix it and we
already have a test in proc for it.
2. change TestNoDebug_AcceptNoRequestButDisconnect to be less picky
about message ordering, all message orderings seem to be fine, there
is no reason to insist on a particular one, since the DAP server is
unable to actually produce it deterministically.
Fixes#2860
* dap: support 'Env' attribute for launch requests
Env is applied in addition to the delve process environment
variables. The env setting is done by calling os.Setenv
as early as possible when a Launch request is received.
Prior discussion is in https://github.com/go-delve/delve/pull/2582
In Visual Studio Code, setting null for an environment variable
in launch.json or tasks.json indicates users want to unset
the environment variable. Support the behavior by accepting
nil value.
* dap: Env field itself can be omitempty
* edit comment
* service/debugger: disable breakpoints with hitcond not satisfiable
To avoid slowing down the debugged process unnecessarily, we disable
breakpoints with a hit condition that can no longer be hit again.
* test: add integration tests for hit conditions no more satisfiable
* proc/test: fix typo in breakpoints related tests
* test: use the new API for hitcond integration tests
* go.mod: update golang.org/x/tools to v0.1.8
Fixes TestGeneratedDoc on go1.18
* TeamCity: bump test matrix
Add 1.18 to test matrix. Remove 1.15 from test matrix and from support range.
* proc,tests: update for regabi on arm64 and 386
Make sure that stacktrace registers always contain the PC register of
the current frame, even though the debug_frame rules might not specify
it on architectures that use a link register.
The PC register is needed to look up loclist entries for variable
evaluation.
* goversion: bump maximum supported Go version to 1.18
* proc: disable asyncpreempt on linux/arm64
Asyncpreempt on linux/arm64 can sometimes restart a sequence of
instructions which will make breakpoint appear to be hit twice in some
cases.
When printing breakpoints on generic functions use the function name
without parameters instead of using the name of the first instantiation
that appears on the list.
* service/debugger: fix bug internal err with Restart on recorded target
If Restart is called after a Continue and Rewind on a recorded target
that has already terminated it will return an internal error.
* proc/gdbserial: allow rewind to work after process exit with rr
It is sometimes useful to set breakpoints and rewind a terminated
process when using rr, for example if interested in the last execution
of some function.
RR will not allow a backward continue after the process exit packet has
been sent, however rr will also generate a synthetic SIGKILL right
before process exit.
Treat this packet as a process exit and change some things so both
continuing backwards and setting breakpoints can be done, on recorded
targets, after process exit has been reported.
* made Pid a method of Target instead of a method of Process
* changed argument of NewTarget to ProcessInternal, since that's the
interface that backends have to implement
* removed warnings about ProcessInternal since there is no way for
users of pkg/proc to access those methods anyway
* made RecordingManipulation an optional interface for backends, Target
supplies its own dummy implementation when the backend doesn't
* inlined small interfaces that only existed to be inlined in
proc.Process anyway
* removed unused function findExecutable in the Windows and no-native
darwin backends
* removed (*EvalScope).EvalVariable, an old synonym for EvalExpression
* proc,locspec: support setting breakpoints by func name on generic funcs
Changes proc.Function to parse function names correctly when they
contain instantiation lists and locspec to match generic functions.
* vendor: update golang.org/x/tools
The old version of golang.org/x/tools is incompatible with the new
iexport format.
From the DAP spec:
If this attribute exists and is non-empty, the backend must not 'break' (stop) but log the message instead.
Expressions within {} are interpolated.
This change parses the log messages and stores the parsed values as a format string and list of expressions to evaluate and get the string value of.
Updates golang/vscode-go#123
* service/dap: fix goroutine id selection for hardcoded breakpoints
Determining the stopped goroutine id on a breakpoint required
checking for breakpoints since some may be tracepoints. However,
there may be goroutines stopped on hardcoded breakpoints with
no breakpoint. We fix this by checking for runtime.breakpoint or
StopReason=proc.StopHardcodedBreakpoint.
We want to provide more flexibility for users to make changes to their configurations while the debug session is running. This could be accomplished by creating a custom request, but that were require a new UI as well, and every client of dlv dap to provide its own UI for this. By using the evaluate context, users can use the already existing debug console to change their configurations.
This change includes a refactor of the terminal code in order to share the code with the dap package.
This change provides a very similar to UI as the terminal package, but there are different configuration options that are DAP specific. We plan to use this same mechanism to expose a few other commands including "sources" to help users debug an ineffective substitutePath configuration.
This high-level goal is to push more shutdown logic into Session and not rely Server.Stop() because dap's version of Stop() is different from rpccommon. That means triggering the same shutdown steps in multiple places, so additional safeguards are added to make some of the duplicate steps no-ops to avoid errors, extra logging, etc.
This includes the following changes:
close client conn when request loop in serveDAPCodec exits (to match rpccommon)
exit request loop after processing a disconnect request (instead of relying on next read to fail because conn got closed by triggered Stop(), which is skipped in case of accept-multiclient and is not closed in Stop() in rpccommon)
reset debugger to nil to avoid shutting it down more than once and causing duplicate logging (in case stopDebugSession is called from onDisconnectRequest and Server.Stop or Session.Close as things shut down)
reset binaryToRemove to "" upon removal to avoid duplicate error (in case Close() is called more than once outside of Stop(), which technically is not the case right now)
expand testing for all possible server shutdown triggers
testing for Session-only shutdown as it will be integrated into rpccommon without dap.Server wrapper
updates golang/vscode-go#1830
updates #2328
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* service/dap: remove deadlock in TestLaunchDebugRequest
Fixes#2746
* terminal: fix TestScopePrefix flakiness
When there are more than 10 frames api.PrintStack will prefix the
output with spaces to right justify the frame number, which confuses
TestScopePrefix.
* _scripts: pass -buildvcs for Go 1.18 and later on TeamCity
Go 1.18 will try to stamp builds with the VCS version, this doesn't
work on TeamCity because the checkout isn't a valid repository (but
looks like it).
Pass -buildvcs=false to disable this feature.
* proc: switch to goroutine stack if first frame's func can not be found
If the first frame on the system stack can not be resolved to a
function switch directly to the goroutine stack.
Normally calls can't be performed on recorded processes, becuase the
future instructions executed by the target are predetermined. The rr
debugger however has a mechanism that allows this by taking the current
state of the recording and allowing it to diverge from the recording,
temporarily.
This commit adds support for starting and ending such diversions around
function calls.
Note: this requires rr version 5.5 of later to work, see:
https://github.com/rr-debugger/rr/pull/2748
This adds a new `--client-addr=host:port` flag to `dlv dap`.
If it is supplied, the dap process will dial into the tcp port where
a DAP client is waiting, and work with only the DAP client.
The DAP client is supposed to start the normal DAP message
exchange starting with the 'initialize' request after the dlv dap
process dials in and the connection is set up.
VS Code Go extension plans to use this mode for
* reliably detecting `dlv dap` readiness. Currently it depends on
watching the log stream. After this PR, it can listen on a network port.
* running `dlv dap` from any terminal (part of RunInTerminal workflow
implementation).
A set breakpoints request could come in while the program is running. For a seamless user experience, the server should set the breakpoint and then continue program execution.
Updates golang/vscode-go#1676
* proc/native: always stop after RequestManualStop on Windows
On Windows RequestManualStop will generate an exception on a special
DbgUiRemoteBreakin thread, sometimes this thread will die before we
finish stopping the process. We need to account for that and still stop
even if the thread is gone and no other thread hit a breakpoint.
Fixes flakiness of TestIssue419.
* proc/native: fix watchpoints with new threads on Windows
When a new thread is created we must reapply all watchpoints to it,
like we do on linux.
* tests: be lenient on goroutinestackprog tests on Windows
We can not guarantee that we find all goroutines stopped in a good
place and sometimes the stacktrace fails on Windows.
* service/dap: refactor the server into two layers
* Add delay before setting debugger in remote tests
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
Change debug_info type reader and proc to convert parametric types into
their real types by reading the corresponding dictionary entry and
using the same method used for interfaces to retrieve the DIE from a
runtime._type address.
'2586e9b1'.
With generics a single function can have multiple concrete
instantiations, the old version of FindFileLocation supported at most
one concrete instantiation per function and any number of inlined
calls, this supports any number of inlined calls and concrete
functions.
Internal breakpoints do not need IDs and assigning them from a counter
separate from the user ID counter can be a cause of confusion.
If a user breakpoint is overlayed on top of a pre-existing internal
breakpoint the temporary ID will be surfaced as if it was a user ID,
possibly conflicting with another user ID.
If a temporary breakpoint is overlayed on top of a pre-existing user
breakpoint and the user breakpoint is first deleted and then
re-created, the user ID will be resurrected along with the breakpoint,
instead of allocating a fresh one.
This change removes internal breakpoint IDs entirely, only user
breakpoints receive an ID.
Right now, if (*compositeMemory).WriteMemory needs to write a value to
a register that's smaller than the full size of the register (say, a
uint32 being passed as an argument), then (*AMD64Registers).SetReg can
later fail a sanity check that ensures the passed DwarfRegister is a
full size register.
Fix this by reading the old value of the register and overwriting just
the relevant parts with the new register. For the purposes of an
argument, it would probably be fine to just pad with zeroes, but merging
with the existing value is what gdb does.
Fixes#2698
Log points are special kinds of breakpoints that do not 'break' but instead log a message and then continue. This change implements basic log points that simply log the provided message, without any interpolation.
In order to resume execution after hitting a breakpoint, I added a new lock resumeMu and tracked the running state within the DAP server. resumeMu must be held in order to issue a debugger request that would start execution. This means it can be used to make sure that another goroutine does not resume execution while you are holding the lock.
Most of the synchronization logic is taken from PR #2530
Updates golang/vscode-go#123
When we set a limit on the number of threads that would be
returned, it was possible that the selected thread was not
included in the list of threads. This could cause issues
because the stopped reason is associated with the selected
goroutine, so users could be missing out on important info.
This change makes sure that the selected goroutine is included
by adding it to the end of the list.
Formally define these types and document their meaning.
We will auto-generate the dlv-dap documentation from these Go type doc.
mapToStruct is a helper that sets the given struct's fields with the
info in map[string]interface{} (launch/attach's Arguments). We achieve
this by reencoding map[string]interface{} to json and decoding back to
the target struct. If go-dap left the implementation-specific arguments
as json.RawMessage and let the implementation decode as needed, this
reencoding could've been avoided.
encoding/json itself does not have mean to enforce required fields.
There was a test case that checks substitutePath elements must set
both from/to fields. Path.UnmarshalJSON implements the check.
I am not yet sure about the need for distinction between missing
'from/to' and empty strings yet. (empty value is useful when dealing with
a binary built with trimpath, right?)
A minor behavior change - previously, if noDebug is not a boolean type,
we ignored the attribute silently. Since we use json decoding, any
mismatched types will cause an error and this non-boolean type noDebug
attribute will result in launch failure.
This patch enables the eBPF tracer backend to parse the ID of the
Goroutine which hit the uprobe. This implementation is specific to AMD64
and will have to be generalized further in order to be used on other
architectures.
* service/dap: add test verifying handling of relative program path
* Add exec test, log build dir and document in --help
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* service/dap: add test that verifies output path is relative to wd
* Use cleanExeName to get the right output name on Win
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
Change the socket search to check both the remote and local fields of the
socket match the socket we want to find.
Sockets are identified by the 4-uple
local_addr, local_port, remote_addr, remote_port
Two socket can differ by a single one of this four elements.
It is possible for the same local_port to be used by two different sockets,
as long as they are connecting to different remote addresses (or remote
ports).
An example of this bug in action can be seen at:
https://github.com/golang/vscode-go/runs/3141270564?check_suite_focus=true
There the server starts listening on 127.0.0.1:46011 and rejects a valid
client connection by finding the following socket:
60: 0100007F:DD82 0100007F:962D 06 00000000:00000000 03:00000133 00000000 0 0 0 3 0000000000000000
the local address of this socket is 0100007F:DD82 (127.0.0.1:56706), and the
remote address is 0100007F:962D (127.0.0.1:38445).
The reported error is:
closing connection from different user (127.0.0.1:56706): connections to localhost are only accepted from the same UNIX user for security reasons
note how the local port does match the socket line (56706) but the remote
port is wrong (38445 instead of 46011).
Note also that the state of this socket is 06, or TIME_WAIT, which would be
impossible if this was the right socket, since the right socket would still
be open.
Fixes https://github.com/golang/vscode-go/issues/1555
In order for DAP to support halting the program (either manually or on a breakpoint) performing some action and then resuming execution, there needs to be a way to stop the program without clearing the internal breakpoints. This is necessary for log points and stopping the program to set breakpoints.
The debugging UI makes it seem like a user should be able to set or clear a breakpoint at any time. Adding this ability to complete synchronous requests while the program is running is thus important to create a seamless user experience.
This change just adds a configuration to determine whether the target should clear the stepping breakpoints, and changes the server to use this new mode. Using the new mode means that the DAP server must determine when it expect the next to be canceled and do this manually.
* terminal,service: add way to see internal breakpoints
Now that Delve has internal breakpoints that survive for long periods
of time it will be useful to have an option to display them.
* proc,terminal,service: support stack watchpoints
Adds support for watchpoints on stack allocated variables.
When a stack variable is watched, in addition to the normal watchpoint
some support breakpoints are created:
- one breakpoint inside runtime.copystack, used to adjust the address
of the watchpoint when the stack is resized
- one or more breakpoints used to detect when the stack variable goes
out of scope, those are similar to the breakpoints set by StepOut.
Implements #279
* proc: move breakpoint condition evaluation out of backends
Moves breakpoint condition evaluation from the point where breakpoints
are set, inside ContinueOnce, to (*Target).Continue.
This accomplishes three things:
1. the breakpoint evaluation method needs not be exported anymore
2. breakpoint condition evaluation can be done with a full scope,
containing a Target object, something that wasn't possible before
because ContinueOnce doesn't have access to the Target object.
3. moves breakpoint condition evaluation out of the critical section
where some of the threads of the target process might be still
running.
* proc/native: handle process death during stop() on Windows
It is possible that the thread dies while we are inside the stop()
function. This results in an Access is denied error being returned by
SuspendThread being called on threads that no longer exist.
Delay the reporting the error from SuspendThread until the end of
stop() and only report it if the thread still exists at that point.
Fixes flakyness with TestIssue1101 that was exacerbated by moving
breakpoint condition evaluation outside of the backends.
The Threads request sent immediately after the ConfigurationDone
request can be processed in two possible states:
- while the program is being executed, when it will return Id=1,
Name=Dummy
- after the program terminates, when it will return Id=-1, Name=Current
additionally the response could be received in any order with the
Terminate event.
Remove the problematic Threads request from the test.
There is already a lock on the actual buffered tracepoints collection
within proc, and this method call doesn't do anything to mutate Target
otherwise so we shouldn't be opening ourselves up for a race condition
error or any other kind of parallelism problem.
Additionally, with this lock we essentially can never get the data until
the process has exited becuase `continue` will lock the target. This
change allows us to get the buffered tracepoint information immediately
and display it as the program is running.
The loop searching for a suitable goroutine is not guaranteed to ever
find it, and failing to find one is not an error.
Changes testStepParkedHelper to match the behavior of TestNextParked in
proc_test.go.
Deletes TestStepInParked because it does not test anything meaningful
beyond what's already tested by TestNextParked.
Returning monotonically increasing totalFrames values for subsequent requests can be used to enforce paging in the client. If we are not at the end of the stackFrames that are returned, we return a higher total frames to suggest to the client that they should request more frames.
To make it more clear that the user can resume the program when they encounter a next while nexting error, make the exception information have instructions for resuming the program. This implements the suggestions outlined by @polinasok in #2443.
* pkg/proc: Prefer throw instead of fatalthrow
Currently there is a breakpoint set at runtime.fatalthrow to catch any
situation where the runtime crashes (e.g. deadlock).
When we do this, we go up a frame in order to parse the crash reason.
The problem is that there is no guarentee the "s" variable we attempt to
parse will still be considered "live".
Since runtime.fatalthrow is never called directly, set a breakpoint on
runtime.throw instead and prevent having
to search up a stack frame in order to
get the throw reason.
Fixes#2602
* service/dap: Fix TestFatalThrowBreakpoint
* Reenable TestFatalThrow DAP test
* service/dap: Don't skip test on < 1.17
* service/dap: Update test constraint for 1.16
* pkg/proc: Reinstate runtime.fatalthrow as switchstack exception