Supports viewing local variables and evaluating expressions correctly
when range-over-func is used.
The same limitations that the previous commit on this line had still
apply (no inlining, wrong way to identify the range parent in some
cases).
Updates #3733
Because of how range-over-func is implemented it is difficult to
determine the set of visible local variables during expression
compilation (i.e. it is difficulto to keep the HasLocal function
correct).
This commit moves that logic from expression compilation to expression
evaluation.
Updates #3733
When stack watchpoints go out of scope simultaneously they can hide (or
duplicate the effect) of other breakpoints (including other watchpoints
going out of scope) that are placed on the same physical memory
location.
This happens because we delete the watchpoint-out-of-scope breakpoint
while we are evaluating hit breakpoints, mangling the breaklets list.
This commit moves breakpoint deletion out of the
watchpoint-out-of-scope condition, delaying it until all hit
breakpoints have been evaluated.
Also fix bug where on amd64 if all four watchpoints are in use the last
one is not checked.
Fixes#3739
* rebasing on master to implement --followcalls
* in progress changes to enable --followcalls
* rebase to master: modified function to add children to funcs array
* modify main traversal loop
* added tests to check different scenarios
* added tests to check different scenarios
* added tests to check different scenarios
* add test to check for overlapping regular expression
* modified type of strings array as a return only
* changed depth to a simple integer instead of a global map
* avoid calling traverse on recursive calls
* Added tests for various call graphs to test trace followfuncs
* Added tests for various call graphs to test trace followfuncs
* Added tests for various call graphs to test trace followfuncs
* made auxillary changes for build to go through for new option follow-calls
* Add support to print depth of the function calls as well
* Added two sample output files for checking
* Bypass morestack_noctxt in output for verification testing
* Corrected newline error by adding newlines only if the line does not match morestack_noctxt
* Added more tests
* Cleanup
* Updated documentation
* fixed error message in fmt.Errorf
* Fixed result of Errorf not used error
* Addressing review comments to fix depth reporting and other issues
* dont invoke stacktrace if tracefollowcalls is enabled, compute depth from main regex root symbol than main.main
* Addressing a part of review comments
* Added changes to allow deferred functions to be picked up for tracing
* Fix issue to avoid printing stack for a simple trace option
* Moving most tests to integration2_test.go and keeping only one in dlv_test.go
* Moving most tests to integration2_test.go and keeping only one in dlv_test.go
* Adding panic-defer test case
* Moved rest of the tests to integration2_test.go
* addressing review comments: folding Functions and FunctionsDeep, reducing branches by using depth prefix, wrap using %w and other comments
* Optimize traversal and parts of printing trace point function and modify trace output layout
and adjust tests accordingly
* Resolved error occurring due to staticcheck
* Implemented traversal algorithm using breadth first search
* Addressing review comments on the breadth first search implementation and
other comments
* Inline filterRuntimeFuncs and remove duplicate initialization
Initial support for stepping in functions that use the new
range-over-func statement in go1.23.
Does not support:
- inlining
- viewing variables of the enclosing function from a range-over-func
body closure
- the correct way to find the enclosing function from a range-over-func
body closure (but it should work most of the time).
Updates #3733
The following fixes have been applied to make delve work with rr 5.7.0
- added a new launch prefix to exclude from stderr output
- allow the thread selection packet to be sent for 'c' commands even
when the stub supports thread suffixes, because the specification is
unclear over what should be done with bc and bs packets with thread
suffixes.
- changed the way qRRCmd are escaped and added a thread selector to
them to match changes to rr codebase
This change optimizes the gdbwire backend by reducing the number of
round trips we have to make to debugserver. It does this by using the
jstopinfo packet to only query threads which we know to have a stop
reason, and it also uses the registers returned by the 'T' packet
to avoid issuing a bunch of 'p' packets to get the register values.
It seems newer MacOS kernels are sending mach exceptions for watchpoints
which contain the hardware register number as opposed to the address
which triggered the exception. Also, ARM64 seems to have switched to
sending _EXC_I386_SGL as medata[0] for this exception type.
* proc: generalize escapeCheck and allocString
Generalizes the function for checking for escaping pointers so that it
can be used to iterate on all pointers of a variable.
Also generalizes the string allocation opcodes so that in the future we
can use it to call other special runtime functions (for example: map
access, channel send/receive, etc).
* review changes
* Adjust rtype.go script to handle constants moved to internal/abi from
runtime
* Remove tests in service/dap/server_test that relied on knowledge of
the internal layout of channels.
Change 'step' command so that when stepping into a 'go statement' the
debugger will stop on the newly created goroutine, instead of just
stepping over the go statement.
Allows for a user to specify the breakpoint condition directly
when creating the breakpoint. The new syntax looks like the
following:
```
break <name> <locspec> [if <expression>]
```
Also updates docs to include more examples and locspec description
instead of directing users to the online / source documentation.
The `scope.Locals` function did not have any guard checks against missing DWARF information.
This patch adds a check, which likely will need to be added to other functions as well.
* Cirrus-CI: update to FreeBSD 13.3
* proc,go.mod: update x/sys remove KeepAlive calls
Update version of golang.org/x/sys to the latest version and remove
calls to runtime.KeepAlive calls that were added to the FreeBSD backend
to work around an issue in the version of x/sys that we were using.
Adds a recover to the functions reading debug info from the go runtime
data structures for stripped executables.
This function is best-effort and can sometimes fail in weird ways,
instead of crashing recover any panic and turn them into errors.
Fixes#3650
When the users uses a reslice operation load the whole resliced
variable, ignoring the MaxArrayValues setting.
Only apply this when the 'high' part is specified and a literal and the
'low' part is either unspecified or a literal.
Fixes#3600
We used to autoremove the trace recorded by rr but as a result of
various refactorings done to implement follow exec mode this broke.
Restore the functionality.
Also remove the _fixtures/testfnpos.go file which is autogenerated
during testing.
With the glibc loader the link map entry for the static executable has
an empty name field and address equal to 0x0. This case was already
handled by the check in bininfo.go AddImage for names to be valid
paths.
With the musl loader however the first entry, corresponding to the
static executable, has a valid path with address equal to 0x0, since we
record a real address for the image corresponding to the static
executable this results in having two entries for the executable when
musl is used to link go programs.
Change the code scanning the debug link map so that the first entry is
skipped if it has address equal to zero.
Fixes#3617
The flake manifests as an error where the variable i can not be found in
frame 1 and happens in go1.22rc1 between 0.1% and 0.5% of the time (it is highly dependent on CPU contention)
This problem is caused by the new code in evalop.PushLocal referencing the
stale value of SelectedGoroutine. This happens because:
- evalop.PushLocal calls ConvertEvalScope
- ConvertEvalScope calls FindGoroutine
- FindGoroutine checks the value of selectedGoroutine
When breakpoint conditions are evaluated both the value of selectedGoroutine
and currentThread are stale because we can only set their definitive value
*after* all breakpoint conditions have been evaluated.
The fact that it only happens in 1.22rc1 is coincidental, it's probably
caused by the fact that 1.22rc1 migrates goroutines between threads more in
this particular circumstance.
This commit fixes the problem in two ways:
1. selectedGoroutine and currentThread are given temprorary non-stale values
before breakpoint conditions are evaluated
2. evalop.PushLocal is changed so it takes a stack trace of the current
thread rather than resolving it through the selected goroutine.
Either one would suffice however I think we should do both, (2) ensures that
the runtime.frame(n).var will work even if the current thread is not running
any goroutine and (1) ensures that we don't accidentally reference a stale
selectedGoroutine in the future.
The builder is currently spending 15 to 20 minutes installing gcc and
upgrading packages every time we run the tests.
Because of this the build fails sometimes by running out of time.
This change reduces that to 5 minutes by:
* switching from curl to wget (which seems to have fewer dependencies)
* not installing gcc on ppc64le
* skipping tests that depend on gcc or other binutils
Change VersionAfterOrEqual(x, A, B) to return true for pre-releases of
version A.B. This is what it did before, it was broken when goversion
was changed to support the new version format.
* proc: make some type casts less counterintuitive
The interaction of type casts with load configuration is sometimes
counterintuitive. This commit changes the way it is performed so that
when converting slices to strings and vice versa the maximum size
corresponding to the target type is used (i.e. MaxStringLen when
converting slices to strings and MaxArrayValues when converting slices
to strings).
This doesn't fully solve the problem (conversions to []rune are
problematic and multiple chained type casts will still be confusing)
but removes the problem for the majority of practical uses.
Fixes#3595, #3539
This allows us to update this dependency on our schedule which is important because the module relies on manually updating the known list of Go versions to function correctly. Forking allows us to keep this up to date ourselves and possibly create a new system to prevent having to perform this manual step in the future.
Go1.22 has changed some line number assignments. The new line number
assignments are still valid however some tests in dap relied on them
being different and broke as a result. This commit fixes those tests
and makes them less brittle.
Also disables TestDebugStripped and TestDebugStripped2 temporarily on
1.22.
When using debugserver as a backend a manual stop request can end up
looking like an hardcoded breakpoint if the thread that receives the
stop request happens to be stopped right after a hardcoded breakpoint
(and the space between functions is filled with hardcoded breakpoints).
When creating hardcoded breakpoints we should ignore the trapthread if
a manual stop has been requested.
This problem made TestSetBreakpointWhileRunning and
TestSetFunctionBreakpointWhileRunning fail on macOS between 1.7% and 6%
of the time.
TestIssue1376 in rr_test.go used to pass accidentally, the stop when
the start of the recording was reached was mistaken for a hardcoded
breakpoint.
If the target process exits and receives a signal at the same time and
we receive the signal first we should call waitpid again to read the
target's exit status.
This also fixes a nil pointer dereference when trapWaitInternal returns
an error, this fix is probably incomplete but I wasn't able to
reproduce its circumstances after 30000 runs of TestIssue1101 to
properly address it.
This patch switches from using a forked version of one of the libraries
of goretk/gore to using the module directly. This is possible now that
certain functionality has been exposed / fixed within that module making
it usable for Delve.
The gdb remote serial protocol returns in several places a list of key
value pair in the form key1:value1;key2:value2;...;keyN:valueN.
We had ad-hoc parsers for this in three places, this commit
consolidates the parser in a single utility object.
Instead of having a different version for each architecture have a
single version that uses an architecture specific list of registers.
Also generalize it so that, if we want, we can extend the workaround to
other runtime functions we might want to call (for example the channel
send/receive functions).
We had a few checks left over for the TRAVIS variable that detected if
we were running under the TravisCI build system.
This variable hasn't been set since 2020.
Issue #3548 describes a bug in the compiler which was fixed by commit
505e50b. But this case wasn't covered by our current tests (obviously)
and the fix in the compiler looks accidental so it's worth adding a
test for it.
Fixes#3548
This patch adds support for listing and setting breakpoints on inlined functions within stripped binaries. It uses a forked version of `debug/gosym` copied from golang.org/x/vuln/internal/vulncheck/internal/gosym which adds support for parsing the inline tree of the pclntab section. Parsing this section requires knowing the offset of the "go:func.*" symbol, which is not present in stripped binaries via the ``.symtab` section so instead, we search the `.noptrdata` section which contains `runtime.moduledatap` which contains the value of that missing symbol, which we then can use to find the inline tree for a given function.
Given all this we parse the inline tree for each function we find, and then add that information the the appropriate `Function` contained in `bi.Functions`, using a relatively empty `Function` struct as what would be the abstract origin.
- fix TestRefreshCurThreadSelGAfterContinueOnceError and TestBadAccess
to work when debugserver has --unmask-signals
- when a fatal signal is received while singlestepping delay its
delivery until the subsequent continue, otherwise debugserver will get
stuck completely (fixes TestNilPtrDerefInBreakInstr)
We have used a goroutine to keep track of some of the expression
evaluation status across target resumes during call injections.
Now that the expression interpreter has been rewritten to use a stack
machine we can move what little state is left into the stack machine
and get rid of the goroutine-and-channel mechanism.
* proc: use stack machine to evaluate expressions
This commit splits expression evaluation into two parts. The first part (in
pkg/proc/evalop/evalcompile.go) "compiles" as ast.Expr into a list of
instructions (defined in pkg/proc/evalop/ops.go) for a stack machine
(defined by `proc.(*evalStack)`).
The second part is a stack machine (implemented by `proc.(*EvalScope).eval`
and `proc.(*EvalScope).evalOne`) that has two modes of operation: in the
main mode it executes inteructions from the list (by calling `evalOne`), in
the second mode it executes the call injection protocol by calling
`funcCallStep` repeatedly until it either the protocol finishes, needs more
input from the stack machine (to set call arguments) or fails.
This approach has several benefits:
- it is now possible to remove the goroutine we use to evaluate expression
and the channel used to communicate with the Continue loop.
- every time we resume the target to execute the call injection protocol we
need to update several local variables to match the changed state of the
target, this is now done at the top level of the evaluation loop instead of
being hidden inside a recurisive evaluator
- using runtime.Pin to pin addresses returned by an injected call would
allow us to use a more natural evaluation order for function calls, which
would solve some bugs #3310, allow users to inspect values returned by a
call injection #1599 and allow implementing some other features #1465. Doing
this with the recursive evaluator, while keeping backwards compatibility
with versions of Go that do not have runtime.Pin is very hard. However after
this change we can simply conditionally change how compileFunctionCall works
and add some opcodes.
* review round 1
* review round 2
Use the trampoline attribute to detect auto-generated code. This fixes
a bug where stepping into a method of a generic type called through an
interface will take the debugger into an auto-generated wrapper that
does not have a dictionary and using next will step out of the wrapper.
Fixes a bug reported on the #delve channel of the gophers slack server.
There is no benefit to having a small part of the freebsd backend
implemented in C, rather than using cgo. While here, add a missing
call to procstat_close and check the return value of
procstat_getpathname.
Thank you to everyone who contributed to this release:
@alexsaezm, @pgavlin, @archanaravindar, @aarzilli, @hyangah, @thechampagne, @javierhonduco, @andreimatei, @gocurr, @alexandear, @stefanhaller.
* enable func call injection on delve for ppc64le
* Function call injection on Delve/ppc64le, modified DWARF encoding and decoding for floating point registers to make floatsum test work
* Function call injection on Delve/ppc64le cleanup
* skip PIE tests for function call injection on other packages
* Address review comments
* accounted for additional skipped PIE tests for function call injection
* Code cleanup and undoing revert of previous commit
* Enable function call injection only on 1.22 and above and some cleanup
* additional cleanup, go fmt run
* Debug function call tests fail on ppc64le/PIE mode adjusted the backup_test_health.md file accordingly
The current implementation assumes a specific command line interface
for opening an editor at a specific location within the source file.
This patch updates for different formats, namely the one used by the
editor 'hx'.
* proc: correctly update local variables after continue
At various point during the execution of the call injection protocol
the process is resumed and the call injection goroutine could migrate
to a different thread, we must make sure to update our local variables
correctly after every point where the target program is resumed.
'fncall122debug_clean' on 'f469a0a5'.
* go.mod: update golang.org/x/tools
Go 1.22 broke golang.org/x/tools/packages
* cmd/dlv: disable TestStaticcheck with go1.22
Go 1.22 is not yet supported by staticcheck.