Commit Graph

297 Commits

Author SHA1 Message Date
Heschi Kreinick
8954858ee8 proc: round TLS segment size to its alignment (#1682)
The fix for #1428 was buggy, partly because I communicated poorly. Sorry
about that.

The size of the TLS segment should be padded such that TLS addresses
are congruent in the file to where they will end up memory, i.e.
(tlsoffset%align) == (vaddr%align). In most cases, vaddr will be aligned
and it won't matter, but if not then simply aligning the end of the
segment is incorrect. This should be right.

(For the record, the current rounding logic is working in bits, but
PtrSize is in bytes, so it wasn't working as originally intended
either.)
2019-09-04 09:01:53 -07:00
Alessandro Arzilli
a3e884e55c proc: discard variables with address 0 in disassembly sym lookup (#1668)
They are irrelevant and confusing.
2019-08-14 08:58:27 -07:00
Alessandro Arzilli
327fbdbd44 tests: remove duplicate code (#1669) 2019-08-14 08:57:05 -07:00
Alessandro Arzilli
4779218a83 proc/gdbserial: reset thread updater in step loop (#1665)
threadUpdater needs to be reset before every possible use.

Fixes #1659
2019-08-13 11:14:47 -07:00
pjot726
a621034bcf Edited to fix issue #1071 (#1664) 2019-08-13 11:13:56 -07:00
David Chase
440aa31bc6 proc: add *Function.PrologueEndPC to support optargorder tool (#1663)
Intent here is to bring optargorder up to date with delve
and keep it in sync (and to use optargorder to help monitor
compiler output for debugging quality regressions).
2019-08-13 11:13:28 -07:00
Alessandro Arzilli
3b0c886598 proc: next/step/stepout restarts thread from wrong instruction (#1657)
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
2019-08-12 15:11:19 -07:00
Alessandro Arzilli
c441330822 proc: remove (*EvalScope).globalFor (#1658) 2019-08-11 13:56:16 -07:00
Derek Parker
f0a9031969 pkg/proc: Move EvalScope methods, cleanup others
Moves EvalScope methods to the proper file and organizes everything
together. Also makes some EvalScope methods no longer methods and just
pure functions.
2019-08-10 14:03:12 +02:00
Derek Parker
094915e4aa pkg/proc: Drop state from BinaryInfo
Remove `initialized` member in favor of just deriving the information it
represented.
2019-08-10 14:03:12 +02:00
Derek Parker
b87813e177 pkg/proc: Remove extra struct members in BinaryInfo 2019-08-10 14:03:12 +02:00
Derek Parker
1b9ae4188d pkg/proc: Consolidate BinaryInfo/Image methods
The methods for the BinaryInfo and Image structs were spread around in
multiple files. This patch just brings them all under one file.
2019-08-10 14:03:12 +02:00
Derek Parker
9963458d77 pkg/proc: Refactor Disassemble 2019-08-10 14:03:12 +02:00
Derek Parker
583d335ffe pkg/proc: Untangle Arch from G struct
More untangling. Arch doesn't actually need to know anything about a
Goroutine.
2019-08-09 18:15:44 +02:00
Derek Parker
2de4930ad1 pkg/proc: Avoid passing BinaryInfo when not needed
This is going towards untangling proc in order to clean it up.
2019-08-09 18:15:44 +02:00
Derek Parker
a3d530bbd4 pkg/proc: Refactor AMD64 struct
Cleanup some unused members.
2019-08-09 18:15:44 +02:00
Alessandro Arzilli
c9c455cc38 cmd/dlv: actually disable C compiler optimizations when building (#1647)
* proc: fix stacktraces when a SIGSEGV happens during a cgo call

When a SIGSEGV happens in a cgo call (for example as a result of
dereferencing a NULL pointer) the stack layout will look like this:

(system stack) runtime.fatalthrow
(system stack) runtime.throw
(system stack) runtime.sigpanic
(system stack) offending C function
... other C functions...
(system stack) runtime.asmcgocall
(goroutine stack) call inside cgo

The code in switchStack would switch directly from the
runtime.fatalthrow frame to the first frame in the goroutine stack,
hiding important information.

Disable this switch for runtime.fatalthrow and reintroduce the check
for runtime.mstart that existed before this version of the code was
implemented in commit 7bec20.

This problem was reported in comment:
https://github.com/go-delve/delve/issues/935#issuecomment-512182533

* cmd/dlv: actually disable C compiler optimizations when building
2019-08-01 16:31:50 -07:00
Alessandro Arzilli
67b6d4b9c9 travis-ci: fix dwz test problems (#1648)
For some reason the version of dwz in Travis-CI now fails to run on Go
binaries. Ignore the particular error.
2019-07-31 13:09:00 -07:00
Derek Parker
f4eaad69d9
*: Add .cirrus.yml for FreeBSD testing (#1639)
* *: Add .cirrus.yml for FreeBSD testing

* *: run go mod tidy

* service/test: prefer 127.0.0.1 over localhost

* dwarf/line: fix TestDebugLinePrologueParser

* vendor: rerun go mod vendor
2019-07-30 08:38:25 -07:00
Alessandro Arzilli
b65882a588 proc: ignore DW_TAG_inlined_subroutine entries without abstract origin (#1637)
GCC produces DW_TAG_inlined_subroutine entries without a
DW_AT_abstract_origin attribute.
From the bug report:

 <1><1fe6c7c>: Abbrev Number: 41 (DW_TAG_subprogram)
    <1fe6c7d>   DW_AT_external    : 1
    <1fe6c7d>   DW_AT_name        : (indirect string, offset: 0x485814): MultiGetImpl
    (omissis)
 <2><1fe6c9e>: Abbrev Number: 65 (DW_TAG_inlined_subroutine)
    <1fe6c9f>   DW_AT_low_pc      : 0x311023a
    <1fe6ca7>   DW_AT_high_pc     : 0x5
    <1fe6caf>   DW_AT_call_file   : 10
    <1fe6cb0>   DW_AT_call_line   : 1690
 <2><1fe6cb2>: Abbrev Number: 20 (DW_TAG_inlined_subroutine)
    <1fe6cb3>   DW_AT_abstract_origin: <0x1ffb534>
    <1fe6cb7>   DW_AT_entry_pc    : 0x311023f
    <1fe6cbf>   DW_AT_ranges      : 0xe9bf20
    <1fe6cc3>   DW_AT_call_file   : 10
    <1fe6cc4>   DW_AT_call_line   : 1690

Inlined subroutine at 1fe6c9e doesn't have abstract origin, a name or a
declaration location. It's unclear whether this is in-standard and what
it even means.

Let's ignore it.

Fixes #1636
2019-07-26 11:24:35 -07:00
Alessandro Arzilli
dcc1030d18 gdbserial: propagate signals to target while stepping (#1624)
Propagate signals when stepping because debugserver will report them,
from the issue:

2019-07-11T16:31:25+02:00 debug layer=gdbconn <- $z0,105525d,1#c9
2019-07-11T16:31:25+02:00 debug layer=gdbconn -> $OK#00
2019-07-11T16:31:25+02:00 debug layer=gdbconn <- $vCont;s:c41c3#50
2019-07-11T16:31:25+02:00 debug layer=gdbconn -> $T1cthread:c41c3;threads:c41c3,c41d7,c41d8,c41d9,c41da;thread-pcs:105525d,7fffc464bf46,7fffc464bbf2,7fffc464bbf2,7fffc46...
2019-07-11T16:31:25+02:00 debug layer=gdbconn <- $Z0,105525d,1#a9
2019-07-11T16:31:25+02:00 debug layer=gdbconn -> $OK#00

in this case we request a single step on thread c41c3 but debugserver
reports instead a signal (in this case SIGWINCH).

Fixes #1610
2019-07-23 14:42:21 -07:00
Alessandro Arzilli
7d25f6eb97 proc/native/linux: call postExit when process is killed by SIGINT (#1622)
If we return ErrProcessExited we should also set exited to true.
2019-07-17 15:52:28 -07:00
Alessandro Arzilli
29a058ee7e proc: flag variables that have a 'fake' address (#1619)
Add variables flag to mark variables that are allocated on a register
(and have no address) and variables that we read as result of a
function call (and are allocated on a stack that no longer exists when
we show them to the user).
2019-07-16 13:12:16 -07:00
Alessandro Arzilli
158fb7bfac proc: increase maximum string length when loading string for binary ops (#1620)
Increases the maximum string length from 64 to 1MB when loading strings
for a binary operator, also delays the loading until it's necessary.

This ensures that comparison between strings will always succeed in
reasonable situations.

Fixes #1615
2019-07-16 13:11:35 -07:00
Robert Ayrapetyan
df65be43ae *: FreeBSD initial support (#1480)
* FreeBSD initial support

* first code review fixes

* regs slice upd

* execPtraceFunc wrap

* disabled concurrency tests
fixed kill() issue

* disabled concurrency tests
fixed kill() issue

* cleanup vendor related code

* cleanup ptrace calls

* vendoring latest changes

* Revert "vendoring latest changes"

This reverts commit 833cb87b

* vendoring latest changes

* requested changes
2019-07-12 18:28:04 -07:00
Alessandro Arzilli
a8b8f30d39 godwarf: support recursive types involving C qualifiers and typedefs (#1603)
Backports debug/dwarf commit: 535741a69a1300d1fe2800778b99c8a1b75d7fdd
CL: https://go-review.googlesource.com/18459

The x/debug/dwarf that we used for dwarf/godwarf/type.go was forked
from debug/dwarf long before this commit.

Original description:

    Currently readType simultaneously constructs a type graph and resolves
    the sizes of the types. However, these two operations are
    fundamentally at odds: the order we parse a cyclic structure in may be
    different than the order we need to resolve type sizes in. As a
    result, it's possible that when readType attempts to resolve the size
    of a typedef, it may dereference a nil Type field of another typedef
    retrieved from the type cache that's only partially constructed.

    To fix this, we delay resolving typedef sizes until the end of the
    readType recursion, when the full type graph is constructed.

Fixes #1601
2019-07-08 10:24:56 -07:00
dpapastamos
116b9631dc gdbserial: Fix go vet warnings (#1594) 2019-07-01 11:10:34 -07:00
Alessandro Arzilli
dd4fd5dc9c proc: allow simultaneous call injection to multiple goroutines (#1591)
* 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
2019-06-30 10:44:30 -07:00
Alessandro Arzilli
55eed318fd Go 1.13 support (#1546)
* tests: fix tests for Go 1.13

- Go 1.13 doesn't autogenerate init functions anymore, tests that
  expected that now fail and should be skipped.
- Plugin tests now need -gcflags'all=-N -l' now, we were probably
  getting lucky with -gcflags='-N -l' before.

* proc: allow signed integers as shift counts

Go1.13 allows signed integers to be used as the right hand side of a
shift operator, change eval to match.

* goversion: update maximum supported version

* travis: force Go to use vendor directory

Travis scripts get confused by "go: downloading" lines, the exact
reason is not clear. Testing that the vendor directory is up to date is
a good idea anyway.
2019-06-30 10:34:47 -07:00
David Chase
a25d2a2b24 proc: added *BinaryInfo.AllPCsForFileLine for faster bulk queries (#1592)
Support for bulk queries makes the DWARF quality checker
(github.com/dr2chase/dwarf-goodness/cmd/dwarf-goodness)
run much more efficiently (replace quadratic cost with
linear).
2019-06-27 19:39:15 -07:00
Alessandro Arzilli
7afda8dbe0 proc,service: remove support for locspec '<fnname>:0' (#1588)
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).
2019-06-25 13:50:05 -07:00
Alessandro Arzilli
a7c2d837d5 proc: add LocationCover method to BinaryInfo (#1573)
Also fixes findCompileUnitForOffset which was broken in some edge cases
(when looking up an offset inside the last child of the compilation
unit) which don't happen in normal executables (we only look up types, and those
are always direct childs of compile units).
2019-06-24 08:02:14 -07:00
Alessandro Arzilli
79ad269bbb proc: support setting string values when it requires an allocation (#1548)
Allow changing the value of a string variable to a new literal string,
which requires calling runtime.mallocgc to allocate the string into the
target process.

This means that a command like:

    call f("some string")

is now supported.

Additionally the command:

    call s = "some string"

is also supported.

Fixes #826
2019-06-17 09:51:29 -07:00
Derek Parker
b9bcd979d5 proc/linutil: Fix register bitmasks
The bitmasks for transforming a 64-bit register into it's lower-bit
counterparts (e.g. RAX -> EAX -> AX -> AH/AL) were incorrect. This patch
fixes the bitmasks and adds an additional test.
2019-06-16 09:35:14 +02:00
Alessandro Arzilli
cce377066a proc: support childless compile units in loadDebugInfoMaps (#1574)
Childless compile units would confuse loadDebugInfoMaps.
No test because I don't know what causes go to invoke GNU As in such a
way that it produces a childless compile unit.

Fixes #1572
2019-06-11 15:13:27 -07:00
Alessandro Arzilli
2d6d016bf1 proc: fix panic when calling Ancestors on a parked goroutine (#1570)
Fixes #1568
2019-06-03 10:41:33 -07:00
Alessandro Arzilli
215e13e81b proc: simplify partial unit support (#1565)
Instead of reading partial units as we see them skip them entirely and
then re-read them when they are imported, directly into the destination
compile unit.

This avoids a lot of duplicate code in the loadDebugInfoMaps function
and will simplify implementing logical breakpoints and support for the
new DW_AT_go_package_name attribute added in Go 1.13.
2019-05-31 09:08:20 -07:00
tschundler
9076056c70 proc: Less confusing error message for requesting break on blank line. (#1556)
The current wording is confusing - the file exists and the line exists, so what is the problem? I suspect this ambiguity is behind #1496 and likely others.

Also I updated the style to return values like the rest of the code in the file, which is also more readable (IMO and per https://github.com/golang/go/wiki/CodeReviewComments#named-result-parameters)
2019-05-30 08:11:21 -07:00
Alessandro Arzilli
60830c2b1d More Function Calls, parts 2 (#1504)
* proc: support nested function calls

Changes the code in fncall.go to support nested function calls.

This changes delays argument evaluation until after we have used
the call injection protocol to allocate an argument frame. When
evaluating the parse tree of an expression we'll initiate each
function call we find on the way down and then complete the function
call on the way up.

For example. in:

	f(g(x))

we will:

1. initiate the call injection protocol for f(...)
2. progress it until the point where we have space for the arguments
   of 'f' (i.e. when we receive the debugCallAXCompleteCall message
   from the target runtime)
3. inititate the call injection protocol for g(...)
4. progress it until the point where we have space for the arguments
   of 'g'
5. copy the value of x into the argument frame of 'g'
6. finish the call to g(...)
7. copy the return value of g(x) into the argument frame of 'f'
8. finish the call to f(...)

Updates #119

* proc: bugfix: closure addr was wrong for non-closure functions
2019-05-30 08:08:37 -07:00
Justin Clift
6f258d91a5 proc: trivial typo fix (#1561) 2019-05-30 08:02:27 -07:00
Alessandro Arzilli
04834a781a proc: save location expr and decl line for escaped variables (#1553)
Copy the location expression and declaration line of escaped variables
when auto-dereferencing them.
2019-05-23 13:07:13 -07:00
Alessandro Arzilli
c30a333f7b proc: allow function calls to appear inside an expression (#1503)
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
2019-05-09 08:29:58 -07:00
Alessandro Arzilli
f3b149bda7 proc: support debugging plugins (#1414)
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
2019-05-08 14:06:38 -07:00
Alessandro Arzilli
71a7fe04d9 proc/test: fix flakyness of TestCallConcurrent (#1543)
Remove the breakpoint set in TestCallConcurrent so that it doesn't
interfere with the call injection protocol.
The fact that it can is a bug but that bug is better addressed after
PRs #1503 and #1504 are merged, this keeps tests happy in the meantime.

Fixes #1542
2019-05-02 09:15:18 -07:00
Alessandro Arzilli
2cadddd787 proc: Update map reading code for Go 1.12 (#1532)
Go 1.12 introduced a change to the internal map representation where
empty map cells can be marked with a tophash value of 1 instead of just
0.

Fixes #1531
2019-04-26 10:23:43 -07:00
Alessandro Arzilli
0b3c7d80cd proc/native: fix target program crash caused by call injection (linux) (#1538)
RestoreRegisters on linux would also restore FS_BASE and GS_BASE, if
the target goroutine migrated to a different thread during the call
injection this would result in two threads of the target process
pointing to the same TLS area which would greatly confuse the target
runtime, leading to fatal panics with nonsensical stack traces.

Other backends are unaffected:

- native/windows doesn't store the TLS in the same CONTEXT struct as
  the other register values.
- native/darwin doesn't support function calls (and wouldn't store the
  TLS value in the same struct)
- gdbserial/rr doesn't support function calls (because it's a
  recording)
- gsdbserial/lldb extracts the value of TLS by executing code in the
  target process.
2019-04-25 09:45:37 -07:00
aarzilli
9826531597 proc,debugger,terminal: read goroutine ancestors
Add options to the stack command to read the goroutine ancestors.
Ancestor tracking was added to Go 1.12 with CL:
https://go-review.googlesource.com/c/go/+/70993/

Implements #1491
2019-03-28 13:55:32 +01:00
Alessandro Arzilli
48f1f51ef9 Miscellaneous logging improvements (#1525)
* *: 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
2019-03-27 14:58:36 -07:00
Alessandro Arzilli
af1ffc8504 proc,proc/native,proc/gdbserial: initial plugin support (#1413)
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
2019-03-20 10:32:51 -07:00
Alessandro Arzilli
09c92c75b9 proc: simplify logic of (*stackIterator).newStackframe (#1513)
The lookup at it.pc-1 is only ever done if fn is not nil and pc !=
fn.entry. Also when it happens only the File and Line fields are
allowed to change.
2019-03-18 10:08:23 -07:00