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.
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.
* 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/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.
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.
* 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.
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.
Delve represents registerized variables (fully or partially) using
compositeMemory, implementing proc.(*compositeMemory).WriteMemory is
necessary to make SetVariable and function calls work when Go will
switch to using the register calling convention in 1.17.
This commit also makes some refactoring by moving the code that
converts between register numbers and register names out of pkg/proc
into a different package.
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>
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.
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.
* proc,proc/*: move SelectedGoroutine to proc.Target, remove PostInitializationSetup
moves SelectedGoroutine, SwitchThread and SwitchGoroutine to
proc.Target, merges PostInitializationSetup with NewTarget.
* proc,proc/*: add StopReason field to Target
Adds a StopReason field to the Target object describing why the target
process is currently stopped. This will be useful for the DAP server
(which needs to report this reason in one of its requests) as well as
making pull request #1785 (reverse step) conformant to the new
architecture.
* proc: collect NewTarget arguments into a struct
* tests: misc test fixes for go1.14
- math.go is now ambiguous due to changes to the go runtime so specify
that we mean our own math.go in _fixtures
- go list -m requires vendor-mode to be disabled so pass '-mod=' to it
in case user has GOFLAGS=-mod=vendor
- update version of go/packages, required to work with go 1.14 (and
executed go mod vendor)
- Increased goroutine migration in one development version of Go 1.14
revealed a problem with TestCheckpoints in command_test.go and
rr_test.go. The tests were always wrong because Restart(checkpoint)
doesn't change the current thread but we can't assume that when the
checkpoint was taken the current goroutine was running on the same
thread.
* goversion: update maximum supported version
* Makefile: disable testing lldb-server backend on linux with Go 1.14
There seems to be some incompatibility with lldb-server version 6.0.0
on linux and Go 1.14.
* proc/gdbserial: better handling of signals
- if multiple signals are received simultaneously propagate all of them to the
target threads instead of only one.
- debugserver will drop an interrupt request if a target thread simultaneously
receives a signal, handle this situation.
* dwarf/line: normalize backslashes for windows executables
Starting with Go 1.14 the compiler sometimes emits backslashes as well
as forward slashes in debug_line, normalize everything to / for
conformity with the behavior of previous versions.
* proc/native: partial support for Windows async preempt mechanism
See https://github.com/golang/go/issues/36494 for a description of why
full support for 1.14 under windows is problematic.
* proc/native: disable Go 1.14 async preemption on Windows
See https://github.com/golang/go/issues/36494
* 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
Specifically, make sure that both DebugActiveProcess and
WaitForDebugEvent Windows APIs are executed on the same thread.
Otherwise WaitForDebugEvent fails with ERROR_INVALID_HANDLE as per its
documentation
https://docs.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-waitfordebugevent
'... Only the thread that created the process being debugged can call
WaitForDebugEvent. ...'
Fixes#1825
proc.Next and proc.Step will call, after setting their temp
breakpoints, curthread.SetCurrentBreakpoint. This is intended to find
if one of the newly created breakpoints happens to be at the same
instruction that curthread is stopped at.
However SetCurrentBreakpoint is intended to be called after a Continue
and StepInstruction operation so it will also detect if curthread is
stopped one byte after a breakpoint.
If the instruction immediately preceeding the current instruction of
curthread happens to:
1. have one of the newly created temp breakpoints
2. be one byte long
SetCurrentBreakpoint will believe that we just hit that breakpoint and
therefore the instruction should be repeated, and thus rewind the PC of
curthread by 1.
We should distinguish between the two uses of SetCurrentBreakpoint and
disable the check for "just hit" breakpoints when inappropriate.
Fixes#1656
The repository is being switched from the personal account
github.com/derekparker/delve to the organization account
github.com/go-delve/delve. This patch updates imports and docs, while
preserving things which should not be changed such as my name in the
CHANGELOG and in TODO comments.
This patch is a slight refactor to share more code used for genericprocess initialization. There will always be OS/backend specificinitialization, but as much as can be shared should be to preventduplicating of any logic (setting internal breakpoints, loading bininfo,etc).
Some libraries (for example steam_api64.dll) will send this exception
code to set the thread name on Microsoft VisualC.
In theory it should be fine to send the exception back to the target,
which is responsible for setting a handler for it, in practice in some
cases (steam_api64.dll) this will crash the program. So we'll mask it
instead.
Fixes#1383
Support for position independent executables (PIE) on the native linux
backend, the gdbserver backend on linux and the core backend.
Also implemented in the windows native backend, but it can't be tested
because go doesn't support PIE on windows yet.
Change the linux verison of proc/native and proc/gdbserial (with
debugserver) so that they let the target process use the terminal when
delve is launched in headless mode.
Windows already worked, proc/gdbserial (with rr) already worked.
I couldn't find a way to make proc/gdbserial (with lldb-server) work.
No tests are added because I can't think of a way to test for
foregroundness of a process.
Fixes#65
Conditional breakpoints with unmet conditions would cause next and step
to skip the line.
This breakpoint changes the Kind field of proc.Breakpoint from a single
value to a bit field, each breakpoint object can represent
simultaneously a user breakpoint and one internal breakpoint (of which
we have several different kinds).
The breakpoint condition for internal breakpoints is stored in the new
internalCond field of proc.Breakpoint so that it will not conflict with
user specified conditions.
The breakpoint setting code is changed to allow overlapping one
internal breakpoint on a user breakpoint, or a user breakpoint on an
existing internal breakpoint. All other combinations are rejected. The
breakpoint clearing code is changed to clear the UserBreakpoint bit and
only remove the phisical breakpoint if no other bits are set in the
Kind field. ClearInternalBreakpoints does the same thing but clearing
all bits that aren't the UserBreakpoint bit.
Fixes#844
While we are waiting for the process to exit in native.(*Process).Kill
we could receive queued exception events, those must be continued or
the wait will never finish.
* proc/native: make sure debugged executable can be deleted on windows
Delve opens debugged executable to read binary info it
contains, but it never closes the file. Windows will not
let you delete file that is opened. So close Process.bi
in Process.postExit, and actually call Process.postExit
from windows Process.Kill.
Also Windows sends some debugging events
(EXIT_PROCESS_DEBUG_EVENT event in particular) after Delve
calls TerminateProcess. The events need to be consumed by
debugger before debugged process will be released by
Windows. So call Process.waitForDebugEvent after
TerminateProcess in Process.Kill.
Fixes#398
* cmd/dlv: make TestIssue398 pass on darwin
* cmd/dlv: add comment for TestIssue398
* proc/native: wait for debuggee to exit before returning from windows Process.Kill
* proc/native: close process handle before returning from windows killProcess
* proc/native: remove not used Process.Process
While implementing the gdbserial backend everything was changed to call
Detach to "close" a process so that gdbserial could do its clean up in
a single place. However the native implementation of Detach does not
actually kill processes we launched.
Fixes#821