{"record":{"id":"27709ee687e044f7","repo":"go-delve/delve","slug":"can-not-start-a-call-injection-while-running-backw","errorCode":null,"errorMessage":"can not start a call injection while running backwards","messagePattern":"can not start a call injection while running backwards","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/gdbserial/gdbserver.go","lineNumber":137,"sourceCode":"\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\n\texited, detached bool\n\talmostExited     bool // true if 'rr' has sent its synthetic SIGKILL\n\tctrlC            bool // ctrl-c was sent to stop inferior\n","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/gdbserial/gdbserver.go#L119-L155","documentation":"Delve's gdbserial backend returns this when a call injection (function call via breakpoint injection) is requested while the recorded target is being run in reverse (rr record/replay backwards). Call injection is only meaningful for forward execution; attempting it while direction is backward is rejected to avoid corrupting replay state.","triggerScenarios":"Calling proc.ProcessInternal start-call-injection style APIs (e.g. via debugger call injection during a replay session) while proc.Direction is Backward.","commonSituations":"Using rr reverse debugging with delve and issuing a call (e.g. printing a function call in the CLI, conditional breakpoints with call expressions) while reverse-stepping/backward continue is active.","solutions":["Set direction back to forward before the call: proc.ChangeDirection(proc.Forward) then retry the call injection.","Postpone/avoid function-call evaluation while reverse-running; use plain variable reads instead.","If using rr, stop the reverse continue/step so the process is idle before evaluating calls.","Check delve version: newer versions may gracefully defer call injection instead of erroring."],"exampleFix":"// before (during reverse execution)\nerr := grp.Selected.CallFunction(...)\n// after\np.ChangeDirection(proc.Forward)\nerr := grp.Selected.CallFunction(...)","handlingStrategy":"validation","validationCode":"if p.Dir() == proc.Backward {\n    return errors.New(\"switch to forward direction before call injection\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check proc.Direction before evaluating function calls during rr replay.","Only use call-injecting features (function-call eval, call-based breakpoints) while running forward.","Prefer plain variable reads over call evaluation when reverse-stepping."],"tags":["gdbserial","rr","reverse-execution","call-injection"],"backgroundTag":"call-injection-while-reversing","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}