func()

in tools/go-agent/instrument/plugins/instrument.go [344:454]


func (i *Instrument) copyOperatorsFS(context *rewrite.Context, baseDir, packageName string) ([]string, error) {
	result := make([]string, 0)
	var debugBaseDir string
	for _, dir := range rewrite.OperatorDirs {
		entries, err := core.FS.ReadDir(dir)
		if err != nil {
			return nil, err
		}
		files := make([]*rewrite.FileInfo, 0)
		if i.compileOpts.DebugDir != "" {
			debugBaseDir = filepath.Join(i.compileOpts.DebugDir, "plugins", "core", dir)
		}

		for _, entry := range entries {
			if strings.HasSuffix(entry.Name(), "_test.go") || strings.HasSuffix(entry.Name(), "_test_base.go") {
				continue
			}
			file, err1 := fs.ReadFile(core.FS, filepath.Join(dir, entry.Name()))
			if err1 != nil {
				return nil, err1
			}

			var rewriteFile *rewrite.FileInfo
			if debugBaseDir != "" {
				rewriteFile = rewrite.NewFileWithDebug(dir, entry.Name(), string(file), debugBaseDir)
			} else {
				rewriteFile = rewrite.NewFile(dir, entry.Name(), string(file))
			}
			files = append(files, rewriteFile)
		}

		rewrited, err := context.MultipleFilesWithWritten("skywalking_agent_core_", baseDir, filepath.Base(dir), files)
		if err != nil {
			return nil, err
		}
		result = append(result, rewrited...)
	}

	// write extra file for link the operator function
	tmpFiles, err := tools.WriteMultipleFile(baseDir, map[string]string{
		"skywalking_agent_core_linker.go": tools.ExecuteTemplate(`package {{.PackageName}}

import (
	_ "unsafe"
)

//go:linkname {{.OperatorGetLinkMethod}} {{.OperatorGetLinkMethod}}
var {{.OperatorGetLinkMethod}} func() interface{}

//go:linkname {{.OperatorAppendInitNotifyLinkMethod}} {{.OperatorAppendInitNotifyLinkMethod}}
var {{.OperatorAppendInitNotifyLinkMethod}} func(func())

//go:linkname {{.MetricsRegisterAppenderLinkMethod}} {{.MetricsRegisterAppenderLinkMethod}}
var {{.MetricsRegisterAppenderLinkMethod}} func(interface{})

//go:linkname {{.MetricsHookAppenderLinkMethod}} {{.MetricsHookAppenderLinkMethod}}
var {{.MetricsHookAppenderLinkMethod}} func(func())

func init() {
	if {{.OperatorGetLinkMethod}} != nil {
		{{.OperatorGetRealMethod}} = func() {{.OperatorTypeName}} {
			tmpOp := {{.OperatorGetLinkMethod}}()
			if tmpOp == nil {
				return nil
			}
			if opVal, ok := tmpOp.({{.OperatorTypeName}}); ok {
				return opVal
			}
			return nil
		}
	}
	if {{.OperatorAppendInitNotifyLinkMethod}} != nil {
		{{.OperatorAppendInitNotifyRealMethod}} = {{.OperatorAppendInitNotifyLinkMethod}}
	}
	if {{.MetricsRegisterAppenderLinkMethod}} != nil {
		{{.MetricsRegisterAppenderRealMethod}} = {{.MetricsRegisterAppenderLinkMethod}}
	}
	if {{.MetricsHookAppenderLinkMethod}} != nil {
		{{.MetricsHookAppenderRealMethod}} = {{.MetricsHookAppenderLinkMethod}}
	}
}
`, struct {
			PackageName                        string
			OperatorGetLinkMethod              string
			OperatorGetRealMethod              string
			OperatorTypeName                   string
			OperatorAppendInitNotifyLinkMethod string
			OperatorAppendInitNotifyRealMethod string
			MetricsRegisterAppenderLinkMethod  string
			MetricsRegisterAppenderRealMethod  string
			MetricsHookAppenderLinkMethod      string
			MetricsHookAppenderRealMethod      string
		}{
			PackageName:                        packageName,
			OperatorGetLinkMethod:              consts.GlobalTracerGetMethodName,
			OperatorGetRealMethod:              rewrite.GlobalOperatorRealGetMethodName,
			OperatorTypeName:                   rewrite.GlobalOperatorTypeName,
			OperatorAppendInitNotifyLinkMethod: consts.GlobalTracerInitAppendNotifyMethodName,
			OperatorAppendInitNotifyRealMethod: rewrite.GlobalOperatorRealAppendTracerInitNotify,
			MetricsRegisterAppenderLinkMethod:  consts.MetricsRegisterAppendMethodName,
			MetricsRegisterAppenderRealMethod:  rewrite.MetricsRegisterAppender,
			MetricsHookAppenderLinkMethod:      consts.MetricsHookAppendMethodName,
			MetricsHookAppenderRealMethod:      rewrite.MetricsCollectAppender,
		}),
	})
	if err != nil {
		return nil, err
	}
	result = append(result, tmpFiles...)
	return result, nil
}