Commit b8258107 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent b873512b
...@@ -22,7 +22,8 @@ ...@@ -22,7 +22,8 @@
// XXX text // XXX text
package neo package neo
//go:generate sh -c "go run ../xcommon/tracing/cmd/gotracegen/gotracegen.go ." // XXX gotrace ... -> gotrace gen ...
//go:generate sh -c "go run ../xcommon/tracing/cmd/gotrace/gotrace.go ."
import ( import (
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
......
...@@ -92,7 +92,7 @@ func (v byPkgPath) Swap(i, j int) { v[i], v[j] = v[j], v[i] } ...@@ -92,7 +92,7 @@ func (v byPkgPath) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
func (v byPkgPath) Len() int { return len(v) } func (v byPkgPath) Len() int { return len(v) }
// progImporter is types.Importer that imports packages from loaded loader.Program // progImporter is types.Importer that imports packages from loaded loader.Program
type progImporter { type progImporter struct {
prog *loader.Program prog *loader.Program
} }
...@@ -108,9 +108,13 @@ func (pi *progImporter) Import(path string) (*types.Package, error) { ...@@ -108,9 +108,13 @@ func (pi *progImporter) Import(path string) (*types.Package, error) {
// parseTraceEvent parses trace event definition into traceEvent // parseTraceEvent parses trace event definition into traceEvent
// text is text argument after "//trace:event " // text is text argument after "//trace:event "
func parseTraceEvent(pkgi *loader.PackageInfo, text string) (*traceEvent, error) { func parseTraceEvent(prog *loader.Program, pkgi *loader.PackageInfo, srcfile *ast.File, pos token.Position, text string) (*traceEvent, error) {
posErr := func(format string, argv ...interface{}) error {
return fmt.Errorf("%v: "+format, append([]interface{}{pos}, argv...)...)
}
if !strings.HasPrefix(text, "trace") { if !strings.HasPrefix(text, "trace") {
return nil, fmt.Errorf("trace event must start with \"trace\"") // XXX pos return nil, posErr("trace event must start with \"trace\"")
} }
// prepare artificial package with trace event definition as func declaration // prepare artificial package with trace event definition as func declaration
...@@ -128,43 +132,61 @@ func parseTraceEvent(pkgi *loader.PackageInfo, text string) (*traceEvent, error) ...@@ -128,43 +132,61 @@ func parseTraceEvent(pkgi *loader.PackageInfo, text string) (*traceEvent, error)
if imp.Name != nil { if imp.Name != nil {
impline += imp.Name.Name + " " impline += imp.Name.Name + " "
} }
impline += `"` + imp.Path.Value + `"` impline += imp.Path.Value
buf.emit("%s", impline) buf.emit("\t%s", impline)
} }
buf.emit("\t. %q", pkgi.Pkg.Path) buf.emit("")
buf.emit("\t. %q", pkgi.Pkg.Path())
buf.emit(")") buf.emit(")")
// func itself // func itself
buf.emit("\nfunc " + text) buf.emit("\nfunc " + text)
// XXX add all imports from file of trace event definition context // now parse/typecheck
fset := token.NewFileSet() // XXX tfset := token.NewFileSet()
filename := "tracefunc.go" // XXX -> original_file.go:<lineno> ? filename := fmt.Sprintf("%v:%v+trace:event %v", pos.Filename, pos.Line, text)
f, err := parser.ParseFile(fset, filename, text, 0) println("--------")
println(buf.String())
println("--------")
tf, err := parser.ParseFile(tfset, filename, buf.String(), 0)
if err != nil { if err != nil {
return nil, err return nil, err // should already have pos' as prefix
} }
if len(f.Decls) != 1 { if len(tf.Decls) != 1 {
return nil, fmt.Errorf("trace event must be func-like") return nil, posErr("trace event must be func-like")
} }
declf, ok := f.Decls[0].(*ast.FuncDecl) declf, ok := tf.Decls[0].(*ast.FuncDecl)
if !ok { if !ok {
return nil, fmt.Errorf("trace event must be func-like, not %v", f.Decls[0]) return nil, posErr("trace event must be func-like, not %v", tf.Decls[0])
} }
// XXX ok to allow methods (declf.Recv != nil) ? // XXX ok to allow methods (declf.Recv != nil) ?
if declf.Type.Results != nil { if declf.Type.Results != nil {
return nil, fmt.Errorf("trace event must not return results") return nil, posErr("trace event must not return results")
} }
// typecheck prepared package to get trace func argument types // typecheck prepared package to get trace func argument types
conf := types.Config{
Importer: &progImporter{prog},
// we took imports from original source file verbatim,
// but most of them probably won't be used.
DisableUnusedImportCheck: true,
}
tinfo := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
tpkg, err := conf.Check("xxx", tfset, []*ast.File{tf}, tinfo)
if err != nil {
return nil, err // should already have pos' as prefix
}
Importer: &progImporter{lprog} _ = tpkg
// XXX +pos // XXX +pos
return &traceEvent{pkgi, declf}, nil return &traceEvent{pkgi, declf}, nil // XXX + tinfo, tpkg, ...
} }
// packageTrace returns tracing information about a package // packageTrace returns tracing information about a package
...@@ -196,9 +218,9 @@ func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package { ...@@ -196,9 +218,9 @@ func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package {
directive, arg := textv[0], textv[1] directive, arg := textv[0], textv[1]
switch directive { switch directive {
case "//trace:event": case "//trace:event":
event, err := parseTraceEvent(pkgi, arg) event, err := parseTraceEvent(lprog, pkgi, file, pos, arg)
if err != nil { if err != nil {
log.Fatalf("%v: %v", pos, err) log.Fatal(err)
} }
eventv = append(eventv, event) eventv = append(eventv, event)
......
// Code generated by lab.nexedi.com/kirr/go123/tracing/cmd/gotrace; DO NOT EDIT.
package pipenet
// code generated for tracepoints
import (
"lab.nexedi.com/kirr/neo/go/xcommon/tracing"
"unsafe"
)
// traceevent: traceAccept(conn <nil>) XXX better raw .Text (e.g. comments)
type _t_traceAccept struct {
tracing.Probe
probefunc func(conn <nil>)
}
var _traceAccept *_t_traceAccept
func traceAccept(conn <nil>) {
if _traceAccept != nil {
_traceAccept_run(conn)
}
}
func _traceAccept_run(conn <nil>) {
for p := _traceAccept; p != nil; p = (*_t_traceAccept)(unsafe.Pointer(p.Next())) {
p.probefunc(conn)
}
}
func traceAccept_Attach(pg *tracing.ProbeGroup, probe func(conn <nil>)) *tracing.Probe {
p := _t_traceAccept{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceAccept)), &p.Probe)
return &p.Probe
}
// traceevent: traceDial(addr <nil>) XXX better raw .Text (e.g. comments)
type _t_traceDial struct {
tracing.Probe
probefunc func(addr <nil>)
}
var _traceDial *_t_traceDial
func traceDial(addr <nil>) {
if _traceDial != nil {
_traceDial_run(addr)
}
}
func _traceDial_run(addr <nil>) {
for p := _traceDial; p != nil; p = (*_t_traceDial)(unsafe.Pointer(p.Next())) {
p.probefunc(addr)
}
}
func traceDial_Attach(pg *tracing.ProbeGroup, probe func(addr <nil>)) *tracing.Probe {
p := _t_traceDial{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceDial)), &p.Probe)
return &p.Probe
}
// traceevent: traceListen(laddr <nil>) XXX better raw .Text (e.g. comments)
type _t_traceListen struct {
tracing.Probe
probefunc func(laddr <nil>)
}
var _traceListen *_t_traceListen
func traceListen(laddr <nil>) {
if _traceListen != nil {
_traceListen_run(laddr)
}
}
func _traceListen_run(laddr <nil>) {
for p := _traceListen; p != nil; p = (*_t_traceListen)(unsafe.Pointer(p.Next())) {
p.probefunc(laddr)
}
}
func traceListen_Attach(pg *tracing.ProbeGroup, probe func(laddr <nil>)) *tracing.Probe {
p := _t_traceListen{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceListen)), &p.Probe)
return &p.Probe
}
// traceevent: traceNew(name <nil>) XXX better raw .Text (e.g. comments)
type _t_traceNew struct {
tracing.Probe
probefunc func(name <nil>)
}
var _traceNew *_t_traceNew
func traceNew(name <nil>) {
if _traceNew != nil {
_traceNew_run(name)
}
}
func _traceNew_run(name <nil>) {
for p := _traceNew; p != nil; p = (*_t_traceNew)(unsafe.Pointer(p.Next())) {
p.probefunc(name)
}
}
func traceNew_Attach(pg *tracing.ProbeGroup, probe func(name <nil>)) *tracing.Probe {
p := _t_traceNew{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceNew)), &p.Probe)
return &p.Probe
}
// traceevent: traceNewHost(host <nil>) XXX better raw .Text (e.g. comments)
type _t_traceNewHost struct {
tracing.Probe
probefunc func(host <nil>)
}
var _traceNewHost *_t_traceNewHost
func traceNewHost(host <nil>) {
if _traceNewHost != nil {
_traceNewHost_run(host)
}
}
func _traceNewHost_run(host <nil>) {
for p := _traceNewHost; p != nil; p = (*_t_traceNewHost)(unsafe.Pointer(p.Next())) {
p.probefunc(host)
}
}
func traceNewHost_Attach(pg *tracing.ProbeGroup, probe func(host <nil>)) *tracing.Probe {
p := _t_traceNewHost{probefunc: probe}
tracing.AttachProbe(pg, (**tracing.Probe)(unsafe.Pointer(&_traceNewHost)), &p.Probe)
return &p.Probe
}
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