in tools/go-agent/instrument/runtime/instrument.go [41:95]
func (r *Instrument) FilterAndEdit(path string, curFile *dst.File, cursor *dstutil.Cursor, allFiles []*dst.File) bool {
switch n := cursor.Node().(type) {
case *dst.TypeSpec:
if n.Name != nil && n.Name.Name != "g" {
return false
}
st, ok := n.Type.(*dst.StructType)
if !ok {
return false
}
for _, f := range st.Fields.List {
if len(f.Names) > 0 && f.Names[0].Name == "goid" {
r.goIDType = f.Type.(*dst.Ident).Name
}
}
// append the tls field
st.Fields.List = append(st.Fields.List, &dst.Field{
Names: []*dst.Ident{dst.NewIdent(consts.TLSFieldName)},
Type: dst.NewIdent("interface{}")})
tools.LogWithStructEnhance("runtime", "g", consts.TLSFieldName, "tls field")
return true
case *dst.FuncDecl:
if n.Name.Name != "newproc1" {
return false
}
if len(n.Type.Results.List) != 1 {
return false
}
if len(n.Type.Params.List) != 3 {
return false
}
parameters := tools.EnhanceParameterNames(n.Type.Params, tools.FieldListTypeParam)
results := tools.EnhanceParameterNames(n.Type.Results, tools.FieldListTypeResult)
tools.InsertStmtsBeforeBody(n.Body, `defer func() {
{{(index .Results 0).Name}}.{{.TLSField}} = goroutineChange({{(index .Parameters 1).Name}}.{{.TLSField}})
}()
`, struct {
Parameters []*tools.ParameterInfo
Results []*tools.ParameterInfo
TLSField string
OperatorField string
SnapshotInterface string
}{
Parameters: parameters,
Results: results,
TLSField: consts.TLSFieldName,
OperatorField: consts.GlobalTracerFieldName,
SnapshotInterface: consts.GlobalTracerSnapshotInterface,
})
tools.LogWithMethodEnhance("runtime", "", "newproc1", "support cross goroutine context propagating")
return true
}
return false
}