github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/collection_service.go (about)

     1  package collection
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/Rookout/GoSDK/pkg/config"
     8  	"github.com/Rookout/GoSDK/pkg/rookoutErrors"
     9  	"github.com/Rookout/GoSDK/pkg/services/collection/registers"
    10  	"github.com/Rookout/GoSDK/pkg/services/collection/variable"
    11  )
    12  
    13  type Stackframe struct {
    14  	File     string `json:"file"`
    15  	Line     int    `json:"line"`
    16  	Function string `json:"function,omitempty"`
    17  }
    18  
    19  type CollectionService struct {
    20  	
    21  	variables              []*variable.Variable
    22  	StackTraceElements     []Stackframe
    23  	variableLocators       []*variable.VariableLocator
    24  	variablesCache         *variable.VariablesCache
    25  	dictVariableLocator    *variable.VariableLocator
    26  	shouldLoadDictVariable bool
    27  	dictAddr               uint64
    28  	regs                   registers.Registers
    29  	pointerSize            int
    30  	goid                   int 
    31  }
    32  
    33  const goDictionaryName = ".dict"
    34  
    35  func NewCollectionService(regs registers.Registers, pointerSize int, stackTraceElements []Stackframe, variableLocators []*variable.VariableLocator, goid int) (*CollectionService, rookoutErrors.RookoutError) {
    36  	c := &CollectionService{
    37  		StackTraceElements:     stackTraceElements,
    38  		regs:                   regs,
    39  		shouldLoadDictVariable: false,
    40  		pointerSize:            pointerSize,
    41  		goid:                   goid,
    42  		variablesCache:         variable.NewVariablesCache(),
    43  	}
    44  
    45  	for _, variableLocator := range variableLocators {
    46  		if variableLocator.VariableName == goDictionaryName {
    47  			c.dictVariableLocator = variableLocator
    48  			c.shouldLoadDictVariable = true
    49  		} else {
    50  			c.variableLocators = append(c.variableLocators, variableLocator)
    51  		}
    52  	}
    53  
    54  	return c, nil
    55  }
    56  
    57  func (c *CollectionService) GetFrame() *Stackframe {
    58  	return &c.StackTraceElements[0]
    59  }
    60  
    61  func (c *CollectionService) loadDictVariable(config config.ObjectDumpConfig) {
    62  	if c.shouldLoadDictVariable {
    63  		dictVar := c.dictVariableLocator.Locate(c.regs, 0, c.variablesCache, config)
    64  		dictAddr := dictVar.Addr
    65  
    66  		c.dictAddr = uint64(dictAddr)
    67  		c.shouldLoadDictVariable = false
    68  	}
    69  }
    70  
    71  func (c *CollectionService) GetVariables(config config.ObjectDumpConfig) []*variable.Variable {
    72  	c.loadDictVariable(config)
    73  
    74  	var variables []*variable.Variable
    75  	for _, varLocator := range c.variableLocators {
    76  		variables = append(variables, c.locateAndLoadVariable(varLocator, config))
    77  	}
    78  
    79  	return variables
    80  }
    81  
    82  func (c *CollectionService) GetVariable(name string, config config.ObjectDumpConfig) (*variable.Variable, error) {
    83  	c.loadDictVariable(config)
    84  
    85  	for _, varLocator := range c.variableLocators {
    86  		if varLocator.VariableName == name || varLocator.VariableName == "&"+name {
    87  			return c.locateAndLoadVariable(varLocator, config), nil
    88  		}
    89  	}
    90  	return nil, errors.New("variable not found")
    91  }
    92  
    93  func (c *CollectionService) locateAndLoadVariable(varLocator *variable.VariableLocator, objectDumpConfig config.ObjectDumpConfig) (v *variable.Variable) {
    94  	v = varLocator.Locate(c.regs, c.dictAddr, c.variablesCache, objectDumpConfig)
    95  	if name := v.Name; len(name) > 1 && name[0] == '&' {
    96  		v = v.MaybeDereference()
    97  		if v.Addr == 0 && v.Unreadable == nil {
    98  			v.Unreadable = fmt.Errorf("no address for escaped variable")
    99  		}
   100  		v.Name = name[1:]
   101  	}
   102  
   103  	if v.ObjectDumpConfig.ShouldTailor {
   104  		v.UpdateObjectDumpConfig(config.TailorObjectDumpConfig(v.Kind, int(v.Len)))
   105  	}
   106  
   107  	v.LoadValue()
   108  	c.variables = append(c.variables, v)
   109  	return v
   110  }
   111  
   112  func (c *CollectionService) Close() error {
   113  	for _, v := range c.variables {
   114  		_ = v.Close()
   115  	}
   116  
   117  	return nil
   118  }
   119  
   120  func (c *CollectionService) GoroutineID() int {
   121  	return c.goid
   122  }