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
The DWARF standard does not say that a DW_ATTR_abstract_origin can only
reference entries that appear before it, this change fixes BinaryInfo
to comply. See #2284 for an example of this happening.
Changs TestClientServer_FullStacktrace and
Test1ClientServer_FullStacktrace to log more information, also removes
code from TestFrameEvaluation that could mask the error.
Updates #2231
* add -json flag when running tests on TeamCity
* introduce TeamCity builds
* restore gdbserial constants for 386
Otherwise compilation fails.
* skip TestAttachRequest on Windows as it never finishes
* run tests on 1.16beta1
* proc: misc test fixes for Go 1.16
* proc: fix cgo stacktraces in Go 1.16 with simplified C -> Go call path
* dwarf/line: make dwarf/line correct when '\\' are used
Our code depends heavily on paths being '/' separated because go always
produced '/' separated file paths. The call to filepath.Join will
normalize the paths, on windows, to always be '\\' separated, which
violated our assumptions.
This didn't use to be a problem because the codepath that calls
filepath.Join was never exercised by executable files produced by Go,
but Go 1.16 started producing debug_line sections that use the
directory table with https://go-review.googlesource.com/c/go/+/263017/.
Fix this to always use path.Join after making sure, on windows, to
always normalize paths to use '/' as a separator. Replace the use of
filepath.IsAbs with an operating system independent version.
* goversion: bump supported Go version
If a thread exits while we are looking at it just treat it as if the
status had reported it as exited instead of doing something special.
Fixes flakiness in TestIssue387.
Fix bug in DAP test: TestEvaluateCallRequest.
In Go 1.15 the call injection will be executed on a different goroutine
from the goroutine where it was started on to avoid confusing the
garbage collector, the test must be aware of this fact and use the
goroutine ID from the stopped response instead of assuming 1 is the
currently selected goroutine.
Disables TestAttachDetach when running in Github Actions.
Disable some coredump tests when running in Github Actions (core size
limits?).
The comment on the advanceRegs() method was referencing several
nonexistent fields. This patch fixes that, and improves the comment to
reference the peculiar interaction between the method and it.regs.
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.
Adds a flag that distinguishes the return values of an injected
function call from the return values of a function call executed by the
target program.
* Use the active xcode-select path instead of a hardcoded Xcode path
* Refactored exec.Command to invoke Output instead of running with a custom buffer for stdout
Addresses review comment by @derekparker
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
On linux we can not read memory if the thread we use to do it is
occupied doing certain system calls. The exact conditions when this
happens have never been clear.
This problem was worked around by using the Blocked method which
recognized the most common circumstances where this would happen.
However this is a hack: Blocked returning true doesn't mean that the
problem will manifest and Blocked returning false doesn't necessarily
mean the problem will not manifest. A side effect of this is issue
#2151 where sometimes we can't read the memory of a thread and find its
associated goroutine.
This commit fixes this problem by always reading memory using a thread
we know to be good for this, specifically the one returned by
ContinueOnce. In particular the changes are as follows:
1. Remove (ProcessInternal).CurrentThread and
(ProcessInternal).SetCurrentThread, the "current thread" becomes a
field of Target, CurrentThread becomes a (*Target) method and
(*Target).SwitchThread basically just sets a field Target.
2. The backends keep track of their own internal idea of what the
current thread is, to use it to read memory, this is the thread they
return from ContinueOnce as trapthread
3. The current thread in the backend and the current thread in Target
only ever get synchronized in two places: when the backend creates a
Target object the currentThread field of Target is initialized with the
backend's current thread and when (*Target).Restart gets called (when a
recording is rewound the currentThread used by Target might not exist
anymore).
4. We remove the MemoryReadWriter interface embedded in Thread and
instead add a Memory method to Process that returns a MemoryReadWriter.
The backends will return something here that will read memory using
the current thread saved by the backend.
5. The Thread.Blocked method is removed
One possible problem with this change is processes that have threads
with different memory maps. As far as I can determine this could happen
on old versions of linux but this option was removed in linux 2.5.
Fixes#2151
TestStepConcurrentDirect will occasionally fail (7% of the time on my
setup) by either causing the target processs to execute an invalid
instruction or (more infrequently) by switching to the wrong thread.
Both of those are caused by receiving SIGTRAPs for threads hitting a
breakpoint after it has been removed (the thread hits the breakpoint,
we stop everything and remove the breakpoint and only after we receive
the signal).
Change native.(*nativeProcess).stop to handle SIGTRAPs that can't be
attributed to a breakpoint, a hardcoded breakpoint in the program's
text, or manual stops (and therefore are likely caused by phantom
breakpoint hits).
Co-authored-by: a <a@kra>
Due to a missing check TestCgoStacktrace2 didn't actually check
anything. Enable it and then skip it on linux/386 and linux/arm64 where
it's broken.
Co-authored-by: a <a@kra>
If the process receives a signal (or sends a singal to itself) and then
dies before we can route the signal back to it we still need to
retrieve its exit status.
Fixes a rare failure of TestIssue1101 in proc_test.go
Co-authored-by: a <a@kra>
* proc/tests: keep track of tests skipped due to backend problems
Mark tests skipped due to backend problems and add a script to keep
track of them.
* Travis-CI: add ignorechecksum option to chocolatey command
Looks like a configuration problem on chocolatey's end.
* proc: use argument position for addr only when injecting function calls
We can not, in general, use the argument position to determine the
address of a formal parameter, it will not work in presence of
optimizations or inlining. In those cases formal arguments could be
stored in registers.
Fixes#2176
* Travis-CI: add ignorechecksum option to chocolatey command
Looks like a configuration problem on chocolatey's end.
Co-authored-by: a <a@kra>
* Revert "proc: Find executable should follow symbol links."
This reverts commit 3e04ad0fada0c3ab57caf58bc024e4c0f9a3e01a.
* proc: resolve symlinks when searching for split debug_info if path is /proc/pid/exe
Fixes#2168
During the testing of the core dump generation feature two bugs were
discovered in gdbserial:
1. we don't check that both bytes of the checksum are read, if the
buffer only has one byte we can end up reading only one byte instead
of two and the second byte will mess up the parsing of the next
packet
2. binary encoded packets can start with an 'E' and not be errors, when
using binary responses add an extra check for the lenght of the
response before deciding that the response is an error.
Unfortunately this encoding is inherently ambiguous (we can't
distinguish a 3 byte response starting with 'E' from an error) so
binary requests that lead to short responses should be avoided.
Testing this is complicated, they will be tested implicitly by the
upcoming core dump test.
Co-authored-by: a <a@kra>
Since proc is supposed to work independently from the target
architecture it shouldn't use architecture-dependent types, like
uintptr. For example when reading a 64bit core file on a 32bit
architecture, uintptr will be 32bit but the addresses proc needs to
represent will be 64bit.
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
Commit 1ee8d5c reviewed in Pull Request #1960 relaxed some tests using
goroutinestackprog but missed others.
Fixes some test flakiness that isn't relevant.
* 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
Recent change #2061:
292f5c69f0c769fd32c2e8b1e7153b56e908efd7
proc: step into unexported runtime funcs when already inside runtime
means that TestIssue414 (which tries to step repeatedly until the
program exits) can now steps through way more runtime code than it ever
did before. This causes this test to occasionally fail. Stepping
blindly through runtime code has never been particularly safe as the
runtime can switch to a different goroutine causing Delve to misbehave.
This change restores the previous behavior of TestIssue414 where Step
behaved like Next inside runtime code.
These methods only work if registers have been loaded once after the
last resume, there's probably no code path that calls SetXX before
Thread.Registers but lets make sure it can't happen anyway.
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
Normally we don't step into unexported runtime functions because the
compiler is free to insert them into the code and they are not relevant
to the user, however if we are already stepping through a runtime
function we should let step into work normally and step into other
runtime functions.
Changes implementations of proc.Registers interface and the
op.DwarfRegisters struct so that floating point registers can be loaded
only when they are needed.
Removes the floatingPoint parameter from proc.Thread.Registers.
This accomplishes three things:
1. it simplifies the proc.Thread.Registers interface
2. it makes it impossible to accidentally create a broken set of saved
registers or of op.DwarfRegisters by accidentally calling
Registers(false)
3. it improves general performance of Delve by avoiding to load
floating point registers as much as possible
Floating point registers are loaded under two circumstances:
1. When the Slice method is called with floatingPoint == true
2. When the Copy method is called
Benchmark before:
BenchmarkConditionalBreakpoints-4 1 4327350142 ns/op
Benchmark after:
BenchmarkConditionalBreakpoints-4 1 3852642917 ns/op
Updates #1549
Unexport `GetDebugServerAbsolutePath` and avoid unnecessary repeated calls.
Remove `os.Stat` because `Exec.LookPath` has already used `os.Stat`.And Fix
some comments.
On linux platform, we simply treated `/proc/$pid/exe` as the
executable of targeting process when doing `dlv attach`. The
`/proc/$pid/exe` is a symbol link of the real executable file.
Delve couldn't find the corrsponding external debug file based on the
symbol link:
```
could not attach to pid $pid: could not open debug info
```
The fix is to evaluate the symbol links to the actual executable path.
The process could quit while we are inside stop, we should report the
error otherwise the following code will try to send on the closed
ptrace channel.
Fixes a sporadic error in TestIssue1101.
This flag allows users on UNIX systems to set the tty for the program
being debugged by Delve. This is useful for debugging command line
applications which need access to their own TTY, and also for
controlling the output of the debugged programs so that IDEs may open a
dedicated terminal to show the output for the process.
* gdbserial/gdbserver: Dynamically resolve debugserver binary
Instead of hardcoding the absolute path to the Command Line
Tools (CLT) binary, will attempt to resolve the path at the
$PATH, or at the Xcode bundle. If none are available, will
fallback to the default CLT location.
Fixes#986
* gdbserial/gdbserver: Log outgoing executed commands
Add logging to capture the executable and associated arguments used
in LLDBLaunch and LLDBAttach
Related to #986
* gdbserial/gdbserver: Add unit tests for helper function
Define unit tests for helper function. Setup each test to temporarily make
PATH variable, and file system changes, and subsequently revert them.
Related to #986
* gdbserial/gdbserver: Lazily load function
Lazily obtain absolute path to avoid increasing load times.
Remove flaky tests.
Related to #986
The test was always flaky because we can't fully control the state of
all goroutines in the target program, Go 1.14's asynchronous preemption
exacerbates the problem.
See for example:
https://travis-ci.com/github/go-delve/delve/jobs/302407282
This commit relaxes the checks made by the test to avoid irrelevante
flakiness.
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
Allows Delve clients to stop a recording midway by sending a
Command('halt')
request.
This is implemented by changing debugger.New to start recording the
process on a separate goroutine while holding the processMutex locked.
By locking the processMutex we ensure that almost all RPC requests will
block until the recording is done, since we can not respond correctly
to any of them.
API calls that do not require manipulating or examining the target
process, such as "IsMulticlient", "SetApiVersion" and
"GetState(nowait=true)" will work while we are recording the process.
Two other internal changes are made to the API: both GetState and
Restart become asynchronous requests, like Command. Restart because
this way it can be interrupted by a StopRecording request if the
rerecord option is passed.
GetState because clients need a call that will block until the
recording is compelted and can also be interrupted with a
StopRecording.
Clients that are uninterested in allowing the user to stop a recording
can ignore this change, since eventually they will make a request to
Delve that will block until the recording is completed.
Clients that wish to support this feature must:
1. call GetState(nowait=false) after connecting to Delve, before any
call that would need to manipulate the target process
2. allow the user to send a StopRecording request during the initial
GetState call
3. allow the user to send a StopRecording request during any subsequent
Restart(rerecord=true) request (if supported).
Implements #1747
Reset the timer once we start executing the code paths we actually care
to measure, since the setup and continue steps can be relatively
expensive.
Also, disable recording on benchmarks. This seems less useful, and also
cuts out a lot of noise when benchmarks are run.
When switching to the goroutine stack the stack iterator registers
might not have any entry for the BP register, make sure to add it
instead of just trying to change it.
Instead of rescanning debug_info every time we want to read a function
(either to find inlined calls or its variables) cache the tree of
dwarf.Entry that we would generate and use that.
Benchmark before:
BenchmarkConditionalBreakpoints-4 1 5164689165 ns/op
Benchmark after:
BenchmarkConditionalBreakpoints-4 1 4817425836 ns/op
Updates #1549