func (d *Debugger) AmendBreakpoint(amend *api.Breakpoint) error { d.processMutex.Lock() defer d.processMutex.Unlock() original := d.findBreakpoint(amend.ID) if original == nil { return fmt.Errorf("no breakpoint with ID %d", amend.ID) } if err := api.ValidBreakpointName(amend.Name); err != nil { return err } return copyBreakpointInfo(original, amend) }
func setBreakpoint(t *Term, tracepoint bool, argstr string) error { args := strings.SplitN(argstr, " ", 2) requestedBp := &api.Breakpoint{} locspec := "" switch len(args) { case 1: locspec = argstr case 2: if api.ValidBreakpointName(args[0]) == nil { requestedBp.Name = args[0] locspec = args[1] } else { locspec = argstr } default: return fmt.Errorf("address required") } requestedBp.Tracepoint = tracepoint locs, err := t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, locspec) if err != nil { if requestedBp.Name == "" { return err } requestedBp.Name = "" locspec = argstr var err2 error locs, err2 = t.client.FindLocation(api.EvalScope{GoroutineID: -1, Frame: 0}, locspec) if err2 != nil { return err } } for _, loc := range locs { requestedBp.Addr = loc.PC bp, err := t.client.CreateBreakpoint(requestedBp) if err != nil { return err } fmt.Printf("%s set at %s\n", formatBreakpointName(bp, true), formatBreakpointLocation(bp)) } return nil }
// CreateBreakpoint creates a breakpoint. func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) { d.processMutex.Lock() defer d.processMutex.Unlock() var ( createdBp *api.Breakpoint addr uint64 err error ) if requestedBp.Name != "" { if err = api.ValidBreakpointName(requestedBp.Name); err != nil { return nil, err } if d.findBreakpointByName(requestedBp.Name) != nil { return nil, errors.New("breakpoint name already exists") } } switch { case len(requestedBp.File) > 0: fileName := requestedBp.File if runtime.GOOS == "windows" { // Accept fileName which is case-insensitive and slash-insensitive match fileNameNormalized := strings.ToLower(filepath.ToSlash(fileName)) for symFile := range d.process.Sources() { if fileNameNormalized == strings.ToLower(filepath.ToSlash(symFile)) { fileName = symFile break } } } addr, err = d.process.FindFileLocation(fileName, requestedBp.Line) case len(requestedBp.FunctionName) > 0: if requestedBp.Line >= 0 { addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, false, requestedBp.Line) } else { addr, err = d.process.FindFunctionLocation(requestedBp.FunctionName, true, 0) } default: addr = requestedBp.Addr } if err != nil { return nil, err } bp, err := d.process.SetBreakpoint(addr) if err != nil { return nil, err } if err := copyBreakpointInfo(bp, requestedBp); err != nil { if _, err1 := d.process.ClearBreakpoint(bp.Addr); err1 != nil { err = fmt.Errorf("error while creating breakpoint: %v, additionally the breakpoint could not be properly rolled back: %v", err, err1) } return nil, err } createdBp = api.ConvertBreakpoint(bp) log.Printf("created breakpoint: %#v", createdBp) return createdBp, nil }