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  }