Commit 2547cb7d authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 69174210
......@@ -416,8 +416,8 @@ func {{.Name}}_Attach(pg *tracing.ProbeGroup, probe func({{.ArgvTyped}})) *traci
// traceEventImportTmpl is code template generated for importing one trace event
var traceEventImportTmpl = template.Must(template.New("traceimport").Parse(`
//go:linkname {{.Pkg.Name}}_{{.Name}}_Attach {{.Pkg.Path}}.{{.Name}}_Attach
func {{.Pkg.Name}}_{{.Name}}_Attach(*tracing.ProbeGroup, func({{.ArgvTypedRelativeTo .ImporterPkg}})) *tracing.Probe
//go:linkname {{.Pkg.Pkgi.Pkg.Name}}_{{.Name}}_Attach {{.Pkg.Pkgi.Pkg.Path}}.{{.Name}}_Attach
func {{.Pkg.Pkgi.Pkg.Name}}_{{.Name}}_Attach(*tracing.ProbeGroup, func({{.ArgvTypedRelativeTo .ImporterPkg}})) *tracing.Probe
`))
// magic begins all files generated by gotrace
......@@ -538,14 +538,25 @@ func findPackageNoZTrace(ctxt *build.Context, importPath, fromDir string, mode b
}
*/
// tracegen generates code according to tracing directives in a package @ pkgpath
//
// ctxt is build context for discovering packages
// cwd is "current" directory for resolving local imports (e.g. packages like "./some/package")
func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
// TODO test-only with .TestGoFiles .XTestGoFiles
// filter-out ztrace* files when disovering packages
type Program struct {
// list of loader.Programs in use
//
// We generally need to have several programs because a package can
// trace:import another package which is not otherwise imported by
// original program.
//
// Since go/loader does not support incrementally augmenting loaded
// program with more packages we work-around it with having several
// progs.
progv []*loader.Program
// config for loading programs
loaderConf *loader.Config
}
func NewProgram(ctxt *build.Context, cwd string) *Program {
// adjust build context to filter-out ztrace* files when disovering packages
//
// we don't load what should be generated by us for 2 reasons:
// - code generated could be wrong with older version of the
......@@ -568,23 +579,54 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
return okv, err
}
// XXX text
conf := loader.Config{
p := &Program{}
p.loaderConf = &loader.Config{
ParserMode: parser.ParseComments,
TypeCheckFuncBodies: func(path string) bool { return false },
Build: &ctxtNoZTrace,
Cwd: cwd,
// FindPackage: findPackageNoZTrace,
}
conf.Import(pkgpath)
// load package + all its imports
lprog, err := conf.Load()
return p
}
// Import imports a package and returns associated package info and program under which it was loaded
func (p *Program) Import(pkgpath string) (prog *loader.Program, pkgi *loader.PackageInfo, err error) {
// let's see - maybe it is already there
for _, prog := range p.progv {
pkgi := prog.Package(pkgpath)
if pkgi != nil {
return prog, pkgi, nil
}
}
// not found - we have to load new program rooted at pkgpath
p.loaderConf.ImportPkgs = nil
p.loaderConf.Import(pkgpath)
prog, err = p.loaderConf.Load()
if err != nil {
return err
return nil, nil, err
}
pkgi := lprog.InitialPackages()[0]
p.progv = append(p.progv, prog)
pkgi = prog.InitialPackages()[0]
return prog, pkgi, nil
}
// tracegen generates code according to tracing directives in a package @ pkgpath
//
// ctxt is build context for discovering packages
// cwd is "current" directory for resolving local imports (e.g. packages like "./some/package")
func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
// TODO test-only with .TestGoFiles .XTestGoFiles
P := NewProgram(ctxt, cwd)
lprog, pkgi, err := P.Import(pkgpath)
if err != nil {
return err
}
// determine package directory
if len(pkgi.Files) == 0 {
......@@ -638,13 +680,12 @@ func tracegen(pkgpath string, ctxt *build.Context, cwd string) error {
for _, timport := range tpkg.Importv {
text.emit("\n// traceimport: %v", timport.PkgPath)
impPkgi := lprog.Package(timport.PkgPath)
if impPkgi == nil {
// TODO do not require vvv
return fmt.Errorf("%v: package %s must be also regularly imported", timport.Pos, timport.PkgPath)
impProg, impPkgi, err := P.Import(timport.PkgPath)
if err != nil {
return fmt.Errorf("%v: error trace-importing %s: %v", timport.Pos, timport.PkgPath, err)
}
impPkg, err := packageTrace(lprog, impPkgi)
impPkg, err := packageTrace(impProg, impPkgi)
if err != nil {
return err // XXX err ctx
}
......
// Code generated by lab.nexedi.com/kirr/go123/tracing/cmd/gotrace; DO NOT EDIT.
package pkg2
// code generated for tracepoints
import (
"lab.nexedi.com/kirr/neo/go/xcommon/tracing"
"unsafe"
"a/pkg1"
"net/url"
)
// traceevent: traceDoSomething(i, j int, q string) XXX better raw .Text (e.g. comments)
type _t_traceDoSomething struct {
tracing.Probe
probefunc func(i, j int, q string)
}
var _traceDoSomething *_t_traceDoSomething
func traceDoSomething(i, j int, q string) {
if _traceDoSomething != nil {
_traceDoSomething_run(i, j, q)
}
}
func _traceDoSomething_run(i, j int, q string) {
for p := _traceDoSomething; p != nil; p = (*_t_traceDoSomething)(unsafe.Pointer(p.Next())) {
p.probefunc(i, j, q)
}
}
func traceDoSomething_Attach(pg *tracing.ProbeGroup, probe func(i, j int, q string)) *tracing.Probe {
p := _t_traceDoSomething{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceDoSomething)), &p.Probe)
return &p.Probe
}
// traceimport: a/pkg1
//go:linkname pkg1_traceDoSomething_Attach a/pkg1.traceDoSomething_Attach
func pkg1_traceDoSomething_Attach(*tracing.ProbeGroup, func(topic string)) *tracing.Probe
//go:linkname pkg1_traceNewT_Attach a/pkg1.traceNewT_Attach
func pkg1_traceNewT_Attach(*tracing.ProbeGroup, func(t *pkg1.T)) *tracing.Probe
//go:linkname pkg1_traceNewTPre_Attach a/pkg1.traceNewTPre_Attach
func pkg1_traceNewTPre_Attach(*tracing.ProbeGroup, func()) *tracing.Probe
//go:linkname pkg1_traceURLParsed_Attach a/pkg1.traceURLParsed_Attach
func pkg1_traceURLParsed_Attach(*tracing.ProbeGroup, func(u *url.URL)) *tracing.Probe
// Code generated by lab.nexedi.com/kirr/go123/tracing/cmd/gotrace; DO NOT EDIT.
// empty .s so `go build` does not use -complete for go:linkname to work
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment