gitlab.com/Raven-IO/raven-delve@v1.22.4/service/rpc1/server.go (about) 1 package rpc1 2 3 import ( 4 "errors" 5 "fmt" 6 7 "gitlab.com/Raven-IO/raven-delve/pkg/proc" 8 "gitlab.com/Raven-IO/raven-delve/service" 9 "gitlab.com/Raven-IO/raven-delve/service/api" 10 "gitlab.com/Raven-IO/raven-delve/service/debugger" 11 ) 12 13 var defaultLoadConfig = proc.LoadConfig{ 14 FollowPointers: true, 15 MaxVariableRecurse: 1, 16 MaxStringLen: 64, 17 MaxArrayValues: 64, 18 MaxStructFields: -1, 19 } 20 21 type RPCServer struct { 22 // config is all the information necessary to start the debugger and server. 23 config *service.Config 24 // debugger is a debugger service. 25 debugger *debugger.Debugger 26 } 27 28 func NewServer(config *service.Config, debugger *debugger.Debugger) *RPCServer { 29 return &RPCServer{config, debugger} 30 } 31 32 func (s *RPCServer) ProcessPid(arg1 interface{}, pid *int) error { 33 *pid = s.debugger.ProcessPid() 34 return nil 35 } 36 37 func (s *RPCServer) Detach(kill bool, ret *int) error { 38 return s.debugger.Detach(kill) 39 } 40 41 func (s *RPCServer) Restart(arg1 interface{}, arg2 *int) error { 42 if s.config.Debugger.AttachPid != 0 { 43 return errors.New("cannot restart process Delve did not create") 44 } 45 _, err := s.debugger.Restart(false, "", false, nil, [3]string{}, false) 46 return err 47 } 48 49 func (s *RPCServer) State(arg interface{}, state *api.DebuggerState) error { 50 st, err := s.debugger.State(false) 51 if err != nil { 52 return err 53 } 54 *state = *st 55 return nil 56 } 57 58 func (s *RPCServer) Command(command *api.DebuggerCommand, cb service.RPCCallback) { 59 st, err := s.debugger.Command(command, cb.SetupDoneChan()) 60 cb.Return(st, err) 61 } 62 63 func (s *RPCServer) GetBreakpoint(id int, breakpoint *api.Breakpoint) error { 64 bp := s.debugger.FindBreakpoint(id) 65 if bp == nil { 66 return fmt.Errorf("no breakpoint with id %d", id) 67 } 68 *breakpoint = *bp 69 return nil 70 } 71 72 func (s *RPCServer) GetBreakpointByName(name string, breakpoint *api.Breakpoint) error { 73 bp := s.debugger.FindBreakpointByName(name) 74 if bp == nil { 75 return fmt.Errorf("no breakpoint with name %s", name) 76 } 77 *breakpoint = *bp 78 return nil 79 } 80 81 type StacktraceGoroutineArgs struct { 82 Id int 83 Depth int 84 Full bool 85 } 86 87 func (s *RPCServer) StacktraceGoroutine(args *StacktraceGoroutineArgs, locations *[]api.Stackframe) error { 88 var loadcfg *proc.LoadConfig = nil 89 if args.Full { 90 loadcfg = &defaultLoadConfig 91 } 92 locs, err := s.debugger.Stacktrace(int64(args.Id), args.Depth, 0) 93 if err != nil { 94 return err 95 } 96 *locations, err = s.debugger.ConvertStacktrace(locs, loadcfg) 97 return err 98 } 99 100 func (s *RPCServer) ListBreakpoints(arg interface{}, breakpoints *[]*api.Breakpoint) error { 101 *breakpoints = s.debugger.Breakpoints(false) 102 return nil 103 } 104 105 func (s *RPCServer) CreateBreakpoint(bp, newBreakpoint *api.Breakpoint) error { 106 if err := api.ValidBreakpointName(bp.Name); err != nil { 107 return err 108 } 109 createdbp, err := s.debugger.CreateBreakpoint(bp, "", nil, false) 110 if err != nil { 111 return err 112 } 113 *newBreakpoint = *createdbp 114 return nil 115 } 116 117 func (s *RPCServer) ClearBreakpoint(id int, breakpoint *api.Breakpoint) error { 118 bp := s.debugger.FindBreakpoint(id) 119 if bp == nil { 120 return fmt.Errorf("no breakpoint with id %d", id) 121 } 122 deleted, err := s.debugger.ClearBreakpoint(bp) 123 if err != nil { 124 return err 125 } 126 *breakpoint = *deleted 127 return nil 128 } 129 130 func (s *RPCServer) ClearBreakpointByName(name string, breakpoint *api.Breakpoint) error { 131 bp := s.debugger.FindBreakpointByName(name) 132 if bp == nil { 133 return fmt.Errorf("no breakpoint with name %s", name) 134 } 135 deleted, err := s.debugger.ClearBreakpoint(bp) 136 if err != nil { 137 return err 138 } 139 *breakpoint = *deleted 140 return nil 141 } 142 143 func (s *RPCServer) AmendBreakpoint(amend *api.Breakpoint, unused *int) error { 144 *unused = 0 145 if err := api.ValidBreakpointName(amend.Name); err != nil { 146 return err 147 } 148 return s.debugger.AmendBreakpoint(amend) 149 } 150 151 func (s *RPCServer) ListThreads(arg interface{}, threads *[]*api.Thread) (err error) { 152 pthreads, err := s.debugger.Threads() 153 if err != nil { 154 return err 155 } 156 s.debugger.LockTarget() 157 defer s.debugger.UnlockTarget() 158 *threads = api.ConvertThreads(pthreads, s.debugger.ConvertThreadBreakpoint) 159 return nil 160 } 161 162 func (s *RPCServer) GetThread(id int, thread *api.Thread) error { 163 t, err := s.debugger.FindThread(id) 164 if err != nil { 165 return err 166 } 167 if t == nil { 168 return fmt.Errorf("no thread with id %d", id) 169 } 170 s.debugger.LockTarget() 171 defer s.debugger.UnlockTarget() 172 *thread = *api.ConvertThread(t, s.debugger.ConvertThreadBreakpoint(t)) 173 return nil 174 } 175 176 func (s *RPCServer) ListPackageVars(filter string, variables *[]api.Variable) error { 177 vars, err := s.debugger.PackageVariables(filter, defaultLoadConfig) 178 if err != nil { 179 return err 180 } 181 *variables = api.ConvertVars(vars) 182 return nil 183 } 184 185 type ThreadListArgs struct { 186 Id int 187 Filter string 188 } 189 190 func (s *RPCServer) ListThreadPackageVars(args *ThreadListArgs, variables *[]api.Variable) error { 191 vars, err := s.debugger.PackageVariables(args.Filter, defaultLoadConfig) 192 if err != nil { 193 return err 194 } 195 *variables = api.ConvertVars(vars) 196 return nil 197 } 198 199 func (s *RPCServer) ListRegisters(arg interface{}, registers *string) error { 200 state, err := s.debugger.State(false) 201 if err != nil { 202 return err 203 } 204 205 dregs, err := s.debugger.ThreadRegisters(state.CurrentThread.ID) 206 if err != nil { 207 return err 208 } 209 regs := api.Registers(api.ConvertRegisters(dregs, s.debugger.DwarfRegisterToString, false)) 210 *registers = regs.String() 211 return nil 212 } 213 214 func (s *RPCServer) ListLocalVars(scope api.EvalScope, variables *[]api.Variable) error { 215 vars, err := s.debugger.LocalVariables(scope.GoroutineID, scope.Frame, scope.DeferredCall, defaultLoadConfig) 216 if err != nil { 217 return err 218 } 219 *variables = api.ConvertVars(vars) 220 return nil 221 } 222 223 func (s *RPCServer) ListFunctionArgs(scope api.EvalScope, variables *[]api.Variable) error { 224 vars, err := s.debugger.FunctionArguments(scope.GoroutineID, scope.Frame, scope.DeferredCall, defaultLoadConfig) 225 if err != nil { 226 return err 227 } 228 *variables = api.ConvertVars(vars) 229 return nil 230 } 231 232 type EvalSymbolArgs struct { 233 Scope api.EvalScope 234 Symbol string 235 } 236 237 func (s *RPCServer) EvalSymbol(args EvalSymbolArgs, variable *api.Variable) error { 238 v, err := s.debugger.EvalVariableInScope(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Symbol, defaultLoadConfig) 239 if err != nil { 240 return err 241 } 242 *variable = *api.ConvertVar(v) 243 return nil 244 } 245 246 type SetSymbolArgs struct { 247 Scope api.EvalScope 248 Symbol string 249 Value string 250 } 251 252 func (s *RPCServer) SetSymbol(args SetSymbolArgs, unused *int) error { 253 *unused = 0 254 return s.debugger.SetVariableInScope(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Symbol, args.Value) 255 } 256 257 func (s *RPCServer) ListSources(filter string, sources *[]string) error { 258 ss, err := s.debugger.Sources(filter) 259 if err != nil { 260 return err 261 } 262 *sources = ss 263 return nil 264 } 265 266 func (s *RPCServer) ListFunctions(filter string, funcs *[]string) error { 267 fns, err := s.debugger.Functions(filter) 268 if err != nil { 269 return err 270 } 271 *funcs = fns 272 return nil 273 } 274 275 func (s *RPCServer) ListTypes(filter string, types *[]string) error { 276 tps, err := s.debugger.Types(filter) 277 if err != nil { 278 return err 279 } 280 *types = tps 281 return nil 282 } 283 284 func (s *RPCServer) ListGoroutines(arg interface{}, goroutines *[]*api.Goroutine) error { 285 gs, _, err := s.debugger.Goroutines(0, 0) 286 if err != nil { 287 return err 288 } 289 s.debugger.LockTarget() 290 s.debugger.UnlockTarget() 291 *goroutines = api.ConvertGoroutines(s.debugger.Target(), gs) 292 return nil 293 } 294 295 func (s *RPCServer) AttachedToExistingProcess(arg interface{}, answer *bool) error { 296 if s.config.Debugger.AttachPid != 0 { 297 *answer = true 298 } 299 return nil 300 } 301 302 type FindLocationArgs struct { 303 Scope api.EvalScope 304 Loc string 305 } 306 307 func (s *RPCServer) FindLocation(args FindLocationArgs, answer *[]api.Location) error { 308 var err error 309 *answer, _, err = s.debugger.FindLocation(args.Scope.GoroutineID, args.Scope.Frame, args.Scope.DeferredCall, args.Loc, false, nil) 310 return err 311 } 312 313 type DisassembleRequest struct { 314 Scope api.EvalScope 315 StartPC, EndPC uint64 316 Flavour api.AssemblyFlavour 317 } 318 319 func (s *RPCServer) Disassemble(args DisassembleRequest, answer *api.AsmInstructions) error { 320 var err error 321 insts, err := s.debugger.Disassemble(args.Scope.GoroutineID, args.StartPC, args.EndPC) 322 if err != nil { 323 return err 324 } 325 *answer = make(api.AsmInstructions, len(insts)) 326 for i := range insts { 327 (*answer)[i] = api.ConvertAsmInstruction(insts[i], s.debugger.AsmInstructionText(&insts[i], proc.AssemblyFlavour(args.Flavour))) 328 } 329 return nil 330 }