Fix cast to empty interface type. This is a workaround for a
discrepancy between how type names are serialized by the compiler vs
how type expressions are formatted by go/printer.
* Add support for windows/arm64
* split sentinel files and add winarm64 experiment
* update loadBinaryInfoPE to support PIE binaries
* skip TestDump on windows/arm64
* run windows/arm64 compilation on windows/amd64
* add entry point check for pie binaries
* delete unusded code
* document windows/arm64 breakpoint
* implement changing windows/arm64 fp registers
* update crosscall offset names
* fix G load when using CGO
* fix testvariablescgo
* remove DerefGStructOffset
* derefrence gstructoffset in GStructOffset() if necessary
The logical breakpoints map was created as a side effect of
createUnrecoveredPanicBreakpoint or createFatalThrowBreakpoint, however
with an executable with incomplete debug info (that must be incomplete
in just the right way) both will fail and the logical breakpoint map
will never be created.
It's unknown how such an executable could be created, one easy way is
to debug a non-go executable.
Fixes#3114
Go 1.20 switched to uint64 to represent goroutine IDs, we can't
actually follow suit because we have allowed clients to use -1 to refer
to the currently selected goroutine, however we should at least switch
to int64 and also update the rtype check to accept the 1.20 type.
Go 1.19 is broken on linux/386 with some C compilers, this is a
workaround for our build script. See:
https://github.com/golang/go/issues/52919
Also fix TestBuild if the first message reported by delve is not the
message that indicates the server is listening.
We allowed integer and pointer type casts everywhere but type casts to
string, []byte and []rune only at toplevel.
Fuse evalToplevelTypeCast and evalTypeCast and allow both kinds
everywhere. There are multiple other ways to create variables than
don't reference user memory anyway (which wasn't the case back when
evalToplevelTypeCast was implemented).
Fixes#1423
As we parse this informatin in the loop we must take care to assemble
things correctly. In this situation when we encounter a file name,
the dir index is -1, then subsequently we get the correct dir index
for that file and can put them together. Previously we were adding the
file and then the directory location to the file list instead of
correctly concatenating them, resulting in an incorrect file list making
indexing into the list return incorrect results later on.
This patch improves the output of the trace subcommand by
adding better line breaks, adding goroutine info to the
return statement, and removing unnecessary output.
This patch removes the old error-prone way of tracking
whether the tracepoint is for a function entry or
return. Instead of trying to guess, let the data structure
simply tell us directly.
The ebpf implementations uses cgo, but only to access some C struct
definitions. Instead of using cgo simply duplicate the defintion of
those two structs in Go and add a test to check that the duplicate
definitions remain synchronized.
Fixes#2827
1. return an error when SetUProbe fails, while creating ebpf tracepoints
2. if no tracepoint can be set for 'dlv trace' exit early
3. never leave the traced program running
4. fix typo in description of --ebpf flag
Fixes#3006
Introduces a new TargetGroup abstraction that can be used to manage
multiple related targets.
No actual management of child processes is implemented here, this is
just a refactoring to make it possible to do that in the future.
Updates #2551
In commit eee6f9f82 Go changed the order that crosscall2 uses to save
its registers, update arm64SwitchStack to use the new order when the
binary was compiled by go 1.19.
Fixes#2993
In non-headless instances Ctrl-C should pause the process, not
terminate it. To make this work on Windows we have to pass the
syscall.CREATE_NEW_PROCESS_GROUP flag to os.StartProcess.
When doing a map lookup with a string literal we should load as much of
the keys to at least match the length of the string literal, so that
the lookup doesn't fail with the "string too long" error.
Fixes#3034
Go 1.19 also formats doc comments according to the new godoc syntax.
Some of our comments, especially unexported symbols did not conform to
the godoc syntax and therefore are mangled by 'go fmt'.
This PR runs 'go fmt' from go1.19 on everything and manually fixes the
problems.
See also:
https://github.com/golang/proposal/blob/master/design/51082-godocfmt.md
When we send an interrupt request to debugserver we, sometimes, get one
extra spurious stop packet back.
This stop packet gets interpreted as a response to a qThreadStopInfo request
we make causing the protocol to become desynchronized for a while, until
eventually some kind of error appears.
Here's an example of this problem, distilled from issue #3013:
1 <- $vCont;c#a8
2 <- interrupt
3 -> $T05thread:12efb47;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
4 <- $qThreadStopInfo12efb8e#28
5 -> $T05thread:12efb47;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
6 <- $qThreadStopInfo12efb8f#29
7 -> $T00thread:12efb8e;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
8 <- $qThreadStopInfo12efb90#f4
9 -> $T00thread:12efb8f;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
10 <- $qThreadStopInfo12efb91#f5
11 -> $T00thread:12efb90;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
12 <- $qThreadStopInfo12efb47#f6
13 -> $T00thread:12efb91;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
14 <- $qThreadStopInfo12efb8d#27
15 -> $T05thread:12efb47;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
16 <- $p0;thread:12efb8e;#f5
17 -> $T00thread:12efb8d;threads:12efb47,12efb8d,12efb8e,12efb8f,12efb90,12efb91;thread-pcs:10abe83,7ff81b20e2be,7ff81b20e3ea,...
response (3) is interpreted as the response to the vCont request at (1). We
then make a qThreadStopInfo request (4) and receive a stop packet in
response (5). Packet (5) is interpreted as the response to (4) but it
actually isn't, note how the thread ID is different, packet (5) is actually
a spurious stop packet sent by debug server. From response (5) onward the
protocol is desynchronized, none of the response we process are actually the
response to the preceding request.
This eventually causes a failure at packet (17) which debugserver sent as
the response to request (14) but we interpret as the response to (16).
Fixes#3013
Moves variable evaluation tests to pkg/proc which is where most of the
code they test exists, this also allows the removal of a bunch of
duplicate support code.
Fix pretty printing for CPU register components (created with the
XMM0.uintN syntax) while using format strings
Also fixes printing large literal constants with format strings.
Fixes#3020
* pkg/proc: convert freebsd ptrace code to cgo
There is little point in having cgo call a custom C function, when the same
can be done directly from cgo (with less code and effort). Split the amd64
specific code into ptrace_freebsd_amd64.go. Also avoid mixing C.ptrace()
with syscall.SYS_PTRACE.
This will make further changes easier - no functional change intended.
* pkg/proc: check return values of ptrace calls on freebsd
The return values of the PT_GETNUMLWPS and PT_GETLWPLIST ptrace calls were
previously unchecked. While these should not fail, panic instead of using
-1 with slice allocation/handling.
* pkg/proc: return *amd64util.AMD64Xstate from freebsd ptraceGetRegset
Return a pointer to a struct, rather than a struct - this simplifies the
code in both the caller and the ptraceGetRegset function, while also avoiding
struct copying.
* pkg/proc: fix floating point register setting on freebsd
The original code could never work - PT_SETREGS on freebsd does not
take an iovec, nor does it set FP registers. Furthermore, the xsave
bytes were not stored in the amd64util.AMD64Xstate struct.
Updates #3001
* pkg/proc: re-enable function call injection on freebsd
Floating point registers can now be set and restored correctly.
This is a partial revert of 51090f003bace1f8cc37b8480ffdb6f6cc91fa5a.
Fixes#3001
* pkg/proc: deduplicate register setting code on freebsd
Adds a LogicalBreakpoint type to represent logical breakpoints
explicitly. Until now logical breakpoints were constructed implicitly
by grouping physical breakpoints together by their LogicalID.
Having logical breakpoints represented explicitly allows for a simpler
implementation of disabled breakpoints, as well as allowing a simple
implementation of delayed breakpoints (#1653, #2551) and in general of
breakpoints spanning multiple processes if we implement debugging
process trees (#2551).
Updates #1653
Updates #2551
debugCallV2 for amd64 has a bug where it corrupts the flags registers
every time it is called, this commit works around that problem by
restoring flags one extra time to its original value after stepping out
of debugCallV2.
Fixes#2985
* 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
The fix in #2959 was incomplete and the skip was still broken on
linux/386 for PIE builds due to calls to the get_pc_thunk helper.
Co-authored-by: a <a@kra>
On FreeBSD and OpenBSD, the use of runtime.LockOSThread is resulting in segfaults
within the Go runtime (see https://github.com/golang/go/issues/52394) - while it
should not be necessary, calling runtime.UnlockOSThread upon exit from
handlePtraceFuncs avoids this issue and allows the tests to run correctly.
Replaces sys.Iovec with a similar struct that uses uintptr instead of
*byte for the base field when referring to addresses of the target
process, so that we do not generate invalid pointers.
Fixes#2919
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.
This commit improves the handling of hardcoded breakpoints in Delve.
A hardcoded breakpoint is a breakpoint instruction hardcoded in the
text of the program, for example through runtime.Breakpoint.
1. hardcoded breakpoints are now indicated by setting the breakpoint
field on any thread stopped by a hardcoded breakpoint
2. if multiple hardcoded breakpoints are hit during a single stop all
will be notified to the user.
3. a debugger breakpoint with an unmet condition can't hide a hardcoded
breakpoint anymore.
* 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>
It's possible that an inlined function call also contains an inlined
sunroutine. In this case we should also parse the children of
inlined calls to ensure we don't lose this information.
Always load eh_frame section from the executable file instead of the
split debug info file. The eh_frame section is meant to be loaded in
memory along with the executable file so it will usually not be present
in a split debug info file (or, if it is present, it will be the wrong
one).
packages
Changes UserCurrent to exclude frames stopped inside the 'internal' and
'runtime/internal' packages of the standard library.
Before this change a goroutine blocked accepting or reading from a
socket would be reported as having a user current frame of:
internal/poll.runtime_pollWait
After this change accepting goroutines will be reported with a user
current frame of:
net.(*netFD).accept
and reading goroutines as:
net.(*netFD).read
* 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.
* 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.
Fix signal handling during thread single stepping so that signals that
are generated by executing the current instruction are immediately
propagated to the inferior, while signals other signals sent to the
thread are delayed until the full resume happens.
Fixes a bug where a breakpoint set on an instruction that causes a
SIGSEGV would make Delve hang and a bug where signals received during
single step would make it look like an instruction is executed twice.
Fixes#2801Fixes#2792
Add some dummy go files so that 'go mod vendor' works for modules that
require Delve, becuase directories that do not contain any go code will
not be vendored.
* proc: log errors reading debug_info
Because of an incorrect use of debug/dwarf.Reader errors encountered
while reading debug_info were not reported.
Updates #2786
* proc: use debug_line_str section for PE and Macho-O files
Updates #2786
* 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.
Debugserver has a bug where writing to a AVX-2 or AVX-512 register does
not work unless it is followed by at least a write to a AVX (not 2 or
512) register.
See also: https://bugs.llvm.org/show_bug.cgi?id=52362Fixes#2767
There are persistent issues with watchpoints on Windows, it is not
clear whether it's a problem with the VM running the tests or if there
is a real bug in our implementation of hardware breakpoints on Windows.
Until the cause can be determined watchpoints on Windows will be
disabled.
Updates #2768
* 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
* 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.
Adds watchpoint support to gdbserver backend for rr debugger and
debugserver on macOS/amd64 and macOS/arm64.
Also changes stack watchpoints to support reverse execution.
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.
When the function we are calling is an autogenerated stub (because, for
example, we are calling it through a function pointer) the declaration
line of variables is meaningless and could cause us to discard valid
return arguments.
Go 1.18 removed the jmpdefer call from deferreturn, now deferreturn is
a normal function call that can appear on the stack, rules for
detecting a deferreturn call must be changed and new code must be added
to skip it while stepping out.
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
* pkg/proc: update check for system goroutine
The finalizer goroutine can be either a system goroutine or a user goroutine. It is considered a user goroutine only when it calls back to user code. This change attempts to get closer to the implementation in the src/runtime/traceback.go by checking the value of fingRunning.
We could alternatively adopt the approximation done by src/cmd/trace/trace.go which only special cases "runtime.main", and always considers the finalizer to be a system goroutine.
If we cannot find debug information locally on the system, try and
invoke debuginfod-find in order to ask the linux distribution we're on
to find the debug information for us.