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