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
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>
* 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
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.
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.
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
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.
* 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.
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.
Changes Breakpoint to allow multiple overlapping internal breakpoints
on the same instruction address.
This is done by changing the Breakpoint structure to contain a list of
"breaklets", each breaklet has a BreakpointKind and a condition
expression, independent of the other.
A breakpoint is considered active if any of its breaklets are active.
A breakpoint is removed when all its breaklets are removed.
We also change the terminology "internal breakpoint" to "stepping
breakpoint":
HasInternalBreakpoints -> HasSteppingBreakpoints
IsInternal -> IsStepping
etc...
The motivation for this change is implementing watchpoints on stack
variables.
Watching a stack variable requires also setting a special breakpoint to
find out when the variable goes out of scope. These breakpoints can not
be UserBreakpoints because only one user breakpoint is allowed on the
same instruction and they can not be internal breakpoints because they
should not be cleared when a next operation is completed (they should
be cleared when the variable watch is cleared).
Updates #279
* 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.
The existing documentation was a little light on details. This patch
gives more insight into how the argument to this function is used and
interpreted.
* service/rpc2,service/debugger: more doc updates
Combine debugger.CreateBreakpoint documentation with the documentation
that already existed for the rpc2 server CreateBreakpoint method.
Also adds more contextual information for both the server and client
with links to debugger.CreateBreakpoint documentation.
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
Ensure that any command executed after the process we are trying to
debug prints a correct and consistent exit status.
Previously the exit code was being lost after the first time we printed
that a process has exited. Additionally, certain commands would print
the PID of the process and other would not. This change makes everything
more correct and consistent.
If the client supports paging, we allow them to fetch array and slice items in chunks that we assume will be of a reasonable size. For example, VS Code requests indexed variables in chunks of 100.
Fixesgolang/vscode-go#1518
* pkg/proc: implement support for hit count breakpoints
* update comment
* udpate hitcount comment
* update HitCond description
* add test for hit condition error
* respond to review
* service/dap: add support for hit count breakpoints
* use amendbps to preserve hit counts
* update test health doc
* fix failing test
* simplify hit conditions
* REmove RequestString, use name instead
* update backend_test_health.md
* document hit count cond
* fix tests
* service/dap: implement setFunctionBreakpoints request
* Fix the errors that would not allow func set
* use find locations instead of FindFunctionLocation
* add function breakpoint tests
* return after sending error response
* revert changes to debugger
* exclude regexp function names
* remove switch statement with one case
* remove ReadFile ambiguous test
* Remove TODO for multiple locs
* remove unnecessary setting of bp.Verified on error
* tighten condition for breakpoint name to match function breakpoint
* add tests for different loc types, add FindLocationSpec
* add test using base name of file
* make functionBreakpoint name a constant
* update stop reason to function breakpoint
* remove comment about optimizing onSetFunctionBreakpoints
* respond to review
* add comments to test
* change functionBpPrefix to const
* handle relative paths
* fix capabilites check
* update function breakpoint tests to check for failure
* use negative line number to determine which are errors
* service/dap: implement exception info
* remove adding additional thread
* Fix tests
* add exceptionInfo tests
* update comments
* map paths to client paths
* remove launch.json
* remove change to ConvertEvalScope
* correct name of supportsExceptionInfoRequest
* Add TODO for deleting output event
* Print Stack header to buffer
* Try to move resolving exception info to onExceptionInfoRequest
* save the error and return if it is the current thread
* rename thread to g
* findgoroutine returns goroutine
* clean up findgoroutine
* log errors
* remove output event
* fix grammar
We have some places where we use proc.ErrProcessExited and some places
that use &proc.ErrProcessExited, resulting in checks for process exited
errors occasionally failing on some architectures.
Uniform use of ErrProcessExited to the non-pointer version.
Fixes intermittent failure of TestStepOutPreservesGoroutine.
When restarting we must take care of setting breakpoint IDs correctly
so that enabled breakpoints do not end up having the same ID as a
disabled breakpoint, also we must make sure that breakpoints created
after restart will not get an ID already used by a disabled breakpoint.
* 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: serialize calls to Command API
Wait until the target process has resumed before accepting new calls to
Command. Before this if a 'continue' was immediately followed by a
'halt' the 'halt' could be processed before the 'continue'.
Fixes#1608Fixes#2216
* service/rpccommon: fix DeepSource issues
* Avoid double removal of temp binary
* Add back accidentally removed empty line
* Simplify regex
* Use unique build output directories in test cases
* Recover TestLaunchDebugRequest hidden logging and refine error check
* Special case access-denied error on Windows
* Remove special case for access denied on Windows
* Increase remove delay on Win
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
* proc/core: off-by-one error reading ELF core files
core.(*splicedMemory).ReadMemory checked the entry interval
erroneously when dealing with contiguous entries.
* terminal,service,proc/*: adds dump command (gcore equivalent)
Adds the `dump` command that creates a core file from the target process.
Backends will need to implement a new, optional, method `MemoryMap` that
returns a list of mapped memory regions.
Additionally the method `DumpProcessNotes` can be implemented to write out
to the core file notes describing the target process and its threads. If
DumpProcessNotes is not implemented `proc.Dump` will write a description of
the process and its threads in a OS/arch-independent format (that only Delve
understands).
Currently only linux/amd64 implements `DumpProcessNotes`.
Core files are only written in ELF, there is no minidump or macho-o writers.
# Conflicts:
# pkg/proc/proc_test.go
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.
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
* service/dap: add "panic" and "fatal error" as stopped reasons
The unrecovered panic and fatal throw breakpoints are not set by the
user. We now check for these special breakpoints and send appropriate
stopped reasons to the client.
* Add getter for StopReason
* Set threadID and stop reason correctly
If there is no selected goroutine, no goroutine ID should be set in
the stopped event.
The stopped reason can be better determined using the process
StopReason.
* Update panic breakpoint on next test to work with Go 1.13 runtime
When running panic.go with Go1.13, the next line that is stepped to
after panic('boom') is the defer function in the runtime package. The
unrecovered panic breakpoint is not hit until after several steps.
The test now steps until the breakpoint is hit, or the program terminates
without hitting the unrecovered panic breakpoint, in which case it fails.
* Skip breakpoint on next test in < Go 1.14
* Travis-CI: add ignorechecksum option to chocolatey command
Looks like a configuration problem on chocolatey's end.
* service/*: remove threadID argument of (*Debugger).PackageVariables
Which thread is used doesn't make any difference to the list of package
variables that is returned and this option was only ever used by an old
v1 API call.
* Support global variables
* Respond to review comments
* Clarify comment
* Add more details to test error messages
* Remove flaky main..inittask checks
* Rename globals flag to match vscode-go
* Normalize filepath with slash separator
* Improve handling for unknown package
* Tweak error message
* More refactoring, normalization and error details to deal with Win test failures
* Clean up optional launch args processing
* Add CurrentPackage to debugger and use instead of ListPackagesBuildInfo
Co-authored-by: Polina Sokolova <polinasok@users.noreply.github.com>
Move the conversion of some 'proc' types from service/debugger into
service/rpc1 and service/rpc2. The methods of
service/debugger.(*Debugger) are also used by service/dap which
requires these types to be converted differently and converting them
twice is inefficent and doesn't make much sense.
Updates #2161
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.
* terminal/command: Add 'reload' command
These changes add the 'reload' command, which allows us to rebuild the project
and start the debugging session again. Currently, if the project's code is
updated while debugging it, Delve shows the new source code, but it's still
running the old one. With 'reload', the whole binary is rebuilt, and the
process starts again.
Fixes#1551
* Remove unnecessary print
Changes to be committed:
modified: pkg/terminal/command.go
* Add tests and refactor the code
Changes to be committed:
modified: cmd/dlv/cmds/commands.go
modified: go.mod
modified: pkg/terminal/command.go
modified: service/config.go
modified: service/debugger/debugger.go
modified: service/test/integration2_test.go
* Fix typo in the comment
Changes to be committed:
modified: service/debugger/debugger.go
* Fix typo in the name of the variables
The variables are local therefore the capitalization is not needed
Changes to be committed:
modified: cmd/dlv/cmds/commands.go
* Call GoTestBuild
Also, remove the := to avoid redeclaration
* Change the Kind in the tests
Change from debugger.ExecutingGeneratedTest to
debugger.ExecutingGeneratedFile for consistency.
We are generating a real binary instead of a test
one so ExecutingGeneratedFile makes more sense here.
Changes to be committed:
modified: service/test/integration2_test.go
* Avoid breakpoints based on addresses
Changes to be committed:
modified: service/debugger/debugger.go
* Update the rebuild behaviour
There are a few cases where we can't rebuild the binary because we don't
know how it was build.
Changes to be committed:
modified: service/debugger/debugger.go
* Fix typos and update documentation
Changes to be committed:
modified: Documentation/cli/README.md
modified: pkg/terminal/command.go
modified: service/config.go
modified: service/debugger/debugger.go
* Fix typo
* Remove variables
They were added to the debugger.Config
* Rename variable
Rename Kind to ExecuteKind to make it more accurate
Changes to be committed:
modified: cmd/dlv/cmds/commands.go
modified: service/debugger/debugger.go
modified: service/test/integration2_test.go
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
* cmd/dlv,debugger: Improve dlv trace and trace command output
This patch improves the `dlv trace` subcommand output by reducing the
noise that is generated and providing clearer more concise information.
Also adds new tests closing a gap in our testing (we previously never
really tested this subcommand).
This patch also fixes the `dlv trace` REPL command to behave like the
subcommand in certain situations. If the tracepoint is for a function,
we now show function arguements and return values properly.
Also makes the overall output of the trace subcommand clearer.
Fixes#2027
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.
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
* *: Fix go vet struct complaints
* *: Fix struct vet issue on linux
* *: Ignore proc/native in go vet check
We have to do some unsafe pointer manipulation that will never make go
vet happy within the proc/native package. Ignore it for runs of go vet.
* proc: move defer breakpoint code into a function
Moves the code that sets a breakpoint on the first deferred function,
used by both next and StepOut, to its function.
* proc: implement reverse step/next/stepout
When the direction of execution is reversed (on a recording) Step, Next and
StepOut will behave similarly to their forward version. However there are
some subtle interactions between their behavior, prologue skipping, deferred
calls and normal calls. Specifically:
- when stepping backwards we need to set a breakpoint on the first
instruction after each CALL instruction, once this breakpoint is reached we
need to execute a single StepInstruction operation to reverse step into the
CALL.
- to insure that the prologue is skipped reverse next needs to check if it
is on the first instruction after the prologue, and if it is behave like
reverse stepout.
- there is no reason to set breakpoints on deferred calls when reverse
nexting or reverse stepping out, they will never be hit.
- reverse step out should generally place its breakpoint on the CALL
instruction that created the current stack frame (which will be the CALL
instruction immediately preceding the instruction at the return address).
- reverse step out needs to treat panic calls and deferreturn calls
specially.
* service,terminal: implement reverse step, next, stepout
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
Adds an optional scope prefix to the `regs` command which allows
printing registers for any stack frame (as long as they were somehow
saved). Issue #1838 is not yet to be closed since we are still not
recovering the registers of a segfaulting frame.
Updates #1838
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.
A significant amount of time is spent generating the string
representation for the proc.Registers object of each thread, since this
field is rarely used (only when the Registers API is called) it should
be generated on demand.
Also by changing the internal representation of proc.Register to be
closer to that of op.DwarfRegister it will help us implement #1838
(when Delve will need to be able to display the registers of an
internal frame, which we currently represent using op.DwarfRegister
objects).
Benchmark before:
BenchmarkConditionalBreakpoints-4 1 22292554301 ns/op
Benchmark after:
BenchmarkConditionalBreakpoints-4 1 17326345671 ns/op
Reduces conditional breakpoint latency from 2.2ms to 1.7ms.
Updates #1549, #1838
* pkg/proc: Introduce Target
* pkg/proc: Remove Common.fncallEnabled
Realistically we only block it on recorded backends.
* pkg/proc: Move fncallForG to Target
* pkg/proc: Remove CommonProcess
Remove final bit of functionality stored in CommonProcess and move it to
*Target.
* pkg/proc: Add SupportsFunctionCall to Target
Adds an API call that returns a list of packages contained in the
program and the files that were used to build them, and also a best
guess at which filesystem directory contained the package when it was
built.
This can be used by IDEs to map file paths if the debugging environment
doesn't match the build environment exactly.
Changes CreateBreakpoint to create a logical breakpoint when multiple
addresses are specified, FindLocation and the api.Location type to
return logical locations and the cli to support logical breakpoints.
Modifies FindFileLocation, FindFunctionLocation and LineToPC as well as
service/debugger to support inlining and introduces the concept of
logical breakpoints.
For inlined functions FindFileLocation, FindFunctionLocation and
LineToPC will now return one PC address for each inlining and one PC
for the concrete implementation of the function (if present).
A proc.Breakpoint will continue to represent a physical breakpoint, at
a single memory location.
Breakpoints returned by service/debugger, however, will represent
logical breakpoints and may be associated with multiple memory
locations and, therefore, multiple proc.Breakpoints.
The necessary logic is introduced in service/debugger so that a change
to a logical breakpoint will be mirrored to all its physical
breakpoints and physical breakpoints are aggregated into a single
logical breakpoint when returned.
Make the 'list' command succeed for file:line expressions that don't
map to any instruction.
Adds an argument to the FindLocations API call that makes FindLocations
return if the expression can be parsed, even if it doesn't end up
matching any instruction in debug_line.
Adds a '-r' option to the 'restart' command (and to the Restart API)
that re-records the target when using rr.
Also moves the code to delete the trace directory inside the gdbserial
package.
Add options to start a stacktrace from the values saved in the
runtime.g struct as well as a way to disable the stackSwitch logic and
just get a normal stacktrace.
* proc: allow simultaneous call injection to multiple goroutines
Changes the call injection code so that we can have multiple call
injections going on at the same time as long as they happen on distinct
goroutines.
* proc: fix EvalExpressionWithCalls for constant expressions
The lack of address of constant expressions would confuse EvalExpressionWithCalls
Fixes#1577
The location specified '<fnname>:0' could be used to set a breakpoint
on the entry point of the function (as opposed to locspec '<fnname>'
which sets it after the prologue).
Setting a breakpoint on an entry point is almost never useful, the way
this feature was implemented could cause it to be used accidentally and
there are other ways to accomplish the same task (by setting a
breakpoint on the PC address directly).
The initial implementation of the 'call' command required the
function call to be the root expression, i.e. something like:
double(3) + 1
was not allowed, because the root expression was the binary operator
'+', not the function call.
With this change expressions like the one above and others are
allowed.
This is the first step necessary to implement nested function calls
(where the result of a function call is used as argument to another
function call).
This is implemented by replacing proc.CallFunction with
proc.EvalExpressionWithCalls. EvalExpressionWithCalls will run
proc.(*EvalScope).EvalExpression in a different goroutine. This
goroutine, the 'eval' goroutine, will communicate with the main
goroutine of the debugger by means of two channels: continueRequest
and continueCompleted.
The eval goroutine evaluates the expression recursively, when
a function call is encountered it takes care of setting up the
function call on the target program and writes a request to the
continueRequest channel, this causes the 'main' goroutine to restart
the target program by calling proc.Continue.
Whenever Continue encounters a breakpoint that belongs to the
function call injection protocol (runtime.debugCallV1 and associated
functions) it writes to continueCompleted which resumes the 'eval'
goroutine.
The 'eval' goroutine takes care of implementing the function call
injection protocol.
When the expression is fully evaluated the 'eval' goroutine will
write a special message to 'continueRequest' signaling that the
expression evaluation is terminated which will cause Continue to
return to the user.
Updates #119
This change splits the BinaryInfo object into a slice of Image objects
containing information about the base executable and each loaded shared
library (note: go plugins are shared libraries).
Delve backens are supposed to call BinaryInfo.AddImage whenever they
detect that a new shared library has been loaded.
Member fields of BinaryInfo that are used to speed up access to dwarf
(Functions, packageVars, consts, etc...) remain part of BinaryInfo and
are updated to reference the correct image object. This simplifies this
change.
This approach has a few shortcomings:
1. Multiple shared libraries can define functions or globals with the
same name and we have no way to disambiguate between them.
2. We don't have a way to handle library unloading.
Both of those affect C shared libraries much more than they affect go
plugins. Go plugins can't be unloaded at all and a lot of name
collisions are prevented by import paths.
There's only one problem that is concerning: if two plugins both import
the same package they will end up with multiple definition for the same
function.
For example if two plugins use fmt.Printf the final in-memory image
(and therefore our BinaryInfo object) will end up with two copies of
fmt.Printf at different memory addresses. If a user types
break fmt.Printf
a breakpoint should be created at *both* locations.
Allowing this is a relatively complex change that should be done in a
different PR than this.
For this reason I consider this approach an acceptable and sustainable
stopgap.
Updates #865
Before doing anything check that the version of Go is compatible with
the current version of Delve.
This will improve the error message in the case that another change as
disruptive as Go1.11 dwarf compression, happens.
* *: use loglevel to control what gets logged instead of output redirection
This stops logrus from doing all the formatting just to discard it
immediately afterwards.
* logflags: replace default formatter of logrus
The default formatter of logrus emits logs in two different formats
depending on whether or not the output is going to a terminal. The
output format for non-terminals is indented to be machine readable, but
we mostly read logs ourselves and the excessive quoting makes that
format unreadable.
When outputting to terminals it uses ANSI escape codes unconditionally,
without checking whether the terminal it is connected to actually
supports colors.
This commit replaces the default formatter with a much simpler
formatter that always uses a more readable format, doesn't use colors
and places the key-value pairs at the beginning of the line (which is a
better match for how we use them).
* cmd/dlv: add command line options to redirect logs
Adds two options, --log-to-file and --log-to-fd, to redirect logs to a
file or to a file descriptor.
When one of those two options is specified the "API server listening
at:" message will also be redirected to the specified file/file
descriptor.
This allows clients that want to use the "API server listening at:"
message to do so even if they want to redirect the target's stdout to
another file or device.
Implements #1179, #1523
Adds initial support for plugins, this is only the code needed to keep
track of loaded plugins on linux (both native and gdbserial backend).
It does not actually implement support for debugging plugins on linux.
Updates #865