{"record":{"id":"85a6b67d7fce40f9","repo":"go-delve/delve","slug":"direction-change-with-internal-breakpoints","errorCode":null,"errorMessage":"direction change with internal breakpoints","messagePattern":"direction change with internal breakpoints","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/gdbserial/gdbserver.go","lineNumber":133,"sourceCode":"\n\t\tstdout, err := exec.Command(\"xcode-select\", \"--print-path\").Output()\n\t\tif err != nil {\n\t\t\treturn \"\"\n\t\t}\n\n\t\txcodePath := strings.TrimSpace(string(stdout))\n\t\tif xcodePath == \"\" {\n\t\t\treturn \"\"\n\t\t}\n\n\t\t// xcode-select prints the path to the active Developer directory, which is typically a sibling to SharedFrameworks.\n\t\treturn filepath.Join(xcodePath, \"..\", debugserverXcodeRelativeExecutablePath)\n\t}(),\n}\n\n// ErrDirChange is returned when trying to change execution direction\n// while there are still internal breakpoints set.\nvar ErrDirChange = errors.New(\"direction change with internal breakpoints\")\n\n// ErrStartCallInjectionBackwards is returned when trying to start a call\n// injection while the recording is being run backwards.\nvar ErrStartCallInjectionBackwards = errors.New(\"can not start a call injection while running backwards\")\n\nvar checkCanUnmaskSignalsOnce sync.Once\nvar canUnmaskSignalsCached bool\n\n// gdbProcess implements proc.Process using a connection to a debugger stub\n// that understands Gdb Remote Serial Protocol.\ntype gdbProcess struct {\n\tbi       *proc.BinaryInfo\n\tregnames *gdbRegnames\n\tconn     gdbConn\n\n\tthreads       map[int]*gdbThread\n\tcurrentThread *gdbThread\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/gdbserial/gdbserver.go#L115-L151","documentation":"The gdbserial backend throws this exported error when a direction change (switching between forward and reverse execution of a recorded process, e.g. with rr) is requested while internal breakpoints are still inserted. Reverse-execution machinery cannot safely flip direction with those breakpoints in place, so the request is refused until they are cleared.","triggerScenarios":"`rev`/`restart`/ChangeDirection on an rr-recorded target while user or internal breakpoints set by Delve remain; toggling direction right after stepping set internal breakpoints.","commonSituations":"Time-travel debugging with Mozilla rr and switching to reverse before breakpoints are removed; scripted sessions alternating direction per command.","solutions":["Clear the relevant breakpoints (or continue to remove internal ones) before changing direction","Retry the direction change after the internal breakpoints are drained (e.g. after a continue/step completes)","Compare errors.Is(err, gdbserial.ErrDirChange) in clients and schedule the change after the next resume","Restart the recorded session (rr replay from start) if breakpoint state cannot be cleared"],"exampleFix":"// before\nerr := grp.ChangeDirection(proc.Backward) // may fail with ErrDirChange\n// after\nif err := grp.ChangeDirection(proc.Backward); errors.Is(err, gdbserial.ErrDirChange) {\n    // clear breakpoints / continue, then retry direction change\n}","handlingStrategy":"try-catch","validationCode":"// only change direction when no internal breakpoints are pending\nif len(breakpointsWithInternalState()) == 0 {\n    err := grp.ChangeDirection(proc.Backward)\n    _ = err\n}","typeGuard":"func isErrDirChange(err error) bool {\n    return errors.Is(err, gdbserial.ErrDirChange)\n}","tryCatchPattern":"if err := grp.ChangeDirection(proc.Backward); errors.Is(err, gdbserial.ErrDirChange) {\n    // continue once to clear internal breakpoints, then retry\n}","preventionTips":["Clear breakpoints before reversing direction in rr sessions","Schedule direction changes after a continue/step completes","Check errors.Is(err, gdbserial.ErrDirChange) in clients","Restart the replay session if breakpoint state cannot be drained"],"tags":["debugger","gdbserial","reverse-execution"],"backgroundTag":"direction-change-with-internal-breakpoints","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}