Commit b8258107 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent b873512b
......@@ -22,7 +22,8 @@
// XXX text
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 (
"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] }
func (v byPkgPath) Len() int { return len(v) }
// progImporter is types.Importer that imports packages from loaded loader.Program
type progImporter {
type progImporter struct {
prog *loader.Program
}
......@@ -108,9 +108,13 @@ func (pi *progImporter) Import(path string) (*types.Package, error) {
// parseTraceEvent parses trace event definition into traceEvent
// 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") {
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
......@@ -128,43 +132,61 @@ func parseTraceEvent(pkgi *loader.PackageInfo, text string) (*traceEvent, error)
if imp.Name != nil {
impline += imp.Name.Name + " "
}
impline += `"` + imp.Path.Value + `"`
buf.emit("%s", impline)
impline += imp.Path.Value
buf.emit("\t%s", impline)
}
buf.emit("\t. %q", pkgi.Pkg.Path)
buf.emit("")
buf.emit("\t. %q", pkgi.Pkg.Path())
buf.emit(")")
// func itself
buf.emit("\nfunc " + text)
// XXX add all imports from file of trace event definition context
fset := token.NewFileSet() // XXX
filename := "tracefunc.go" // XXX -> original_file.go:<lineno> ?
f, err := parser.ParseFile(fset, filename, text, 0)
// now parse/typecheck
tfset := token.NewFileSet()
filename := fmt.Sprintf("%v:%v+trace:event %v", pos.Filename, pos.Line, text)
println("--------")
println(buf.String())
println("--------")
tf, err := parser.ParseFile(tfset, filename, buf.String(), 0)
if err != nil {
return nil, err
return nil, err // should already have pos' as prefix
}
if len(f.Decls) != 1 {
return nil, fmt.Errorf("trace event must be func-like")
if len(tf.Decls) != 1 {
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 {
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) ?
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
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
return &traceEvent{pkgi, declf}, nil
return &traceEvent{pkgi, declf}, nil // XXX + tinfo, tpkg, ...
}
// packageTrace returns tracing information about a package
......@@ -196,9 +218,9 @@ func packageTrace(lprog *loader.Program, pkgi *loader.PackageInfo) *Package {
directive, arg := textv[0], textv[1]
switch directive {
case "//trace:event":
event, err := parseTraceEvent(pkgi, arg)
event, err := parseTraceEvent(lprog, pkgi, file, pos, arg)
if err != nil {
log.Fatalf("%v: %v", pos, err)
log.Fatal(err)
}
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