Commit Graph

382 Commits

Author SHA1 Message Date
Derek Parker
4abf4f1c1f pkg/proc: Rename proc.go -> target_exec.go 2020-03-25 17:45:12 +01:00
Derek Parker
ccd438c65f pkg/proc: Move proc exec funcs to Target methods 2020-03-25 17:45:12 +01:00
Alessandro Arzilli
8bb93e9ae1
proc/gdbserial,debugger: allow clients to stop a recording (#1890)
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
2020-03-24 09:09:28 -07:00
Derek Parker
475551cf3d pkg/proc: Reset time after continue in benchmarks
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.
2020-03-24 09:48:34 +01:00
Derek Parker
c4fd80fcd0 pkg/proc: Clean up proc.go
This patch moves out unrelated types, variables and functions from
proc.go into a place where they make more sense.
2020-03-24 09:45:29 +01:00
Alessandro Arzilli
112049176f
proc: fix switch to goroutine stack (#1948)
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.
2020-03-20 11:32:41 -07:00
Alessandro Arzilli
7cd12c34fd
proc,dwarf: cache debug.Entry objects (#1931)
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
2020-03-20 10:23:10 -07:00
Derek Parker
f05ce09473 *: Fix use of deprecated functionality 2020-03-20 09:05:14 +01:00
Alessandro Arzilli
0cfd52787f
proc/gdbserial: add logging when Thread.Location will fail (#1937)
Add logging for Issue #1927. The bug happens during the call to
api.ConvertThread, returning an error will not suffice since
ConvertThread will not surface it.

Updates #1927
2020-03-19 12:28:27 -07:00
Alessandro Arzilli
e1cfd72795
proc: fix bad cached goroutines after a call injection (#1926)
Inserts a call to ClearAllGCache into stepInstructionOut so that cached
goroutine state is not inconsistent after an injected function call.\

Fixes #1925
2020-03-19 12:27:31 -07:00
Derek Parker
731a7fc125 *: consolidate appends where possible 2020-03-19 10:25:09 +01:00
chainhelen
65d7f5c65f
pkg/proc: Prevent program crash when called meanless expression (#1934)
If we call one expression which is the fake method of meanless
string, `delve` will panic. Strengthen the inspection of boundary
conditions when supporting function calls on non-struct types.

Update: #1871
2020-03-18 09:26:24 -07:00
Derek Parker
ad75f78c4e
*: Fix go vet complaints (#1935)
* *: 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.
2020-03-18 09:25:32 -07:00
Alessandro Arzilli
1a9e38aa0c
proc,terminal: Implement reverse step, next and stepout (#1785)
* 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
2020-03-11 15:40:41 -07:00
Alessandro Arzilli
134fcb186e
proc: cache result of GetG (#1921)
Benchmark before:

BenchmarkConditionalBreakpoints-4   	       1	7031242832 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	5282482841 ns/op

Conditional breakpoint evaluation latency: 0.70ms -> 0.52ms

Updates #1549
2020-03-10 12:48:46 -07:00
Alessandro Arzilli
9f97edb0bb
proc,proc/*: add StopReason field to Target (#1877)
* 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
2020-03-10 12:27:38 -07:00
chainhelen
f3a191cd73
pkg/proc,service: support linux/386 (#1884)
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
2020-03-10 09:34:40 -07:00
Alessandro Arzilli
e9b2da17cb
proc/native/linuc: Better native.Process.stop performance (#1874)
* proc/native/linux: only set breakpoints on threads that receive SIGTRAP

* proc/native/linux: do not call (*Thread).Stopped inside (*Process).stop

(*Thread).Stopped is slow because it needs to open, read and parse a
file in /proc, we don't actually need to do that, we can just rely on
the value of Thread.os.running.

Benchmark before:

BenchmarkConditionalBreakpoints-4              1        12476166303 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	10403533675 ns/op

Conditional breakpoint evaluation: 1.24ms -> 1ms

Updates #1549
2020-03-09 10:15:45 -07:00
Derek Parker
12d9b8069c pkg/proc: Add doc comments to Target Restart and Detach 2020-03-06 14:21:17 +01:00
a
23dc9f92c2 proc/gdbserial: disable async preemption on macOS
Disables async preemption on macOS

Fixes #1905
2020-03-02 12:51:26 -08:00
Josh Stone
d0d2d47885 proc/native/linux: try to use process_vm_readv/writev
This change adds `ProcessVmRead` and `ProcessVmWrite` wrappers around
the syscalls `process_vm_readv` and `process_vm_writev`, available since
Linux 3.2. These follow the same permission model as `ptrace`, but they
don't actually require being attached, which means they can be called
directly from any thread in the debugger. They also use `iovec` to write
entire blocks at once, rather than having to peek/poke each `uintptr`.

These wrappers are used in `Thread.ReadMemory` and `WriteMemory`, still
falling back to `ptrace` if that fails for any reason.  Notably,
`process_vm_writev` respects memory protection, so it can't modify
read-only memory like `ptrace`. This frequently occurs when writing
breakpoints in read-only `.text`, so to avoid a lot of wasted `EFAULT`
calls, we only try `process_vm_writev` for larger writes.
2020-02-29 08:25:31 -08:00
chainhelen
7560c33819
pkg,service: Use PCToFunc instead of PCToLine if it only needs func (#1894) 2020-02-25 21:01:37 -08:00
Alessandro Arzilli
d925f6b719
proc,service: allow printing registers for arbitrary frames (#1875)
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
2020-02-24 10:47:02 -08:00
Alessandro Arzilli
ade20a4d4d
proc/native: better error message when building on unsupported systems (#1883)
As we rearrange the code and the Go compiler changes the error message
returned by the compiler on unsupported architectures will change too,
making it un-googlable. Since the error message tends to be rather
obscure too this regularly confuses newbies.

This is an effort to make the error message for unsupported GOOS/GOARCH
combinations the same across all unsupported combinations and to make
it more user friendly.

Directories containing Go source code are supposed to contain a single
package. This property happens to be checked by cmd/go itself so it
will happen even before the syntax is fully checked and therefore has a
high probability of being the first (and only) error message being
print.

Here we take advantage of this by adding to the pkg/proc/native
directory a file with a bad package line that only gets compiled in on
unsupported GOOS/GOARCH combinations.

At present the error message for compiling Delve on unsupported systems
will be:

service/debugger/debugger.go:21:2: found packages native (proc.go) and your_operating_system_and_architecture_combination_is_not_supported_by_delve (support_sentinel.go) in $PATH_TO_DELVE/pkg/proc/native
2020-02-24 09:39:51 -08:00
chainhelen
d0b21fbbf2 pkg/proc: Fix ThreadId when ErrNoGoroutine on g0 stack in GetG
Avoid always showing `no G executing on thread 0` when ErrNoGoroutine on
g0 stack in GetG.
2020-02-24 09:32:27 -08:00
Alessandro Arzilli
fcba291125
proc: remove support for parsing interfaces in Go 1.8 and earlier (#1878)
Go 1.8 has been out of date for a while and the code to support it is
potentially dangerous if a future version of Go removes the runtime
types from debug_info and also changes their representation.
2020-02-20 10:52:48 -08:00
Derek Parker
4136512ef3 pkg/proc: Allow function calls on non-struct types
Removes the restriction that the DWARF type for the receiver of a method
must be a TypeDef. This seems reasonable in practice, but it turns out
Go DWARF does not consider

```
type X int
```

to be a typedef. This patch also allows for calling a method where the
receiver is not used or passed in, such as:

```
func (_ X) Method() { println("why") }
```
2020-02-20 10:31:48 +01:00
chainhelen
4f04b81c28
pkg/proc: Judge the validity of addr ranges when disasm. (#1872)
Avoid panic if start addr is greater than end addr when disasm.
2020-02-19 08:46:03 -08:00
ossdev07
a83d1c1409
proc/core: implementing coredump functionality for ARM64 (#1774)
* proc/native: optimize native.status through buffering (#1865)

Benchmark before:

BenchmarkConditionalBreakpoints-4              1        15649407130 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	14586710018 ns/op

Conditional breakpoint evaluation 1.56ms -> 1.45ms

Updates #1549

* proc/core: Review Comments Incorporated

Signed-off-by: ossdev07 <ossdev@puresoftware.com>

Co-authored-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
2020-02-17 09:29:17 -08:00
Alessandro Arzilli
ecea2e1814
proc: optimize parseG (#1866)
runtime.g is a large and growing struct, we only need a few fields.
Instead of using loadValue to load the full contents of g, cache its
memory and then only load the fields we care about.

Benchmark before:

BenchmarkConditionalBreakpoints-4              1        14586710018 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	12476166303 ns/op

Conditional breakpoint evaluation: 1.45ms -> 1.24ms

Updates #1549
2020-02-17 09:27:56 -08:00
Alessandro Arzilli
c272212baa
proc/native: optimize native.status through buffering (#1865)
Benchmark before:

BenchmarkConditionalBreakpoints-4              1        15649407130 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	14586710018 ns/op

Conditional breakpoint evaluation 1.56ms -> 1.45ms

Updates #1549
2020-02-15 11:55:19 -08:00
Derek Parker
a277b15def proc/gdbserial: Reload thread registers on demand
Instead of reloading the registers for every thread every time the
process executes, reload the registers on demand for individual threads
and memoize the result.
2020-02-13 18:30:32 +01:00
Alessandro Arzilli
5b4f4a81b1
proc: do not load g0 until it's needed when stacktracing (#1863)
The stacktrace code occasionally needs the value of g.m.g0.sched.sp to
switch stacks. Since this is only needed rarely and calling parseG is
relatively expensive we should delay doing it until we know it will be
needed.

Benchmark before:

BenchmarkConditionalBreakpoints-4              1        17326345671 ns/op

Benchmark after:

BenchmarkConditionalBreakpoints-4   	       1	15649407130 ns/op

Reduces conditional breakpoint latency from 1.7ms to 1.56ms.

Updates #1549
2020-02-13 09:12:59 -08:00
Alessandro Arzilli
b9d0ddd82c
proc: only format registers value when it's necessary (#1860)
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
2020-02-12 13:31:48 -08:00
chainhelen
bd279cb9da
pkg/proc: optimize code for supporting different arch in the future. (#1849) 2020-02-10 17:32:50 -08:00
Alessandro Arzilli
0741d3e57f
*: Go 1.14 support branch (#1727)
* 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
2020-02-10 17:31:54 -08:00
chainhelen
f925d3c8d7
pkg/proc: remove meanless code in dwarf_expr_test.go. (#1850) 2020-01-29 16:12:44 +01:00
aarzilli
fc3e01bb5b tests: add benchmark for conditional breakpoints 2020-01-28 11:32:53 +01:00
aarzilli
279c29a37c proc: remove CX method from proc.Registers
It is not used anymore besides internally by the proc/gdbserial
backend.
2020-01-28 11:32:53 +01:00
chainhelen
dee267b68b pkg/proc: fix typo in the comment of PtraceGetFpRegset (#1848) 2020-01-27 10:20:56 +01:00
chainhelen
ff5734a0d8 pkg: fix abbreviation of Flag Register on amd64 (#1845) 2020-01-22 11:35:11 -08:00
Derek Parker
94a20d57da
pkg/proc: Introduce Target and remove CommonProcess (#1834)
* 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
2020-01-21 12:41:24 -08:00
hengwu0
3f7571ec30 proc: implement stacktrace of arm64 (#1780)
* proc: separate amd64-arch code

separate amd64 code about stacktrace, so we can add arm64 stacktrace code.

* proc: implemente stacktrace of arm64

* delve now can use stack, frame commands on arm64-arch debug.

Co-authored-by: tykcd996 <tang.yuke@zte.com.cn>
Co-authored-by: hengwu0 <wu.heng@zte.com.cn>

* test: remove skip-code of stacktrace on arm64

* add LR DWARF register and remove skip-code for fixed tests

* proc: fix the Continue command after the hardcoded breakpoint on arm64

Arm64 use hardware breakpoint, and it will not set PC to the next instruction like amd64. We should move PC in both runtime.breakpoints and hardcoded breakpoints(probably cgo).

* proc: implement cgo stacktrace on arm64

* proc: combine amd64_stack.go and arm64_stack.go file

* proc: reorganize the stacktrace code

* move SwitchStack function arch-related
* fix Continue command after manual stop on arm64
* add timeout flag to make.go to enable infinite timeouts

Co-authored-by: aarzilli <alessandro.arzilli@gmail.com>
Co-authored-by: hengwu0 <wu.heng@zte.com.cn>

Co-authored-by: tykcd996 <56993522+tykcd996@users.noreply.github.com>
Co-authored-by: Alessandro Arzilli <alessandro.arzilli@gmail.com>
2020-01-21 09:11:20 -08:00
Dmitry Neverov
7fe81ca1d6 cache computed labels 2020-01-21 09:08:36 -08:00
Dmitry Neverov
ca3fe88899 proc,service: expose goroutine pprof labels in api
Labels can help in identifying a particular goroutine during debugging.

Fixes #1763
2020-01-21 09:08:36 -08:00
aarzilli
9af1eac341 proc: cache goroutine objects
Adds a cache mapping goroutine IDs to goroutine objects, this allows
speeding up FindGoroutine and makes commands like 'goroutines -t' not
be accidentally quadratic in the number of goroutines.
2020-01-16 10:14:14 -08:00
Alex Brainman
db88d2e91d pkg/prog: Make sure Attach is executed on a single thread
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
2020-01-13 09:44:47 -08:00
aarzilli
adb1746c60 proc: fix inlined stack reading for midstack inlined calls
Due to a bug in the Go compiler midstack inlined calls do not report
their ranges correctly. We can't check if an address is in the range of
a DIE by simply looking at that DIE's range, we should also recursively
check the DIE's children's ranges.

Also fixes the way stacktraces of midstack inlined calls are reported
(they used to be inverted, with the deepest inlined stack frame
reported last).

Fixes #1795
2020-01-10 09:04:48 +01:00
aarzilli
a8606afb0b proc,service: return build informations for each package
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.
2020-01-09 20:19:02 +01:00
aarzilli
0e0d689246 dwarf/line: make LineToPCIn behave like LineToPC for lines without stmt
When a line has instructions associated but none of them have is_stmt
set LineToPC and LineToPCIn should behave in the same way.

Fixes #1817
2020-01-09 09:41:44 -08:00