github.com/undoio/delve@v1.9.0/service/debugger/debugger.go (about)

     1  package debugger
     2  
     3  import (
     4  	"bytes"
     5  	"debug/dwarf"
     6  	"errors"
     7  	"fmt"
     8  	"go/parser"
     9  	"go/token"
    10  	"os"
    11  	"path/filepath"
    12  	"regexp"
    13  	"runtime"
    14  	"sort"
    15  	"strconv"
    16  	"strings"
    17  	"sync"
    18  	"time"
    19  
    20  	"github.com/undoio/delve/pkg/dwarf/op"
    21  	"github.com/undoio/delve/pkg/gobuild"
    22  	"github.com/undoio/delve/pkg/goversion"
    23  	"github.com/undoio/delve/pkg/locspec"
    24  	"github.com/undoio/delve/pkg/logflags"
    25  	"github.com/undoio/delve/pkg/proc"
    26  	"github.com/undoio/delve/pkg/proc/core"
    27  	"github.com/undoio/delve/pkg/proc/gdbserial"
    28  	"github.com/undoio/delve/pkg/proc/native"
    29  	"github.com/undoio/delve/service/api"
    30  	"github.com/sirupsen/logrus"
    31  )
    32  
    33  var (
    34  	// ErrCanNotRestart is returned when the target cannot be restarted.
    35  	// This is returned for targets that have been attached to, or when
    36  	// debugging core files.
    37  	ErrCanNotRestart = errors.New("can not restart this target")
    38  
    39  	// ErrNotRecording is returned when StopRecording is called while the
    40  	// debugger is not recording the target.
    41  	ErrNotRecording = errors.New("debugger is not recording")
    42  
    43  	// ErrCoreDumpInProgress is returned when a core dump is already in progress.
    44  	ErrCoreDumpInProgress = errors.New("core dump in progress")
    45  
    46  	// ErrCoreDumpNotSupported is returned when core dumping is not supported
    47  	ErrCoreDumpNotSupported = errors.New("core dumping not supported")
    48  )
    49  
    50  // Debugger service.
    51  //
    52  // Debugger provides a higher level of
    53  // abstraction over proc.Process.
    54  // It handles converting from internal types to
    55  // the types expected by clients. It also handles
    56  // functionality needed by clients, but not needed in
    57  // lower lever packages such as proc.
    58  type Debugger struct {
    59  	config *Config
    60  	// arguments to launch a new process.
    61  	processArgs []string
    62  
    63  	targetMutex sync.Mutex
    64  	target      *proc.Target
    65  
    66  	log *logrus.Entry
    67  
    68  	running      bool
    69  	runningMutex sync.Mutex
    70  
    71  	stopRecording func() error
    72  	recordMutex   sync.Mutex
    73  
    74  	dumpState proc.DumpState
    75  
    76  	breakpointIDCounter int
    77  }
    78  
    79  type ExecuteKind int
    80  
    81  const (
    82  	ExecutingExistingFile = ExecuteKind(iota)
    83  	ExecutingGeneratedFile
    84  	ExecutingGeneratedTest
    85  	ExecutingOther
    86  )
    87  
    88  // Config provides the configuration to start a Debugger.
    89  //
    90  // Only one of ProcessArgs or AttachPid should be specified. If ProcessArgs is
    91  // provided, a new process will be launched. Otherwise, the debugger will try
    92  // to attach to an existing process with AttachPid.
    93  type Config struct {
    94  	// WorkingDir is working directory of the new process. This field is used
    95  	// only when launching a new process.
    96  	WorkingDir string
    97  
    98  	// AttachPid is the PID of an existing process to which the debugger should
    99  	// attach.
   100  	AttachPid int
   101  
   102  	// CoreFile specifies the path to the core dump to open.
   103  	CoreFile string
   104  
   105  	// Backend specifies the debugger backend.
   106  	Backend string
   107  
   108  	// Foreground lets target process access stdin.
   109  	Foreground bool
   110  
   111  	// DebugInfoDirectories is the list of directories to look for
   112  	// when resolving external debug info files.
   113  	DebugInfoDirectories []string
   114  
   115  	// CheckGoVersion is true if the debugger should check the version of Go
   116  	// used to compile the executable and refuse to work on incompatible
   117  	// versions.
   118  	CheckGoVersion bool
   119  
   120  	// TTY is passed along to the target process on creation. Used to specify a
   121  	// TTY for that process.
   122  	TTY string
   123  
   124  	// Packages contains the packages that we are debugging.
   125  	Packages []string
   126  
   127  	// BuildFlags contains the flags passed to the compiler.
   128  	BuildFlags string
   129  
   130  	// ExecuteKind contains the kind of the executed program.
   131  	ExecuteKind ExecuteKind
   132  
   133  	// Redirects specifies redirect rules for stdin, stdout and stderr
   134  	Redirects [3]string
   135  
   136  	// DisableASLR disables ASLR
   137  	DisableASLR bool
   138  }
   139  
   140  // New creates a new Debugger. ProcessArgs specify the commandline arguments for the
   141  // new process.
   142  func New(config *Config, processArgs []string) (*Debugger, error) {
   143  	logger := logflags.DebuggerLogger()
   144  	d := &Debugger{
   145  		config:      config,
   146  		processArgs: processArgs,
   147  		log:         logger,
   148  	}
   149  
   150  	// Create the process by either attaching or launching.
   151  	switch {
   152  	case d.config.AttachPid > 0:
   153  		d.log.Infof("attaching to pid %d", d.config.AttachPid)
   154  		path := ""
   155  		if len(d.processArgs) > 0 {
   156  			path = d.processArgs[0]
   157  		}
   158  		p, err := d.Attach(d.config.AttachPid, path)
   159  		if err != nil {
   160  			err = go11DecodeErrorCheck(err)
   161  			err = noDebugErrorWarning(err)
   162  			return nil, attachErrorMessage(d.config.AttachPid, err)
   163  		}
   164  		d.target = p
   165  
   166  	case d.config.CoreFile != "":
   167  		var p *proc.Target
   168  		var err error
   169  		switch d.config.Backend {
   170  		case "rr":
   171  			d.log.Infof("opening trace %s", d.config.CoreFile)
   172  			p, err = gdbserial.Replay(d.config.CoreFile, false, false, d.config.DebugInfoDirectories)
   173  		case "undo":
   174  			d.log.Infof("opening recording %s", d.config.CoreFile)
   175  			p, err = gdbserial.UndoReplay(d.config.CoreFile, "", false, d.config.DebugInfoDirectories)
   176  		default:
   177  			d.log.Infof("opening core file %s (executable %s)", d.config.CoreFile, d.processArgs[0])
   178  			p, err = core.OpenCore(d.config.CoreFile, d.processArgs[0], d.config.DebugInfoDirectories)
   179  		}
   180  		if err != nil {
   181  			err = go11DecodeErrorCheck(err)
   182  			return nil, err
   183  		}
   184  		d.target = p
   185  		if err := d.checkGoVersion(); err != nil {
   186  			d.target.Detach(true)
   187  			return nil, err
   188  		}
   189  
   190  	default:
   191  		d.log.Infof("launching process with args: %v", d.processArgs)
   192  		p, err := d.Launch(d.processArgs, d.config.WorkingDir)
   193  		if err != nil {
   194  			if _, ok := err.(*proc.ErrUnsupportedArch); !ok {
   195  				err = go11DecodeErrorCheck(err)
   196  				err = noDebugErrorWarning(err)
   197  				err = fmt.Errorf("could not launch process: %s", err)
   198  			}
   199  			return nil, err
   200  		}
   201  		if p != nil {
   202  			// if p == nil and err == nil then we are doing a recording, don't touch d.target
   203  			d.target = p
   204  		}
   205  		if err := d.checkGoVersion(); err != nil {
   206  			d.target.Detach(true)
   207  			return nil, err
   208  		}
   209  	}
   210  
   211  	return d, nil
   212  }
   213  
   214  // canRestart returns true if the target was started with Launch and can be restarted
   215  func (d *Debugger) canRestart() bool {
   216  	switch {
   217  	case d.config.AttachPid > 0:
   218  		return false
   219  	case d.config.CoreFile != "":
   220  		return false
   221  	default:
   222  		return true
   223  	}
   224  }
   225  
   226  func (d *Debugger) checkGoVersion() error {
   227  	if d.isRecording() {
   228  		// do not do anything if we are still recording
   229  		return nil
   230  	}
   231  	producer := d.target.BinInfo().Producer()
   232  	if producer == "" {
   233  		return nil
   234  	}
   235  	return goversion.Compatible(producer, !d.config.CheckGoVersion)
   236  }
   237  
   238  func (d *Debugger) TargetGoVersion() string {
   239  	d.targetMutex.Lock()
   240  	defer d.targetMutex.Unlock()
   241  	return d.target.BinInfo().Producer()
   242  }
   243  
   244  // Launch will start a process with the given args and working directory.
   245  func (d *Debugger) Launch(processArgs []string, wd string) (*proc.Target, error) {
   246  	if err := verifyBinaryFormat(processArgs[0]); err != nil {
   247  		return nil, err
   248  	}
   249  
   250  	launchFlags := proc.LaunchFlags(0)
   251  	if d.config.Foreground {
   252  		launchFlags |= proc.LaunchForeground
   253  	}
   254  	if d.config.DisableASLR {
   255  		launchFlags |= proc.LaunchDisableASLR
   256  	}
   257  
   258  	switch d.config.Backend {
   259  	case "native":
   260  		return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)
   261  	case "lldb":
   262  		return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects))
   263  	case "rr":
   264  		if d.target != nil {
   265  			// restart should not call us if the backend is 'rr'
   266  			panic("internal error: call to Launch with rr backend and target already exists")
   267  		}
   268  
   269  		run, stop, err := gdbserial.RecordAsync(processArgs, wd, false, d.config.Redirects)
   270  		if err != nil {
   271  			return nil, err
   272  		}
   273  
   274  		// let the initialization proceed but hold the targetMutex lock so that
   275  		// any other request to debugger will block except State(nowait=true) and
   276  		// Command(halt).
   277  		d.targetMutex.Lock()
   278  		d.recordingStart(stop)
   279  
   280  		go func() {
   281  			defer d.targetMutex.Unlock()
   282  
   283  			p, err := d.recordingRun(run)
   284  			if err != nil {
   285  				d.log.Errorf("could not record target: %v", err)
   286  				// this is ugly but we can't respond to any client requests at this
   287  				// point so it's better if we die.
   288  				os.Exit(1)
   289  			}
   290  			d.recordingDone()
   291  			d.target = p
   292  			if err := d.checkGoVersion(); err != nil {
   293  				d.log.Error(err)
   294  				err := d.target.Detach(true)
   295  				if err != nil {
   296  					d.log.Errorf("Error detaching from target: %v", err)
   297  				}
   298  			}
   299  		}()
   300  		return nil, nil
   301  	case "undo":
   302  		tgt, _, err := gdbserial.UndoRecordAndReplay(processArgs, wd, false, d.config.DebugInfoDirectories, d.config.Redirects)
   303  		return tgt, err
   304  
   305  	case "default":
   306  		if runtime.GOOS == "darwin" {
   307  			return betterGdbserialLaunchError(gdbserial.LLDBLaunch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects))
   308  		}
   309  		return native.Launch(processArgs, wd, launchFlags, d.config.DebugInfoDirectories, d.config.TTY, d.config.Redirects)
   310  	default:
   311  		return nil, fmt.Errorf("unknown backend %q", d.config.Backend)
   312  	}
   313  }
   314  
   315  func (d *Debugger) recordingStart(stop func() error) {
   316  	d.recordMutex.Lock()
   317  	d.stopRecording = stop
   318  	d.recordMutex.Unlock()
   319  }
   320  
   321  func (d *Debugger) recordingDone() {
   322  	d.recordMutex.Lock()
   323  	d.stopRecording = nil
   324  	d.recordMutex.Unlock()
   325  }
   326  
   327  func (d *Debugger) isRecording() bool {
   328  	d.recordMutex.Lock()
   329  	defer d.recordMutex.Unlock()
   330  	return d.stopRecording != nil
   331  }
   332  
   333  func (d *Debugger) recordingRun(run func() (string, error)) (*proc.Target, error) {
   334  	tracedir, err := run()
   335  	if err != nil && tracedir == "" {
   336  		return nil, err
   337  	}
   338  
   339  	return gdbserial.Replay(tracedir, false, true, d.config.DebugInfoDirectories)
   340  }
   341  
   342  // Attach will attach to the process specified by 'pid'.
   343  func (d *Debugger) Attach(pid int, path string) (*proc.Target, error) {
   344  	switch d.config.Backend {
   345  	case "native":
   346  		return native.Attach(pid, d.config.DebugInfoDirectories)
   347  	case "lldb":
   348  		return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, d.config.DebugInfoDirectories))
   349  	case "default":
   350  		if runtime.GOOS == "darwin" {
   351  			return betterGdbserialLaunchError(gdbserial.LLDBAttach(pid, path, d.config.DebugInfoDirectories))
   352  		}
   353  		return native.Attach(pid, d.config.DebugInfoDirectories)
   354  	default:
   355  		return nil, fmt.Errorf("unknown backend %q", d.config.Backend)
   356  	}
   357  }
   358  
   359  var errMacOSBackendUnavailable = errors.New("debugserver or lldb-server not found: install Xcode's command line tools or lldb-server")
   360  
   361  func betterGdbserialLaunchError(p *proc.Target, err error) (*proc.Target, error) {
   362  	if runtime.GOOS != "darwin" {
   363  		return p, err
   364  	}
   365  	if _, isUnavailable := err.(*gdbserial.ErrBackendUnavailable); !isUnavailable {
   366  		return p, err
   367  	}
   368  
   369  	return p, errMacOSBackendUnavailable
   370  }
   371  
   372  // ProcessPid returns the PID of the process
   373  // the debugger is debugging.
   374  func (d *Debugger) ProcessPid() int {
   375  	d.targetMutex.Lock()
   376  	defer d.targetMutex.Unlock()
   377  	return d.target.Pid()
   378  }
   379  
   380  // LastModified returns the time that the process' executable was last
   381  // modified.
   382  func (d *Debugger) LastModified() time.Time {
   383  	d.targetMutex.Lock()
   384  	defer d.targetMutex.Unlock()
   385  	return d.target.BinInfo().LastModified()
   386  }
   387  
   388  // FunctionReturnLocations returns all return locations
   389  // for the given function, a list of addresses corresponding
   390  // to 'ret' or 'call runtime.deferreturn'.
   391  func (d *Debugger) FunctionReturnLocations(fnName string) ([]uint64, error) {
   392  	d.targetMutex.Lock()
   393  	defer d.targetMutex.Unlock()
   394  
   395  	var (
   396  		p = d.target
   397  		g = p.SelectedGoroutine()
   398  	)
   399  
   400  	fns, err := p.BinInfo().FindFunction(fnName)
   401  	if err != nil {
   402  		return nil, err
   403  	}
   404  
   405  	var addrs []uint64
   406  
   407  	for _, fn := range fns {
   408  		var regs proc.Registers
   409  		mem := p.Memory()
   410  		if g != nil && g.Thread != nil {
   411  			regs, _ = g.Thread.Registers()
   412  		}
   413  		instructions, err := proc.Disassemble(mem, regs, p.Breakpoints(), p.BinInfo(), fn.Entry, fn.End)
   414  		if err != nil {
   415  			return nil, err
   416  		}
   417  
   418  		for _, instruction := range instructions {
   419  			if instruction.IsRet() {
   420  				addrs = append(addrs, instruction.Loc.PC)
   421  			}
   422  		}
   423  		addrs = append(addrs, proc.FindDeferReturnCalls(instructions)...)
   424  	}
   425  
   426  	return addrs, nil
   427  }
   428  
   429  // Detach detaches from the target process.
   430  // If `kill` is true we will kill the process after
   431  // detaching.
   432  func (d *Debugger) Detach(kill bool) error {
   433  	d.log.Debug("detaching")
   434  	d.targetMutex.Lock()
   435  	defer d.targetMutex.Unlock()
   436  	if ok, _ := d.target.Valid(); !ok {
   437  		return nil
   438  	}
   439  	return d.detach(kill)
   440  }
   441  
   442  func (d *Debugger) detach(kill bool) error {
   443  	if d.config.AttachPid == 0 {
   444  		kill = true
   445  	}
   446  	return d.target.Detach(kill)
   447  }
   448  
   449  // Restart will restart the target process, first killing
   450  // and then exec'ing it again.
   451  // If the target process is a recording it will restart it from the given
   452  // position. If pos starts with 'c' it's a checkpoint ID, otherwise it's an
   453  // event number. If resetArgs is true, newArgs will replace the process args.
   454  func (d *Debugger) Restart(rerecord bool, pos string, resetArgs bool, newArgs []string, newRedirects [3]string, rebuild bool) ([]api.DiscardedBreakpoint, error) {
   455  	d.targetMutex.Lock()
   456  	defer d.targetMutex.Unlock()
   457  
   458  	recorded, _ := d.target.Recorded()
   459  	if recorded && !rerecord {
   460  		d.target.ResumeNotify(nil)
   461  		return nil, d.target.Restart(pos)
   462  	}
   463  
   464  	if pos != "" {
   465  		return nil, proc.ErrNotRecorded
   466  	}
   467  
   468  	if !d.canRestart() {
   469  		return nil, ErrCanNotRestart
   470  	}
   471  
   472  	if valid, _ := d.target.Valid(); valid && !recorded {
   473  		// Ensure the process is in a PTRACE_STOP.
   474  		if err := stopProcess(d.target.Pid()); err != nil {
   475  			return nil, err
   476  		}
   477  	}
   478  	if err := d.detach(true); err != nil {
   479  		return nil, err
   480  	}
   481  	if resetArgs {
   482  		d.processArgs = append([]string{d.processArgs[0]}, newArgs...)
   483  		d.config.Redirects = newRedirects
   484  	}
   485  	var p *proc.Target
   486  	var err error
   487  
   488  	if rebuild {
   489  		switch d.config.ExecuteKind {
   490  		case ExecutingGeneratedFile:
   491  			err = gobuild.GoBuild(d.processArgs[0], d.config.Packages, d.config.BuildFlags)
   492  			if err != nil {
   493  				return nil, fmt.Errorf("could not rebuild process: %s", err)
   494  			}
   495  		case ExecutingGeneratedTest:
   496  			err = gobuild.GoTestBuild(d.processArgs[0], d.config.Packages, d.config.BuildFlags)
   497  			if err != nil {
   498  				return nil, fmt.Errorf("could not rebuild process: %s", err)
   499  			}
   500  		default:
   501  			// We cannot build a process that we didn't start, because we don't know how it was built.
   502  			return nil, fmt.Errorf("cannot rebuild a binary")
   503  		}
   504  	}
   505  
   506  	if recorded && d.config.Backend == "rr" {
   507  		run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Redirects)
   508  		if err2 != nil {
   509  			return nil, err2
   510  		}
   511  
   512  		d.recordingStart(stop)
   513  		p, err = d.recordingRun(run)
   514  		d.recordingDone()
   515  	} else if recorded && d.config.Backend == "undo" {
   516  		p, _, err = gdbserial.UndoRecordAndReplay(d.processArgs, d.config.WorkingDir, false, d.config.DebugInfoDirectories, d.config.Redirects)
   517  	} else {
   518  		p, err = d.Launch(d.processArgs, d.config.WorkingDir)
   519  	}
   520  	if err != nil {
   521  		return nil, fmt.Errorf("could not launch process: %s", err)
   522  	}
   523  
   524  	discarded := []api.DiscardedBreakpoint{}
   525  	p.Breakpoints().Logical = d.target.Breakpoints().Logical
   526  	d.target = p
   527  	for _, oldBp := range d.target.Breakpoints().Logical {
   528  		if oldBp.LogicalID < 0 || !oldBp.Enabled {
   529  			continue
   530  		}
   531  		if len(oldBp.File) > 0 {
   532  			oldBp.TotalHitCount = 0
   533  			oldBp.HitCount = make(map[int]uint64)
   534  			err := d.createPhysicalBreakpoints(oldBp)
   535  			if err != nil {
   536  				discarded = append(discarded, api.DiscardedBreakpoint{Breakpoint: api.ConvertLogicalBreakpoint(oldBp), Reason: err.Error()})
   537  				continue
   538  			}
   539  		} else {
   540  			discarded = append(discarded, api.DiscardedBreakpoint{Breakpoint: api.ConvertLogicalBreakpoint(oldBp), Reason: "can not recreate watchpoint on restart"})
   541  		}
   542  	}
   543  	return discarded, nil
   544  }
   545  
   546  // State returns the current state of the debugger.
   547  func (d *Debugger) State(nowait bool) (*api.DebuggerState, error) {
   548  	if d.IsRunning() && nowait {
   549  		return &api.DebuggerState{Running: true}, nil
   550  	}
   551  
   552  	if d.isRecording() && nowait {
   553  		return &api.DebuggerState{Recording: true}, nil
   554  	}
   555  
   556  	d.dumpState.Mutex.Lock()
   557  	if d.dumpState.Dumping && nowait {
   558  		return &api.DebuggerState{CoreDumping: true}, nil
   559  	}
   560  	d.dumpState.Mutex.Unlock()
   561  
   562  	d.targetMutex.Lock()
   563  	defer d.targetMutex.Unlock()
   564  	return d.state(nil)
   565  }
   566  
   567  func (d *Debugger) state(retLoadCfg *proc.LoadConfig) (*api.DebuggerState, error) {
   568  	if _, err := d.target.Valid(); err != nil {
   569  		return nil, err
   570  	}
   571  
   572  	var (
   573  		state     *api.DebuggerState
   574  		goroutine *api.Goroutine
   575  	)
   576  
   577  	if d.target.SelectedGoroutine() != nil {
   578  		goroutine = api.ConvertGoroutine(d.target, d.target.SelectedGoroutine())
   579  	}
   580  
   581  	exited := false
   582  	if _, err := d.target.Valid(); err != nil {
   583  		_, exited = err.(proc.ErrProcessExited)
   584  	}
   585  
   586  	state = &api.DebuggerState{
   587  		SelectedGoroutine: goroutine,
   588  		Exited:            exited,
   589  	}
   590  
   591  	for _, thread := range d.target.ThreadList() {
   592  		th := api.ConvertThread(thread, d.ConvertThreadBreakpoint(thread))
   593  
   594  		th.CallReturn = thread.Common().CallReturn
   595  		if retLoadCfg != nil {
   596  			th.ReturnValues = api.ConvertVars(thread.Common().ReturnValues(*retLoadCfg))
   597  		}
   598  
   599  		state.Threads = append(state.Threads, th)
   600  		if thread.ThreadID() == d.target.CurrentThread().ThreadID() {
   601  			state.CurrentThread = th
   602  		}
   603  	}
   604  
   605  	state.NextInProgress = d.target.Breakpoints().HasSteppingBreakpoints()
   606  
   607  	if recorded, _ := d.target.Recorded(); recorded {
   608  		state.When, _ = d.target.When()
   609  	}
   610  
   611  	state.WatchOutOfScope = make([]*api.Breakpoint, 0, len(d.target.Breakpoints().WatchOutOfScope))
   612  	for _, bp := range d.target.Breakpoints().WatchOutOfScope {
   613  		abp := api.ConvertLogicalBreakpoint(bp.Logical)
   614  		api.ConvertPhysicalBreakpoints(abp, []*proc.Breakpoint{bp})
   615  		state.WatchOutOfScope = append(state.WatchOutOfScope, abp)
   616  	}
   617  
   618  	return state, nil
   619  }
   620  
   621  // CreateBreakpoint creates a breakpoint using information from the provided `requestedBp`.
   622  // This function accepts several different ways of specifying where and how to create the
   623  // breakpoint that has been requested. Any error encountered during the attempt to set the
   624  // breakpoint will be returned to the caller.
   625  //
   626  // The ways of specifying a breakpoint are listed below in the order they are considered by
   627  // this function:
   628  //
   629  // - If requestedBp.TraceReturn is true then it is expected that
   630  // requestedBp.Addrs will contain the list of return addresses
   631  // supplied by the caller.
   632  //
   633  // - If requestedBp.File is not an empty string the breakpoint
   634  // will be created on the specified file:line location
   635  //
   636  // - If requestedBp.FunctionName is not an empty string
   637  // the breakpoint will be created on the specified function:line
   638  // location.
   639  //
   640  // - If requestedBp.Addrs is filled it will create a logical breakpoint
   641  // corresponding to all specified addresses.
   642  //
   643  // - Otherwise the value specified by arg.Breakpoint.Addr will be used.
   644  //
   645  // Note that this method will use the first successful method in order to
   646  // create a breakpoint, so mixing different fields will not result is multiple
   647  // breakpoints being set.
   648  func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) {
   649  	d.targetMutex.Lock()
   650  	defer d.targetMutex.Unlock()
   651  
   652  	var (
   653  		addrs []uint64
   654  		err   error
   655  	)
   656  
   657  	if requestedBp.Name != "" {
   658  		if d.findBreakpointByName(requestedBp.Name) != nil {
   659  			return nil, errors.New("breakpoint name already exists")
   660  		}
   661  	}
   662  
   663  	switch {
   664  	case requestedBp.TraceReturn:
   665  		addrs = []uint64{requestedBp.Addr}
   666  	case len(requestedBp.File) > 0:
   667  		fileName := requestedBp.File
   668  		if runtime.GOOS == "windows" {
   669  			// Accept fileName which is case-insensitive and slash-insensitive match
   670  			fileNameNormalized := strings.ToLower(filepath.ToSlash(fileName))
   671  			for _, symFile := range d.target.BinInfo().Sources {
   672  				if fileNameNormalized == strings.ToLower(filepath.ToSlash(symFile)) {
   673  					fileName = symFile
   674  					break
   675  				}
   676  			}
   677  		}
   678  		addrs, err = proc.FindFileLocation(d.target, fileName, requestedBp.Line)
   679  	case len(requestedBp.FunctionName) > 0:
   680  		addrs, err = proc.FindFunctionLocation(d.target, requestedBp.FunctionName, requestedBp.Line)
   681  	case len(requestedBp.Addrs) > 0:
   682  		addrs = requestedBp.Addrs
   683  	default:
   684  		addrs = []uint64{requestedBp.Addr}
   685  	}
   686  
   687  	if err != nil {
   688  		return nil, err
   689  	}
   690  
   691  	createdBp, err := createLogicalBreakpoint(d, addrs, requestedBp, 0)
   692  	if err != nil {
   693  		return nil, err
   694  	}
   695  	d.log.Infof("created breakpoint: %#v", createdBp)
   696  	return createdBp, nil
   697  }
   698  
   699  func (d *Debugger) convertBreakpoint(lbp *proc.LogicalBreakpoint) *api.Breakpoint {
   700  	abp := api.ConvertLogicalBreakpoint(lbp)
   701  	api.ConvertPhysicalBreakpoints(abp, d.findBreakpoint(lbp.LogicalID))
   702  	return abp
   703  }
   704  
   705  func (d *Debugger) ConvertThreadBreakpoint(thread proc.Thread) *api.Breakpoint {
   706  	if b := thread.Breakpoint(); b.Active && b.Breakpoint.Logical != nil {
   707  		return d.convertBreakpoint(b.Breakpoint.Logical)
   708  	}
   709  	return nil
   710  }
   711  
   712  // createLogicalBreakpoint creates one physical breakpoint for each address
   713  // in addrs and associates all of them with the same logical breakpoint.
   714  func createLogicalBreakpoint(d *Debugger, addrs []uint64, requestedBp *api.Breakpoint, id int) (*api.Breakpoint, error) {
   715  	p := d.target
   716  
   717  	if lbp := p.Breakpoints().Logical[requestedBp.ID]; lbp != nil {
   718  		abp := d.convertBreakpoint(lbp)
   719  		return abp, proc.BreakpointExistsError{File: lbp.File, Line: lbp.Line}
   720  	}
   721  
   722  	var lbp *proc.LogicalBreakpoint
   723  	if id <= 0 {
   724  		d.breakpointIDCounter++
   725  		id = d.breakpointIDCounter
   726  		lbp = &proc.LogicalBreakpoint{LogicalID: id, HitCount: make(map[int]uint64), Enabled: true}
   727  		p.Breakpoints().Logical[id] = lbp
   728  	}
   729  
   730  	err := copyLogicalBreakpointInfo(lbp, requestedBp)
   731  	if err != nil {
   732  		return nil, err
   733  	}
   734  
   735  	bps := make([]*proc.Breakpoint, len(addrs))
   736  	for i := range addrs {
   737  		bps[i], err = p.SetBreakpoint(id, addrs[i], proc.UserBreakpoint, nil)
   738  		if err != nil {
   739  			break
   740  		}
   741  	}
   742  	if err != nil {
   743  		delete(p.Breakpoints().Logical, id)
   744  		if isBreakpointExistsErr(err) {
   745  			return nil, err
   746  		}
   747  		for _, bp := range bps {
   748  			if bp == nil {
   749  				continue
   750  			}
   751  			if err1 := p.ClearBreakpoint(bp.Addr); err1 != nil {
   752  				err = fmt.Errorf("error while creating breakpoint: %v, additionally the breakpoint could not be properly rolled back: %v", err, err1)
   753  				return nil, err
   754  			}
   755  		}
   756  		return nil, err
   757  	}
   758  
   759  	return d.convertBreakpoint(bps[0].Logical), nil
   760  }
   761  
   762  func (d *Debugger) createPhysicalBreakpoints(lbp *proc.LogicalBreakpoint) error {
   763  	addrs, err := proc.FindFileLocation(d.target, lbp.File, lbp.Line)
   764  	if err != nil {
   765  		return err
   766  	}
   767  	bps := make([]*proc.Breakpoint, len(addrs))
   768  	for i := range addrs {
   769  		bps[i], err = d.target.SetBreakpoint(lbp.LogicalID, addrs[i], proc.UserBreakpoint, nil)
   770  		if err != nil {
   771  			break
   772  		}
   773  	}
   774  	if err != nil {
   775  		if isBreakpointExistsErr(err) {
   776  			return err
   777  		}
   778  		for _, bp := range bps {
   779  			if bp == nil {
   780  				continue
   781  			}
   782  			if err1 := d.target.ClearBreakpoint(bp.Addr); err1 != nil {
   783  				return fmt.Errorf("error while creating breakpoint: %v, additionally the breakpoint could not be properly rolled back: %v", err, err1)
   784  			}
   785  		}
   786  		return err
   787  	}
   788  	return nil
   789  }
   790  
   791  func (d *Debugger) clearPhysicalBreakpoints(id int) error {
   792  	var errs []error
   793  	n := 0
   794  	for _, bp := range d.target.Breakpoints().M {
   795  		if bp.LogicalID() == id {
   796  			n++
   797  			err := d.target.ClearBreakpoint(bp.Addr)
   798  			if err != nil {
   799  				errs = append(errs, err)
   800  			}
   801  		}
   802  	}
   803  	if len(errs) > 0 {
   804  		buf := new(bytes.Buffer)
   805  		for i, err := range errs {
   806  			fmt.Fprintf(buf, "%s", err)
   807  			if i != len(errs)-1 {
   808  				fmt.Fprintf(buf, ", ")
   809  			}
   810  		}
   811  
   812  		if len(errs) == n {
   813  			return fmt.Errorf("unable to clear breakpoint %d: %v", id, buf.String())
   814  		}
   815  		return fmt.Errorf("unable to clear breakpoint %d (partial): %s", id, buf.String())
   816  	}
   817  	return nil
   818  }
   819  
   820  func isBreakpointExistsErr(err error) bool {
   821  	_, r := err.(proc.BreakpointExistsError)
   822  	return r
   823  }
   824  
   825  func (d *Debugger) CreateEBPFTracepoint(fnName string) error {
   826  	d.targetMutex.Lock()
   827  	defer d.targetMutex.Unlock()
   828  
   829  	return d.target.SetEBPFTracepoint(fnName)
   830  }
   831  
   832  // amendBreakpoint will update the breakpoint with the matching ID.
   833  // It also enables or disables the breakpoint.
   834  // We can consume this function to avoid locking a goroutine.
   835  func (d *Debugger) amendBreakpoint(amend *api.Breakpoint) error {
   836  	original := d.target.Breakpoints().Logical[amend.ID]
   837  	if original == nil {
   838  		return fmt.Errorf("no breakpoint with ID %d", amend.ID)
   839  	}
   840  	if amend.Disabled && original.Enabled {
   841  		original.Enabled = false
   842  		err := copyLogicalBreakpointInfo(original, amend)
   843  		if err != nil {
   844  			return err
   845  		}
   846  		return d.clearPhysicalBreakpoints(amend.ID)
   847  	}
   848  
   849  	if !amend.Disabled && !original.Enabled {
   850  		original.Enabled = true
   851  		copyLogicalBreakpointInfo(original, amend)
   852  		return d.createPhysicalBreakpoints(original)
   853  	}
   854  
   855  	err := copyLogicalBreakpointInfo(original, amend)
   856  	if err != nil {
   857  		return err
   858  	}
   859  	for _, bp := range d.findBreakpoint(amend.ID) {
   860  		bp.UserBreaklet().Cond = original.Cond
   861  	}
   862  	return nil
   863  }
   864  
   865  // AmendBreakpoint will update the breakpoint with the matching ID.
   866  // It also enables or disables the breakpoint.
   867  func (d *Debugger) AmendBreakpoint(amend *api.Breakpoint) error {
   868  	d.targetMutex.Lock()
   869  	defer d.targetMutex.Unlock()
   870  
   871  	return d.amendBreakpoint(amend)
   872  }
   873  
   874  // CancelNext will clear internal breakpoints, thus cancelling the 'next',
   875  // 'step' or 'stepout' operation.
   876  func (d *Debugger) CancelNext() error {
   877  	d.targetMutex.Lock()
   878  	defer d.targetMutex.Unlock()
   879  	return d.target.ClearSteppingBreakpoints()
   880  }
   881  
   882  func copyLogicalBreakpointInfo(lbp *proc.LogicalBreakpoint, requested *api.Breakpoint) error {
   883  	lbp.Name = requested.Name
   884  	lbp.Tracepoint = requested.Tracepoint
   885  	lbp.TraceReturn = requested.TraceReturn
   886  	lbp.Goroutine = requested.Goroutine
   887  	lbp.Stacktrace = requested.Stacktrace
   888  	lbp.Variables = requested.Variables
   889  	lbp.LoadArgs = api.LoadConfigToProc(requested.LoadArgs)
   890  	lbp.LoadLocals = api.LoadConfigToProc(requested.LoadLocals)
   891  	lbp.UserData = requested.UserData
   892  	lbp.Cond = nil
   893  	if requested.Cond != "" {
   894  		var err error
   895  		lbp.Cond, err = parser.ParseExpr(requested.Cond)
   896  		if err != nil {
   897  			return err
   898  		}
   899  	}
   900  
   901  	lbp.HitCond = nil
   902  	if requested.HitCond != "" {
   903  		opTok, val, err := parseHitCondition(requested.HitCond)
   904  		if err != nil {
   905  			return err
   906  		}
   907  		lbp.HitCond = &struct {
   908  			Op  token.Token
   909  			Val int
   910  		}{opTok, val}
   911  	}
   912  
   913  	return nil
   914  }
   915  
   916  func parseHitCondition(hitCond string) (token.Token, int, error) {
   917  	// A hit condition can be in the following formats:
   918  	// - "number"
   919  	// - "OP number"
   920  	hitConditionRegex := regexp.MustCompile(`((=|>|<|%|!)+|)( |)((\d|_)+)`)
   921  
   922  	match := hitConditionRegex.FindStringSubmatch(strings.TrimSpace(hitCond))
   923  	if match == nil || len(match) != 6 {
   924  		return 0, 0, fmt.Errorf("unable to parse breakpoint hit condition: %q\nhit conditions should be of the form \"number\" or \"OP number\"", hitCond)
   925  	}
   926  
   927  	opStr := match[1]
   928  	var opTok token.Token
   929  	switch opStr {
   930  	case "==", "":
   931  		opTok = token.EQL
   932  	case ">=":
   933  		opTok = token.GEQ
   934  	case "<=":
   935  		opTok = token.LEQ
   936  	case ">":
   937  		opTok = token.GTR
   938  	case "<":
   939  		opTok = token.LSS
   940  	case "%":
   941  		opTok = token.REM
   942  	case "!=":
   943  		opTok = token.NEQ
   944  	default:
   945  		return 0, 0, fmt.Errorf("unable to parse breakpoint hit condition: %q\ninvalid operator: %q", hitCond, opStr)
   946  	}
   947  
   948  	numStr := match[4]
   949  	val, parseErr := strconv.Atoi(numStr)
   950  	if parseErr != nil {
   951  		return 0, 0, fmt.Errorf("unable to parse breakpoint hit condition: %q\ninvalid number: %q", hitCond, numStr)
   952  	}
   953  
   954  	return opTok, val, nil
   955  }
   956  
   957  // ClearBreakpoint clears a breakpoint.
   958  func (d *Debugger) ClearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) {
   959  	d.targetMutex.Lock()
   960  	defer d.targetMutex.Unlock()
   961  	return d.clearBreakpoint(requestedBp)
   962  }
   963  
   964  // clearBreakpoint clears a breakpoint, we can consume this function to avoid locking a goroutine
   965  func (d *Debugger) clearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) {
   966  	if requestedBp.ID <= 0 {
   967  		bp := d.target.Breakpoints().M[requestedBp.Addr]
   968  		requestedBp.ID = bp.LogicalID()
   969  	}
   970  
   971  	lbp := d.target.Breakpoints().Logical[requestedBp.ID]
   972  	clearedBp := d.convertBreakpoint(lbp)
   973  
   974  	delete(d.target.Breakpoints().Logical, requestedBp.ID)
   975  
   976  	err := d.clearPhysicalBreakpoints(requestedBp.ID)
   977  	if err != nil {
   978  		return nil, err
   979  	}
   980  
   981  	d.log.Infof("cleared breakpoint: %#v", clearedBp)
   982  	return clearedBp, nil
   983  }
   984  
   985  // isBpHitCondNotSatisfiable returns true if the breakpoint bp has a hit
   986  // condition that is no more satisfiable.
   987  // The hit condition is considered no more satisfiable if it can no longer be
   988  // hit again, for example with {Op: "==", Val: 1} and TotalHitCount == 1.
   989  func isBpHitCondNotSatisfiable(bp *api.Breakpoint) bool {
   990  	if bp.HitCond == "" {
   991  		return false
   992  	}
   993  
   994  	tok, val, err := parseHitCondition(bp.HitCond)
   995  	if err != nil {
   996  		return false
   997  	}
   998  	switch tok {
   999  	case token.EQL, token.LEQ:
  1000  		if int(bp.TotalHitCount) >= val {
  1001  			return true
  1002  		}
  1003  	case token.LSS:
  1004  		if int(bp.TotalHitCount) >= val-1 {
  1005  			return true
  1006  		}
  1007  	}
  1008  
  1009  	return false
  1010  }
  1011  
  1012  // Breakpoints returns the list of current breakpoints.
  1013  func (d *Debugger) Breakpoints(all bool) []*api.Breakpoint {
  1014  	d.targetMutex.Lock()
  1015  	defer d.targetMutex.Unlock()
  1016  
  1017  	abps := []*api.Breakpoint{}
  1018  	if all {
  1019  		for _, bp := range d.target.Breakpoints().M {
  1020  			var abp *api.Breakpoint
  1021  			if bp.Logical != nil {
  1022  				abp = api.ConvertLogicalBreakpoint(bp.Logical)
  1023  			} else {
  1024  				abp = &api.Breakpoint{}
  1025  			}
  1026  			api.ConvertPhysicalBreakpoints(abp, []*proc.Breakpoint{bp})
  1027  			abp.VerboseDescr = bp.VerboseDescr()
  1028  			abps = append(abps, abp)
  1029  		}
  1030  	} else {
  1031  		for _, lbp := range d.target.Breakpoints().Logical {
  1032  			abps = append(abps, d.convertBreakpoint(lbp))
  1033  		}
  1034  	}
  1035  	return abps
  1036  }
  1037  
  1038  // FindBreakpoint returns the breakpoint specified by 'id'.
  1039  func (d *Debugger) FindBreakpoint(id int) *api.Breakpoint {
  1040  	d.targetMutex.Lock()
  1041  	defer d.targetMutex.Unlock()
  1042  	lbp := d.target.Breakpoints().Logical[id]
  1043  	if lbp == nil {
  1044  		return nil
  1045  	}
  1046  	return d.convertBreakpoint(lbp)
  1047  }
  1048  
  1049  func (d *Debugger) findBreakpoint(id int) []*proc.Breakpoint {
  1050  	var bps []*proc.Breakpoint
  1051  	for _, bp := range d.target.Breakpoints().M {
  1052  		if bp.LogicalID() == id {
  1053  			bps = append(bps, bp)
  1054  		}
  1055  	}
  1056  	return bps
  1057  }
  1058  
  1059  // FindBreakpointByName returns the breakpoint specified by 'name'
  1060  func (d *Debugger) FindBreakpointByName(name string) *api.Breakpoint {
  1061  	d.targetMutex.Lock()
  1062  	defer d.targetMutex.Unlock()
  1063  	return d.findBreakpointByName(name)
  1064  }
  1065  
  1066  func (d *Debugger) findBreakpointByName(name string) *api.Breakpoint {
  1067  	for _, lbp := range d.target.Breakpoints().Logical {
  1068  		if lbp.Name == name {
  1069  			return d.convertBreakpoint(lbp)
  1070  		}
  1071  	}
  1072  	return nil
  1073  }
  1074  
  1075  // CreateWatchpoint creates a watchpoint on the specified expression.
  1076  func (d *Debugger) CreateWatchpoint(goid, frame, deferredCall int, expr string, wtype api.WatchType) (*api.Breakpoint, error) {
  1077  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1078  	if err != nil {
  1079  		return nil, err
  1080  	}
  1081  	d.breakpointIDCounter++
  1082  	bp, err := d.target.SetWatchpoint(d.breakpointIDCounter, s, expr, proc.WatchType(wtype), nil)
  1083  	if err != nil {
  1084  		return nil, err
  1085  	}
  1086  	if d.findBreakpointByName(expr) == nil {
  1087  		bp.Logical.Name = expr
  1088  	}
  1089  	return d.convertBreakpoint(bp.Logical), nil
  1090  }
  1091  
  1092  // Threads returns the threads of the target process.
  1093  func (d *Debugger) Threads() ([]proc.Thread, error) {
  1094  	d.targetMutex.Lock()
  1095  	defer d.targetMutex.Unlock()
  1096  
  1097  	if _, err := d.target.Valid(); err != nil {
  1098  		return nil, err
  1099  	}
  1100  
  1101  	return d.target.ThreadList(), nil
  1102  }
  1103  
  1104  // FindThread returns the thread for the given 'id'.
  1105  func (d *Debugger) FindThread(id int) (proc.Thread, error) {
  1106  	d.targetMutex.Lock()
  1107  	defer d.targetMutex.Unlock()
  1108  
  1109  	if _, err := d.target.Valid(); err != nil {
  1110  		return nil, err
  1111  	}
  1112  
  1113  	for _, th := range d.target.ThreadList() {
  1114  		if th.ThreadID() == id {
  1115  			return th, nil
  1116  		}
  1117  	}
  1118  	return nil, nil
  1119  }
  1120  
  1121  // FindGoroutine returns the goroutine for the given 'id'.
  1122  func (d *Debugger) FindGoroutine(id int) (*proc.G, error) {
  1123  	d.targetMutex.Lock()
  1124  	defer d.targetMutex.Unlock()
  1125  
  1126  	return proc.FindGoroutine(d.target, id)
  1127  }
  1128  
  1129  func (d *Debugger) setRunning(running bool) {
  1130  	d.runningMutex.Lock()
  1131  	d.running = running
  1132  	d.runningMutex.Unlock()
  1133  }
  1134  
  1135  func (d *Debugger) IsRunning() bool {
  1136  	d.runningMutex.Lock()
  1137  	defer d.runningMutex.Unlock()
  1138  	return d.running
  1139  }
  1140  
  1141  // Command handles commands which control the debugger lifecycle
  1142  func (d *Debugger) Command(command *api.DebuggerCommand, resumeNotify chan struct{}) (*api.DebuggerState, error) {
  1143  	var err error
  1144  
  1145  	if command.Name == api.Halt {
  1146  		// RequestManualStop does not invoke any ptrace syscalls, so it's safe to
  1147  		// access the process directly.
  1148  		d.log.Debug("halting")
  1149  
  1150  		d.recordMutex.Lock()
  1151  		if d.stopRecording == nil {
  1152  			err = d.target.RequestManualStop()
  1153  			// The error returned from d.target.Valid will have more context
  1154  			// about the exited process.
  1155  			if _, valErr := d.target.Valid(); valErr != nil {
  1156  				err = valErr
  1157  			}
  1158  		}
  1159  		d.recordMutex.Unlock()
  1160  	}
  1161  
  1162  	withBreakpointInfo := true
  1163  
  1164  	d.targetMutex.Lock()
  1165  	defer d.targetMutex.Unlock()
  1166  
  1167  	d.setRunning(true)
  1168  	defer d.setRunning(false)
  1169  
  1170  	if command.Name != api.SwitchGoroutine && command.Name != api.SwitchThread && command.Name != api.Halt {
  1171  		d.target.ResumeNotify(resumeNotify)
  1172  	} else if resumeNotify != nil {
  1173  		close(resumeNotify)
  1174  	}
  1175  
  1176  	switch command.Name {
  1177  	case api.Continue:
  1178  		d.log.Debug("continuing")
  1179  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1180  			return nil, err
  1181  		}
  1182  		err = d.target.Continue()
  1183  	case api.DirectionCongruentContinue:
  1184  		d.log.Debug("continuing (direction congruent)")
  1185  		err = d.target.Continue()
  1186  	case api.Call:
  1187  		d.log.Debugf("function call %s", command.Expr)
  1188  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1189  			return nil, err
  1190  		}
  1191  		if command.ReturnInfoLoadConfig == nil {
  1192  			return nil, errors.New("can not call function with nil ReturnInfoLoadConfig")
  1193  		}
  1194  		g := d.target.SelectedGoroutine()
  1195  		if command.GoroutineID > 0 {
  1196  			g, err = proc.FindGoroutine(d.target, command.GoroutineID)
  1197  			if err != nil {
  1198  				return nil, err
  1199  			}
  1200  		}
  1201  		err = proc.EvalExpressionWithCalls(d.target, g, command.Expr, *api.LoadConfigToProc(command.ReturnInfoLoadConfig), !command.UnsafeCall)
  1202  	case api.Rewind:
  1203  		d.log.Debug("rewinding")
  1204  		if err := d.target.ChangeDirection(proc.Backward); err != nil {
  1205  			return nil, err
  1206  		}
  1207  		err = d.target.Continue()
  1208  	case api.Next:
  1209  		d.log.Debug("nexting")
  1210  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1211  			return nil, err
  1212  		}
  1213  		err = d.target.Next()
  1214  	case api.ReverseNext:
  1215  		d.log.Debug("reverse nexting")
  1216  		if err := d.target.ChangeDirection(proc.Backward); err != nil {
  1217  			return nil, err
  1218  		}
  1219  		err = d.target.Next()
  1220  	case api.Step:
  1221  		d.log.Debug("stepping")
  1222  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1223  			return nil, err
  1224  		}
  1225  		err = d.target.Step()
  1226  	case api.ReverseStep:
  1227  		d.log.Debug("reverse stepping")
  1228  		if err := d.target.ChangeDirection(proc.Backward); err != nil {
  1229  			return nil, err
  1230  		}
  1231  		err = d.target.Step()
  1232  	case api.StepInstruction:
  1233  		d.log.Debug("single stepping")
  1234  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1235  			return nil, err
  1236  		}
  1237  		err = d.target.StepInstruction()
  1238  	case api.ReverseStepInstruction:
  1239  		d.log.Debug("reverse single stepping")
  1240  		if err := d.target.ChangeDirection(proc.Backward); err != nil {
  1241  			return nil, err
  1242  		}
  1243  		err = d.target.StepInstruction()
  1244  	case api.StepOut:
  1245  		d.log.Debug("step out")
  1246  		if err := d.target.ChangeDirection(proc.Forward); err != nil {
  1247  			return nil, err
  1248  		}
  1249  		err = d.target.StepOut()
  1250  	case api.ReverseStepOut:
  1251  		d.log.Debug("reverse step out")
  1252  		if err := d.target.ChangeDirection(proc.Backward); err != nil {
  1253  			return nil, err
  1254  		}
  1255  		err = d.target.StepOut()
  1256  	case api.SwitchThread:
  1257  		d.log.Debugf("switching to thread %d", command.ThreadID)
  1258  		err = d.target.SwitchThread(command.ThreadID)
  1259  		withBreakpointInfo = false
  1260  	case api.SwitchGoroutine:
  1261  		d.log.Debugf("switching to goroutine %d", command.GoroutineID)
  1262  		var g *proc.G
  1263  		g, err = proc.FindGoroutine(d.target, command.GoroutineID)
  1264  		if err == nil {
  1265  			err = d.target.SwitchGoroutine(g)
  1266  		}
  1267  		withBreakpointInfo = false
  1268  	case api.Halt:
  1269  		// RequestManualStop already called
  1270  		withBreakpointInfo = false
  1271  	}
  1272  
  1273  	if err != nil {
  1274  		if pe, ok := err.(proc.ErrProcessExited); ok && command.Name != api.SwitchGoroutine && command.Name != api.SwitchThread {
  1275  			state := &api.DebuggerState{}
  1276  			state.Pid = d.target.Pid()
  1277  			state.Exited = true
  1278  			state.ExitStatus = pe.Status
  1279  			state.Err = pe
  1280  			return state, nil
  1281  		}
  1282  		return nil, err
  1283  	}
  1284  	state, stateErr := d.state(api.LoadConfigToProc(command.ReturnInfoLoadConfig))
  1285  	if stateErr != nil {
  1286  		return state, stateErr
  1287  	}
  1288  	if withBreakpointInfo {
  1289  		err = d.collectBreakpointInformation(state)
  1290  	}
  1291  	for _, th := range state.Threads {
  1292  		if th.Breakpoint != nil && th.Breakpoint.TraceReturn {
  1293  			for _, v := range th.BreakpointInfo.Arguments {
  1294  				if (v.Flags & api.VariableReturnArgument) != 0 {
  1295  					th.ReturnValues = append(th.ReturnValues, v)
  1296  				}
  1297  			}
  1298  		}
  1299  	}
  1300  	if bp := state.CurrentThread.Breakpoint; bp != nil && isBpHitCondNotSatisfiable(bp) {
  1301  		bp.Disabled = true
  1302  		d.amendBreakpoint(bp)
  1303  	}
  1304  	return state, err
  1305  }
  1306  
  1307  func (d *Debugger) collectBreakpointInformation(state *api.DebuggerState) error {
  1308  	if state == nil {
  1309  		return nil
  1310  	}
  1311  
  1312  	for i := range state.Threads {
  1313  		if state.Threads[i].Breakpoint == nil || state.Threads[i].BreakpointInfo != nil {
  1314  			continue
  1315  		}
  1316  
  1317  		bp := state.Threads[i].Breakpoint
  1318  		bpi := &api.BreakpointInfo{}
  1319  		state.Threads[i].BreakpointInfo = bpi
  1320  
  1321  		if bp.Goroutine {
  1322  			g, err := proc.GetG(d.target.CurrentThread())
  1323  			if err != nil {
  1324  				return err
  1325  			}
  1326  			bpi.Goroutine = api.ConvertGoroutine(d.target, g)
  1327  		}
  1328  
  1329  		if bp.Stacktrace > 0 {
  1330  			rawlocs, err := proc.ThreadStacktrace(d.target.CurrentThread(), bp.Stacktrace)
  1331  			if err != nil {
  1332  				return err
  1333  			}
  1334  			bpi.Stacktrace, err = d.convertStacktrace(rawlocs, nil)
  1335  			if err != nil {
  1336  				return err
  1337  			}
  1338  		}
  1339  
  1340  		thread, found := d.target.FindThread(state.Threads[i].ID)
  1341  		if !found {
  1342  			return fmt.Errorf("could not find thread %d", state.Threads[i].ID)
  1343  		}
  1344  
  1345  		if len(bp.Variables) == 0 && bp.LoadArgs == nil && bp.LoadLocals == nil {
  1346  			// don't try to create goroutine scope if there is nothing to load
  1347  			continue
  1348  		}
  1349  
  1350  		s, err := proc.GoroutineScope(d.target, thread)
  1351  		if err != nil {
  1352  			return err
  1353  		}
  1354  
  1355  		if len(bp.Variables) > 0 {
  1356  			bpi.Variables = make([]api.Variable, len(bp.Variables))
  1357  		}
  1358  		for i := range bp.Variables {
  1359  			v, err := s.EvalExpression(bp.Variables[i], proc.LoadConfig{FollowPointers: true, MaxVariableRecurse: 1, MaxStringLen: 64, MaxArrayValues: 64, MaxStructFields: -1})
  1360  			if err != nil {
  1361  				bpi.Variables[i] = api.Variable{Name: bp.Variables[i], Unreadable: fmt.Sprintf("eval error: %v", err)}
  1362  			} else {
  1363  				bpi.Variables[i] = *api.ConvertVar(v)
  1364  			}
  1365  		}
  1366  		if bp.LoadArgs != nil {
  1367  			if vars, err := s.FunctionArguments(*api.LoadConfigToProc(bp.LoadArgs)); err == nil {
  1368  				bpi.Arguments = api.ConvertVars(vars)
  1369  			}
  1370  		}
  1371  		if bp.LoadLocals != nil {
  1372  			if locals, err := s.LocalVariables(*api.LoadConfigToProc(bp.LoadLocals)); err == nil {
  1373  				bpi.Locals = api.ConvertVars(locals)
  1374  			}
  1375  		}
  1376  	}
  1377  
  1378  	return nil
  1379  }
  1380  
  1381  // Sources returns a list of the source files for target binary.
  1382  func (d *Debugger) Sources(filter string) ([]string, error) {
  1383  	d.targetMutex.Lock()
  1384  	defer d.targetMutex.Unlock()
  1385  
  1386  	regex, err := regexp.Compile(filter)
  1387  	if err != nil {
  1388  		return nil, fmt.Errorf("invalid filter argument: %s", err.Error())
  1389  	}
  1390  
  1391  	files := []string{}
  1392  	for _, f := range d.target.BinInfo().Sources {
  1393  		if regex.Match([]byte(f)) {
  1394  			files = append(files, f)
  1395  		}
  1396  	}
  1397  	return files, nil
  1398  }
  1399  
  1400  // Functions returns a list of functions in the target process.
  1401  func (d *Debugger) Functions(filter string) ([]string, error) {
  1402  	d.targetMutex.Lock()
  1403  	defer d.targetMutex.Unlock()
  1404  
  1405  	regex, err := regexp.Compile(filter)
  1406  	if err != nil {
  1407  		return nil, fmt.Errorf("invalid filter argument: %s", err.Error())
  1408  	}
  1409  
  1410  	funcs := []string{}
  1411  	for _, f := range d.target.BinInfo().Functions {
  1412  		if regex.MatchString(f.Name) {
  1413  			funcs = append(funcs, f.Name)
  1414  		}
  1415  	}
  1416  	return funcs, nil
  1417  }
  1418  
  1419  // Types returns all type information in the binary.
  1420  func (d *Debugger) Types(filter string) ([]string, error) {
  1421  	d.targetMutex.Lock()
  1422  	defer d.targetMutex.Unlock()
  1423  
  1424  	regex, err := regexp.Compile(filter)
  1425  	if err != nil {
  1426  		return nil, fmt.Errorf("invalid filter argument: %s", err.Error())
  1427  	}
  1428  
  1429  	types, err := d.target.BinInfo().Types()
  1430  	if err != nil {
  1431  		return nil, err
  1432  	}
  1433  
  1434  	r := make([]string, 0, len(types))
  1435  	for _, typ := range types {
  1436  		if regex.Match([]byte(typ)) {
  1437  			r = append(r, typ)
  1438  		}
  1439  	}
  1440  
  1441  	return r, nil
  1442  }
  1443  
  1444  // PackageVariables returns a list of package variables for the thread,
  1445  // optionally regexp filtered using regexp described in 'filter'.
  1446  func (d *Debugger) PackageVariables(filter string, cfg proc.LoadConfig) ([]*proc.Variable, error) {
  1447  	d.targetMutex.Lock()
  1448  	defer d.targetMutex.Unlock()
  1449  
  1450  	regex, err := regexp.Compile(filter)
  1451  	if err != nil {
  1452  		return nil, fmt.Errorf("invalid filter argument: %s", err.Error())
  1453  	}
  1454  
  1455  	scope, err := proc.ThreadScope(d.target, d.target.CurrentThread())
  1456  	if err != nil {
  1457  		return nil, err
  1458  	}
  1459  	pv, err := scope.PackageVariables(cfg)
  1460  	if err != nil {
  1461  		return nil, err
  1462  	}
  1463  	pvr := pv[:0]
  1464  	for i := range pv {
  1465  		if regex.Match([]byte(pv[i].Name)) {
  1466  			pvr = append(pvr, pv[i])
  1467  		}
  1468  	}
  1469  	return pvr, nil
  1470  }
  1471  
  1472  // ThreadRegisters returns registers of the specified thread.
  1473  func (d *Debugger) ThreadRegisters(threadID int, floatingPoint bool) (*op.DwarfRegisters, error) {
  1474  	d.targetMutex.Lock()
  1475  	defer d.targetMutex.Unlock()
  1476  
  1477  	thread, found := d.target.FindThread(threadID)
  1478  	if !found {
  1479  		return nil, fmt.Errorf("couldn't find thread %d", threadID)
  1480  	}
  1481  	regs, err := thread.Registers()
  1482  	if err != nil {
  1483  		return nil, err
  1484  	}
  1485  	return d.target.BinInfo().Arch.RegistersToDwarfRegisters(0, regs), nil
  1486  }
  1487  
  1488  // ScopeRegisters returns registers for the specified scope.
  1489  func (d *Debugger) ScopeRegisters(goid, frame, deferredCall int, floatingPoint bool) (*op.DwarfRegisters, error) {
  1490  	d.targetMutex.Lock()
  1491  	defer d.targetMutex.Unlock()
  1492  
  1493  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1494  	if err != nil {
  1495  		return nil, err
  1496  	}
  1497  	return &s.Regs, nil
  1498  }
  1499  
  1500  // DwarfRegisterToString returns the name and value representation of the given register.
  1501  func (d *Debugger) DwarfRegisterToString(i int, reg *op.DwarfRegister) (string, bool, string) {
  1502  	return d.target.BinInfo().Arch.DwarfRegisterToString(i, reg)
  1503  }
  1504  
  1505  // LocalVariables returns a list of the local variables.
  1506  func (d *Debugger) LocalVariables(goid, frame, deferredCall int, cfg proc.LoadConfig) ([]*proc.Variable, error) {
  1507  	d.targetMutex.Lock()
  1508  	defer d.targetMutex.Unlock()
  1509  
  1510  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1511  	if err != nil {
  1512  		return nil, err
  1513  	}
  1514  	return s.LocalVariables(cfg)
  1515  }
  1516  
  1517  // FunctionArguments returns the arguments to the current function.
  1518  func (d *Debugger) FunctionArguments(goid, frame, deferredCall int, cfg proc.LoadConfig) ([]*proc.Variable, error) {
  1519  	d.targetMutex.Lock()
  1520  	defer d.targetMutex.Unlock()
  1521  
  1522  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1523  	if err != nil {
  1524  		return nil, err
  1525  	}
  1526  	return s.FunctionArguments(cfg)
  1527  }
  1528  
  1529  // Function returns the current function.
  1530  func (d *Debugger) Function(goid, frame, deferredCall int, cfg proc.LoadConfig) (*proc.Function, error) {
  1531  	d.targetMutex.Lock()
  1532  	defer d.targetMutex.Unlock()
  1533  
  1534  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1535  	if err != nil {
  1536  		return nil, err
  1537  	}
  1538  	return s.Fn, nil
  1539  }
  1540  
  1541  // EvalVariableInScope will attempt to evaluate the variable represented by 'symbol'
  1542  // in the scope provided.
  1543  func (d *Debugger) EvalVariableInScope(goid, frame, deferredCall int, expr string, cfg proc.LoadConfig) (*proc.Variable, error) {
  1544  	d.targetMutex.Lock()
  1545  	defer d.targetMutex.Unlock()
  1546  
  1547  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1548  	if err != nil {
  1549  		return nil, err
  1550  	}
  1551  	return s.EvalExpression(expr, cfg)
  1552  }
  1553  
  1554  // LoadResliced will attempt to 'reslice' a map, array or slice so that the values
  1555  // up to cfg.MaxArrayValues children are loaded starting from index start.
  1556  func (d *Debugger) LoadResliced(v *proc.Variable, start int, cfg proc.LoadConfig) (*proc.Variable, error) {
  1557  	d.targetMutex.Lock()
  1558  	defer d.targetMutex.Unlock()
  1559  	return v.LoadResliced(start, cfg)
  1560  }
  1561  
  1562  // SetVariableInScope will set the value of the variable represented by
  1563  // 'symbol' to the value given, in the given scope.
  1564  func (d *Debugger) SetVariableInScope(goid, frame, deferredCall int, symbol, value string) error {
  1565  	d.targetMutex.Lock()
  1566  	defer d.targetMutex.Unlock()
  1567  
  1568  	s, err := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1569  	if err != nil {
  1570  		return err
  1571  	}
  1572  	return s.SetVariable(symbol, value)
  1573  }
  1574  
  1575  // Goroutines will return a list of goroutines in the target process.
  1576  func (d *Debugger) Goroutines(start, count int) ([]*proc.G, int, error) {
  1577  	d.targetMutex.Lock()
  1578  	defer d.targetMutex.Unlock()
  1579  	return proc.GoroutinesInfo(d.target, start, count)
  1580  }
  1581  
  1582  // FilterGoroutines returns the goroutines in gs that satisfy the specified filters.
  1583  func (d *Debugger) FilterGoroutines(gs []*proc.G, filters []api.ListGoroutinesFilter) []*proc.G {
  1584  	if len(filters) == 0 {
  1585  		return gs
  1586  	}
  1587  	d.targetMutex.Lock()
  1588  	defer d.targetMutex.Unlock()
  1589  	r := []*proc.G{}
  1590  	for _, g := range gs {
  1591  		ok := true
  1592  		for i := range filters {
  1593  			if !matchGoroutineFilter(d.target, g, &filters[i]) {
  1594  				ok = false
  1595  				break
  1596  			}
  1597  		}
  1598  		if ok {
  1599  			r = append(r, g)
  1600  		}
  1601  	}
  1602  	return r
  1603  }
  1604  
  1605  func matchGoroutineFilter(tgt *proc.Target, g *proc.G, filter *api.ListGoroutinesFilter) bool {
  1606  	var val bool
  1607  	switch filter.Kind {
  1608  	default:
  1609  		fallthrough
  1610  	case api.GoroutineFieldNone:
  1611  		val = true
  1612  	case api.GoroutineCurrentLoc:
  1613  		val = matchGoroutineLocFilter(g.CurrentLoc, filter.Arg)
  1614  	case api.GoroutineUserLoc:
  1615  		val = matchGoroutineLocFilter(g.UserCurrent(), filter.Arg)
  1616  	case api.GoroutineGoLoc:
  1617  		val = matchGoroutineLocFilter(g.Go(), filter.Arg)
  1618  	case api.GoroutineStartLoc:
  1619  		val = matchGoroutineLocFilter(g.StartLoc(tgt), filter.Arg)
  1620  	case api.GoroutineLabel:
  1621  		idx := strings.Index(filter.Arg, "=")
  1622  		if idx >= 0 {
  1623  			val = g.Labels()[filter.Arg[:idx]] == filter.Arg[idx+1:]
  1624  		} else {
  1625  			_, val = g.Labels()[filter.Arg]
  1626  		}
  1627  	case api.GoroutineRunning:
  1628  		val = g.Thread != nil
  1629  	case api.GoroutineUser:
  1630  		val = !g.System(tgt)
  1631  	}
  1632  	if filter.Negated {
  1633  		val = !val
  1634  	}
  1635  	return val
  1636  }
  1637  
  1638  func matchGoroutineLocFilter(loc proc.Location, arg string) bool {
  1639  	return strings.Contains(formatLoc(loc), arg)
  1640  }
  1641  
  1642  func formatLoc(loc proc.Location) string {
  1643  	fnname := "?"
  1644  	if loc.Fn != nil {
  1645  		fnname = loc.Fn.Name
  1646  	}
  1647  	return fmt.Sprintf("%s:%d in %s", loc.File, loc.Line, fnname)
  1648  }
  1649  
  1650  // GroupGoroutines divides goroutines in gs into groups as specified by groupBy and groupByArg.
  1651  // A maximum of maxGoroutinesPerGroup are saved in each group, but the total
  1652  // number of goroutines in each group is recorded.
  1653  func (d *Debugger) GroupGoroutines(gs []*proc.G, group *api.GoroutineGroupingOptions) ([]*proc.G, []api.GoroutineGroup, bool) {
  1654  	if group.GroupBy == api.GoroutineFieldNone {
  1655  		return gs, nil, false
  1656  	}
  1657  	d.targetMutex.Lock()
  1658  	defer d.targetMutex.Unlock()
  1659  
  1660  	groupMembers := map[string][]*proc.G{}
  1661  	totals := map[string]int{}
  1662  
  1663  	for _, g := range gs {
  1664  		var key string
  1665  		switch group.GroupBy {
  1666  		case api.GoroutineCurrentLoc:
  1667  			key = formatLoc(g.CurrentLoc)
  1668  		case api.GoroutineUserLoc:
  1669  			key = formatLoc(g.UserCurrent())
  1670  		case api.GoroutineGoLoc:
  1671  			key = formatLoc(g.Go())
  1672  		case api.GoroutineStartLoc:
  1673  			key = formatLoc(g.StartLoc(d.target))
  1674  		case api.GoroutineLabel:
  1675  			key = fmt.Sprintf("%s=%s", group.GroupByKey, g.Labels()[group.GroupByKey])
  1676  		case api.GoroutineRunning:
  1677  			key = fmt.Sprintf("running=%v", g.Thread != nil)
  1678  		case api.GoroutineUser:
  1679  			key = fmt.Sprintf("user=%v", !g.System(d.target))
  1680  		}
  1681  		if len(groupMembers[key]) < group.MaxGroupMembers {
  1682  			groupMembers[key] = append(groupMembers[key], g)
  1683  		}
  1684  		totals[key]++
  1685  	}
  1686  
  1687  	keys := make([]string, 0, len(groupMembers))
  1688  	for key := range groupMembers {
  1689  		keys = append(keys, key)
  1690  	}
  1691  	sort.Strings(keys)
  1692  
  1693  	tooManyGroups := false
  1694  	gsout := []*proc.G{}
  1695  	groups := []api.GoroutineGroup{}
  1696  	for _, key := range keys {
  1697  		if group.MaxGroups > 0 && len(groups) >= group.MaxGroups {
  1698  			tooManyGroups = true
  1699  			break
  1700  		}
  1701  		groups = append(groups, api.GoroutineGroup{Name: key, Offset: len(gsout), Count: len(groupMembers[key]), Total: totals[key]})
  1702  		gsout = append(gsout, groupMembers[key]...)
  1703  	}
  1704  	return gsout, groups, tooManyGroups
  1705  }
  1706  
  1707  // Stacktrace returns a list of Stackframes for the given goroutine. The
  1708  // length of the returned list will be min(stack_len, depth).
  1709  // If 'full' is true, then local vars, function args, etc will be returned as well.
  1710  func (d *Debugger) Stacktrace(goroutineID, depth int, opts api.StacktraceOptions) ([]proc.Stackframe, error) {
  1711  	d.targetMutex.Lock()
  1712  	defer d.targetMutex.Unlock()
  1713  
  1714  	if _, err := d.target.Valid(); err != nil {
  1715  		return nil, err
  1716  	}
  1717  
  1718  	g, err := proc.FindGoroutine(d.target, goroutineID)
  1719  	if err != nil {
  1720  		return nil, err
  1721  	}
  1722  
  1723  	if g == nil {
  1724  		return proc.ThreadStacktrace(d.target.CurrentThread(), depth)
  1725  	} else {
  1726  		return g.Stacktrace(depth, proc.StacktraceOptions(opts))
  1727  	}
  1728  }
  1729  
  1730  // Ancestors returns the stacktraces for the ancestors of a goroutine.
  1731  func (d *Debugger) Ancestors(goroutineID, numAncestors, depth int) ([]api.Ancestor, error) {
  1732  	d.targetMutex.Lock()
  1733  	defer d.targetMutex.Unlock()
  1734  
  1735  	if _, err := d.target.Valid(); err != nil {
  1736  		return nil, err
  1737  	}
  1738  
  1739  	g, err := proc.FindGoroutine(d.target, goroutineID)
  1740  	if err != nil {
  1741  		return nil, err
  1742  	}
  1743  	if g == nil {
  1744  		return nil, errors.New("no selected goroutine")
  1745  	}
  1746  
  1747  	ancestors, err := proc.Ancestors(d.target, g, numAncestors)
  1748  	if err != nil {
  1749  		return nil, err
  1750  	}
  1751  
  1752  	r := make([]api.Ancestor, len(ancestors))
  1753  	for i := range ancestors {
  1754  		r[i].ID = ancestors[i].ID
  1755  		if ancestors[i].Unreadable != nil {
  1756  			r[i].Unreadable = ancestors[i].Unreadable.Error()
  1757  			continue
  1758  		}
  1759  		frames, err := ancestors[i].Stack(depth)
  1760  		if err != nil {
  1761  			r[i].Unreadable = fmt.Sprintf("could not read ancestor stacktrace: %v", err)
  1762  			continue
  1763  		}
  1764  		r[i].Stack, err = d.convertStacktrace(frames, nil)
  1765  		if err != nil {
  1766  			r[i].Unreadable = fmt.Sprintf("could not read ancestor stacktrace: %v", err)
  1767  		}
  1768  	}
  1769  	return r, nil
  1770  }
  1771  
  1772  // ConvertStacktrace converts a slice of proc.Stackframe into a slice of
  1773  // api.Stackframe, loading local variables and arguments of each frame if
  1774  // cfg is not nil.
  1775  func (d *Debugger) ConvertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadConfig) ([]api.Stackframe, error) {
  1776  	d.targetMutex.Lock()
  1777  	defer d.targetMutex.Unlock()
  1778  	return d.convertStacktrace(rawlocs, cfg)
  1779  }
  1780  
  1781  func (d *Debugger) convertStacktrace(rawlocs []proc.Stackframe, cfg *proc.LoadConfig) ([]api.Stackframe, error) {
  1782  	locations := make([]api.Stackframe, 0, len(rawlocs))
  1783  	for i := range rawlocs {
  1784  		frame := api.Stackframe{
  1785  			Location: api.ConvertLocation(rawlocs[i].Call),
  1786  
  1787  			FrameOffset:        rawlocs[i].FrameOffset(),
  1788  			FramePointerOffset: rawlocs[i].FramePointerOffset(),
  1789  
  1790  			Defers: d.convertDefers(rawlocs[i].Defers),
  1791  
  1792  			Bottom: rawlocs[i].Bottom,
  1793  		}
  1794  		if rawlocs[i].Err != nil {
  1795  			frame.Err = rawlocs[i].Err.Error()
  1796  		}
  1797  		if cfg != nil && rawlocs[i].Current.Fn != nil {
  1798  			var err error
  1799  			scope := proc.FrameToScope(d.target, d.target.Memory(), nil, rawlocs[i:]...)
  1800  			locals, err := scope.LocalVariables(*cfg)
  1801  			if err != nil {
  1802  				return nil, err
  1803  			}
  1804  			arguments, err := scope.FunctionArguments(*cfg)
  1805  			if err != nil {
  1806  				return nil, err
  1807  			}
  1808  
  1809  			frame.Locals = api.ConvertVars(locals)
  1810  			frame.Arguments = api.ConvertVars(arguments)
  1811  		}
  1812  		locations = append(locations, frame)
  1813  	}
  1814  
  1815  	return locations, nil
  1816  }
  1817  
  1818  func (d *Debugger) convertDefers(defers []*proc.Defer) []api.Defer {
  1819  	r := make([]api.Defer, len(defers))
  1820  	for i := range defers {
  1821  		ddf, ddl, ddfn := defers[i].DeferredFunc(d.target)
  1822  		drf, drl, drfn := d.target.BinInfo().PCToLine(defers[i].DeferPC)
  1823  
  1824  		r[i] = api.Defer{
  1825  			DeferredLoc: api.ConvertLocation(proc.Location{
  1826  				PC:   ddfn.Entry,
  1827  				File: ddf,
  1828  				Line: ddl,
  1829  				Fn:   ddfn,
  1830  			}),
  1831  			DeferLoc: api.ConvertLocation(proc.Location{
  1832  				PC:   defers[i].DeferPC,
  1833  				File: drf,
  1834  				Line: drl,
  1835  				Fn:   drfn,
  1836  			}),
  1837  			SP: defers[i].SP,
  1838  		}
  1839  
  1840  		if defers[i].Unreadable != nil {
  1841  			r[i].Unreadable = defers[i].Unreadable.Error()
  1842  		}
  1843  	}
  1844  
  1845  	return r
  1846  }
  1847  
  1848  // CurrentPackage returns the fully qualified name of the
  1849  // package corresponding to the function location of the
  1850  // current thread.
  1851  func (d *Debugger) CurrentPackage() (string, error) {
  1852  	d.targetMutex.Lock()
  1853  	defer d.targetMutex.Unlock()
  1854  
  1855  	if _, err := d.target.Valid(); err != nil {
  1856  		return "", err
  1857  	}
  1858  	loc, err := d.target.CurrentThread().Location()
  1859  	if err != nil {
  1860  		return "", err
  1861  	}
  1862  	if loc.Fn == nil {
  1863  		return "", fmt.Errorf("unable to determine current package due to unspecified function location")
  1864  	}
  1865  	return loc.Fn.PackageName(), nil
  1866  }
  1867  
  1868  // FindLocation will find the location specified by 'locStr'.
  1869  func (d *Debugger) FindLocation(goid, frame, deferredCall int, locStr string, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) {
  1870  	d.targetMutex.Lock()
  1871  	defer d.targetMutex.Unlock()
  1872  
  1873  	if _, err := d.target.Valid(); err != nil {
  1874  		return nil, err
  1875  	}
  1876  
  1877  	loc, err := locspec.Parse(locStr)
  1878  	if err != nil {
  1879  		return nil, err
  1880  	}
  1881  
  1882  	return d.findLocation(goid, frame, deferredCall, locStr, loc, includeNonExecutableLines, substitutePathRules)
  1883  }
  1884  
  1885  // FindLocationSpec will find the location specified by 'locStr' and 'locSpec'.
  1886  // 'locSpec' should be the result of calling 'locspec.Parse(locStr)'. 'locStr'
  1887  // is also passed, because it made be used to broaden the search criteria, if
  1888  // the parsed result did not find anything.
  1889  func (d *Debugger) FindLocationSpec(goid, frame, deferredCall int, locStr string, locSpec locspec.LocationSpec, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) {
  1890  	d.targetMutex.Lock()
  1891  	defer d.targetMutex.Unlock()
  1892  
  1893  	if _, err := d.target.Valid(); err != nil {
  1894  		return nil, err
  1895  	}
  1896  
  1897  	return d.findLocation(goid, frame, deferredCall, locStr, locSpec, includeNonExecutableLines, substitutePathRules)
  1898  }
  1899  
  1900  func (d *Debugger) findLocation(goid, frame, deferredCall int, locStr string, locSpec locspec.LocationSpec, includeNonExecutableLines bool, substitutePathRules [][2]string) ([]api.Location, error) {
  1901  	s, _ := proc.ConvertEvalScope(d.target, goid, frame, deferredCall)
  1902  
  1903  	locs, err := locSpec.Find(d.target, d.processArgs, s, locStr, includeNonExecutableLines, substitutePathRules)
  1904  	for i := range locs {
  1905  		if locs[i].PC == 0 {
  1906  			continue
  1907  		}
  1908  		file, line, fn := d.target.BinInfo().PCToLine(locs[i].PC)
  1909  		locs[i].File = file
  1910  		locs[i].Line = line
  1911  		locs[i].Function = api.ConvertFunction(fn)
  1912  	}
  1913  	return locs, err
  1914  }
  1915  
  1916  // Disassemble code between startPC and endPC.
  1917  // if endPC == 0 it will find the function containing startPC and disassemble the whole function.
  1918  func (d *Debugger) Disassemble(goroutineID int, addr1, addr2 uint64) ([]proc.AsmInstruction, error) {
  1919  	d.targetMutex.Lock()
  1920  	defer d.targetMutex.Unlock()
  1921  
  1922  	if _, err := d.target.Valid(); err != nil {
  1923  		return nil, err
  1924  	}
  1925  
  1926  	if addr2 == 0 {
  1927  		fn := d.target.BinInfo().PCToFunc(addr1)
  1928  		if fn == nil {
  1929  			return nil, fmt.Errorf("address %#x does not belong to any function", addr1)
  1930  		}
  1931  		addr1 = fn.Entry
  1932  		addr2 = fn.End
  1933  	}
  1934  
  1935  	g, err := proc.FindGoroutine(d.target, goroutineID)
  1936  	if err != nil {
  1937  		return nil, err
  1938  	}
  1939  
  1940  	curthread := d.target.CurrentThread()
  1941  	if g != nil && g.Thread != nil {
  1942  		curthread = g.Thread
  1943  	}
  1944  	regs, _ := curthread.Registers()
  1945  
  1946  	return proc.Disassemble(d.target.Memory(), regs, d.target.Breakpoints(), d.target.BinInfo(), addr1, addr2)
  1947  }
  1948  
  1949  func (d *Debugger) AsmInstructionText(inst *proc.AsmInstruction, flavour proc.AssemblyFlavour) string {
  1950  	d.targetMutex.Lock()
  1951  	defer d.targetMutex.Unlock()
  1952  	return inst.Text(flavour, d.target.BinInfo())
  1953  }
  1954  
  1955  // Recorded returns true if the target is a recording.
  1956  func (d *Debugger) Recorded() (recorded bool, tracedir string) {
  1957  	d.targetMutex.Lock()
  1958  	defer d.targetMutex.Unlock()
  1959  	return d.target.Recorded()
  1960  }
  1961  
  1962  // FindThreadReturnValues returns the return values of the function that
  1963  // the thread of the given 'id' just stepped out of.
  1964  func (d *Debugger) FindThreadReturnValues(id int, cfg proc.LoadConfig) ([]*proc.Variable, error) {
  1965  	d.targetMutex.Lock()
  1966  	defer d.targetMutex.Unlock()
  1967  
  1968  	if _, err := d.target.Valid(); err != nil {
  1969  		return nil, err
  1970  	}
  1971  
  1972  	thread, found := d.target.FindThread(id)
  1973  	if !found {
  1974  		return nil, fmt.Errorf("could not find thread %d", id)
  1975  	}
  1976  
  1977  	return thread.Common().ReturnValues(cfg), nil
  1978  }
  1979  
  1980  // Checkpoint will set a checkpoint specified by the locspec.
  1981  func (d *Debugger) Checkpoint(where string) (int, error) {
  1982  	d.targetMutex.Lock()
  1983  	defer d.targetMutex.Unlock()
  1984  	return d.target.Checkpoint(where)
  1985  }
  1986  
  1987  // Checkpoints will return a list of checkpoints.
  1988  func (d *Debugger) Checkpoints() ([]proc.Checkpoint, error) {
  1989  	d.targetMutex.Lock()
  1990  	defer d.targetMutex.Unlock()
  1991  	return d.target.Checkpoints()
  1992  }
  1993  
  1994  // ClearCheckpoint will clear the checkpoint of the given ID.
  1995  func (d *Debugger) ClearCheckpoint(id int) error {
  1996  	d.targetMutex.Lock()
  1997  	defer d.targetMutex.Unlock()
  1998  	return d.target.ClearCheckpoint(id)
  1999  }
  2000  
  2001  // ListDynamicLibraries returns a list of loaded dynamic libraries.
  2002  func (d *Debugger) ListDynamicLibraries() []*proc.Image {
  2003  	d.targetMutex.Lock()
  2004  	defer d.targetMutex.Unlock()
  2005  	return d.target.BinInfo().Images[1:] // skips the first image because it's the executable file
  2006  
  2007  }
  2008  
  2009  // ExamineMemory returns the raw memory stored at the given address.
  2010  // The amount of data to be read is specified by length.
  2011  // This function will return an error if it reads less than `length` bytes.
  2012  func (d *Debugger) ExamineMemory(address uint64, length int) ([]byte, error) {
  2013  	d.targetMutex.Lock()
  2014  	defer d.targetMutex.Unlock()
  2015  
  2016  	mem := d.target.Memory()
  2017  	data := make([]byte, length)
  2018  	n, err := mem.ReadMemory(data, address)
  2019  	if err != nil {
  2020  		return nil, err
  2021  	}
  2022  	if length != n {
  2023  		return nil, errors.New("the specific range has exceeded readable area")
  2024  	}
  2025  	return data, nil
  2026  }
  2027  
  2028  func (d *Debugger) GetVersion(out *api.GetVersionOut) error {
  2029  	if d.config.CoreFile != "" {
  2030  		if d.config.Backend == "rr" || d.config.Backend == "undo" {
  2031  			out.Backend = d.config.Backend
  2032  		} else {
  2033  			out.Backend = "core"
  2034  		}
  2035  	} else {
  2036  		if d.config.Backend == "default" {
  2037  			if runtime.GOOS == "darwin" {
  2038  				out.Backend = "lldb"
  2039  			} else {
  2040  				out.Backend = "native"
  2041  			}
  2042  		} else {
  2043  			out.Backend = d.config.Backend
  2044  		}
  2045  	}
  2046  
  2047  	if !d.isRecording() && !d.IsRunning() {
  2048  		out.TargetGoVersion = d.target.BinInfo().Producer()
  2049  	}
  2050  
  2051  	out.MinSupportedVersionOfGo = fmt.Sprintf("%d.%d.0", goversion.MinSupportedVersionOfGoMajor, goversion.MinSupportedVersionOfGoMinor)
  2052  	out.MaxSupportedVersionOfGo = fmt.Sprintf("%d.%d.0", goversion.MaxSupportedVersionOfGoMajor, goversion.MaxSupportedVersionOfGoMinor)
  2053  
  2054  	return nil
  2055  }
  2056  
  2057  // ListPackagesBuildInfo returns the list of packages used by the program along with
  2058  // the directory where each package was compiled and optionally the list of
  2059  // files constituting the package.
  2060  func (d *Debugger) ListPackagesBuildInfo(includeFiles bool) []*proc.PackageBuildInfo {
  2061  	d.targetMutex.Lock()
  2062  	defer d.targetMutex.Unlock()
  2063  	return d.target.BinInfo().ListPackagesBuildInfo(includeFiles)
  2064  }
  2065  
  2066  // StopRecording stops a recording (if one is in progress)
  2067  func (d *Debugger) StopRecording() error {
  2068  	d.recordMutex.Lock()
  2069  	defer d.recordMutex.Unlock()
  2070  	if d.stopRecording == nil {
  2071  		return ErrNotRecording
  2072  	}
  2073  	return d.stopRecording()
  2074  }
  2075  
  2076  // StopReason returns the reason the reason why the target process is stopped.
  2077  // A process could be stopped for multiple simultaneous reasons, in which
  2078  // case only one will be reported.
  2079  func (d *Debugger) StopReason() proc.StopReason {
  2080  	d.targetMutex.Lock()
  2081  	defer d.targetMutex.Unlock()
  2082  	return d.target.StopReason
  2083  }
  2084  
  2085  // LockTarget acquires the target mutex.
  2086  func (d *Debugger) LockTarget() {
  2087  	d.targetMutex.Lock()
  2088  }
  2089  
  2090  // UnlockTarget releases the target mutex.
  2091  func (d *Debugger) UnlockTarget() {
  2092  	d.targetMutex.Unlock()
  2093  }
  2094  
  2095  // DumpStart starts a core dump to dest.
  2096  func (d *Debugger) DumpStart(dest string) error {
  2097  	d.targetMutex.Lock()
  2098  	// targetMutex will only be unlocked when the dump is done
  2099  
  2100  	if !d.target.CanDump {
  2101  		d.targetMutex.Unlock()
  2102  		return ErrCoreDumpNotSupported
  2103  	}
  2104  
  2105  	d.dumpState.Mutex.Lock()
  2106  	defer d.dumpState.Mutex.Unlock()
  2107  
  2108  	if d.dumpState.Dumping {
  2109  		d.targetMutex.Unlock()
  2110  		return ErrCoreDumpInProgress
  2111  	}
  2112  
  2113  	fh, err := os.Create(dest)
  2114  	if err != nil {
  2115  		d.targetMutex.Unlock()
  2116  		return err
  2117  	}
  2118  
  2119  	d.dumpState.Dumping = true
  2120  	d.dumpState.AllDone = false
  2121  	d.dumpState.Canceled = false
  2122  	d.dumpState.DoneChan = make(chan struct{})
  2123  	d.dumpState.ThreadsDone = 0
  2124  	d.dumpState.ThreadsTotal = 0
  2125  	d.dumpState.MemDone = 0
  2126  	d.dumpState.MemTotal = 0
  2127  	d.dumpState.Err = nil
  2128  	go func() {
  2129  		defer d.targetMutex.Unlock()
  2130  		d.target.Dump(fh, 0, &d.dumpState)
  2131  	}()
  2132  
  2133  	return nil
  2134  }
  2135  
  2136  // DumpWait waits for the dump to finish, or for the duration of wait.
  2137  // Returns the state of the dump.
  2138  // If wait == 0 returns immediately.
  2139  func (d *Debugger) DumpWait(wait time.Duration) *proc.DumpState {
  2140  	d.dumpState.Mutex.Lock()
  2141  	if !d.dumpState.Dumping {
  2142  		d.dumpState.Mutex.Unlock()
  2143  		return &d.dumpState
  2144  	}
  2145  	d.dumpState.Mutex.Unlock()
  2146  
  2147  	if wait > 0 {
  2148  		alarm := time.After(wait)
  2149  		select {
  2150  		case <-alarm:
  2151  		case <-d.dumpState.DoneChan:
  2152  		}
  2153  	}
  2154  
  2155  	return &d.dumpState
  2156  }
  2157  
  2158  // DumpCancel canels a dump in progress
  2159  func (d *Debugger) DumpCancel() error {
  2160  	d.dumpState.Mutex.Lock()
  2161  	d.dumpState.Canceled = true
  2162  	d.dumpState.Mutex.Unlock()
  2163  	return nil
  2164  }
  2165  
  2166  func (d *Debugger) Target() *proc.Target {
  2167  	return d.target
  2168  }
  2169  
  2170  func (d *Debugger) BuildID() string {
  2171  	return d.target.BinInfo().BuildID
  2172  }
  2173  
  2174  func (d *Debugger) AttachPid() int {
  2175  	return d.config.AttachPid
  2176  }
  2177  
  2178  func (d *Debugger) GetBufferedTracepoints() []api.TracepointResult {
  2179  	traces := d.target.GetBufferedTracepoints()
  2180  	if traces == nil {
  2181  		return nil
  2182  	}
  2183  	results := make([]api.TracepointResult, len(traces))
  2184  	for i, trace := range traces {
  2185  		f, l, fn := d.target.BinInfo().PCToLine(uint64(trace.FnAddr))
  2186  
  2187  		results[i].FunctionName = fn.Name
  2188  		results[i].Line = l
  2189  		results[i].File = f
  2190  		results[i].GoroutineID = trace.GoroutineID
  2191  
  2192  		for _, p := range trace.InputParams {
  2193  			results[i].InputParams = append(results[i].InputParams, *api.ConvertVar(p))
  2194  		}
  2195  		for _, p := range trace.ReturnParams {
  2196  			results[i].ReturnParams = append(results[i].ReturnParams, *api.ConvertVar(p))
  2197  		}
  2198  	}
  2199  	return results
  2200  }
  2201  
  2202  func go11DecodeErrorCheck(err error) error {
  2203  	if _, isdecodeerr := err.(dwarf.DecodeError); !isdecodeerr {
  2204  		return err
  2205  	}
  2206  
  2207  	gover, ok := goversion.Installed()
  2208  	if !ok || !gover.AfterOrEqual(goversion.GoVersion{Major: 1, Minor: 11, Rev: -1}) || goversion.VersionAfterOrEqual(runtime.Version(), 1, 11) {
  2209  		return err
  2210  	}
  2211  
  2212  	return fmt.Errorf("executables built by Go 1.11 or later need Delve built by Go 1.11 or later")
  2213  }
  2214  
  2215  const NoDebugWarning string = "debuggee must not be built with 'go run' or -ldflags='-s -w', which strip debug info"
  2216  
  2217  func noDebugErrorWarning(err error) error {
  2218  	if _, isdecodeerr := err.(dwarf.DecodeError); isdecodeerr || strings.Contains(err.Error(), "could not open debug info") {
  2219  		return fmt.Errorf("%s - %s", err.Error(), NoDebugWarning)
  2220  	}
  2221  	return err
  2222  }