Hello, I wrote (rather derived from the stdlib) a reentrant Parser for the 
Go trace files, so I could stream partial events as they are returned from 
runtime.ReadTrace(). After learning about the format and reading the 
go15trace design doc everything makes sense. I've noticed that 
runtime.traceEvString/traceEvStack are not written until the trace is 
shutting down. A hashtable/map is kept for the stack traces and strings and 
it greatly condenses the trace but does have the caveat that a stack trace 
is not complete until it is stopped. I can reliably work around getting the 
traceEvString data by ignoring the seq and correlating the PC with 
FuncForPC but can't think of a similar work around for traceEvStack. Is 
there a way to do this?

As a quick hack I added a flush() method to traceStackTable and flush 
before waiting for trace to be ready to dequeue to get the behavior I want. 
Would there be any interest of a proper implementation of this? The exact 
proposal being to send new items in traceStackTable and the string map to 
the buffer queue so ReadTrace can pick them up as they are first seen. They 
can still be tracked the same way to prevent duplication of strings/stacks 
in the trace. Based on my testing and limited understanding of ReadData, it 
will send pending data in the fullHead traceBufPtr, there is not a 
threshold of N buffers before writes. But if I'm incorrect may need 
modified to have runtime.ReadTrace() always flush any available trace data 
or a runtime(|/trace).FlushTrace() so a user could signal this explicitly. 
This doesn't affect any of the tooling for traces, they don't have a 
concept of a footer, just a header and events so they will continue to work 
as is.

Use cases could be numerous, you could stream events of functions / 
goroutines as they are created / stopped with line numbers and files in 
real time for debugging. Basically anything that you get from go tool 
trace, but (near) real time which may enable some neat visualization tools. 
What sparked my interest is probably not as interesting to others, but I 
was issuing tokens to track counts/ordering of functions by wrapping a 
inner func. The caveat here being function signatures have to match and it 
doesn't look very clean and has edge cases for reliability and is limited 
to "was this called and how many times".. but it is a bit simpler to reason 
with then complicated signaling / sync prims. With a parser for trace files 
at runtime I can Watch(fn interface{}) any function during a test by taking 
the func ptr (reflect.ValueOf(fn).Pointer()) and calling FuncForPC. Then 
using the file/line/name and correlating it to the trace to validate all 
kinds of additional data points available in trace events. Might be a 
better way to do this, it's just an experiment but it works.

For now I can simply Start() and Stop() at the beginning and end of each 
test for my own use case, so if this makes no sense to anyone else, no 
worries thanks for reading regardless.

-Chris

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to