<div dir="ltr">Hello,<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Sep 21, 2015 at 12:02 PM, Ulf Wiger <span dir="ltr"><<a href="mailto:ulf@feuerlabs.com" target="_blank">ulf@feuerlabs.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>I have had some success using an event/[2,3] function for lightweight debugging, where the functions event(Line, Event) and event(Line Event, State) exist only to be traced. A simple way to generalize this would be to create ‘null’ BIFs: erlang:trace_event(Info, Event) -> ok, erlang:trace_event(Info, Event, State) -> ok (just a trace_event/1 would of course suffice). If not traced, these functions do nothing; when traced, they emit trace info similar to io:format debugging.</div><div><br></div><div>See e.g. the locks application:</div><div><a href="https://github.com/uwiger/locks/blob/master/src/locks_leader.erl#L140" target="_blank">https://github.com/uwiger/locks/blob/master/src/locks_leader.erl#L140</a></div><div><a href="https://github.com/uwiger/locks/blob/master/src/locks_leader.erl#L823" target="_blank">https://github.com/uwiger/locks/blob/master/src/locks_leader.erl#L823</a></div><div><br></div></div></blockquote><div><br></div><div>So it should be possible define your own trace probes (for lack of a better word) in erlang code? That is a very good point. For dtrace we have the dyntrace module that you can put calls to with very little overhead. Maybe something similar can be done for Erlang tracing? I don't think we should step on the toes of logging though, as those (in my opinion) should be two different things.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>The ?debug/[1,2] macro is used to also include line numbers. One could perhaps imagine such a macro existing in dbg, but putting an event() function in dbg as well forces a remote call even when tracing is not enabled.</div></div></blockquote><div><br></div><div>Including the line number could be useful. Maybe adding it in the match spec for the given trace pattern? Much in the same way as {message,{process_dump}} works today?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>I’ve found this extremely useful not least when enabled during multi-node test suite execution, using ttb to merge logs and a final pretty-printing step to produce a text log best viewed with emacs's Erlang syntax highlighting. See <a href="https://github.com/uwiger/locks/blob/master/src/locks_ttb.erl" target="_blank">https://github.com/uwiger/locks/blob/master/src/locks_ttb.erl</a> (Logs fetched only if test case fails).</div><div><br></div></div></blockquote><div><br></div><div>I had completely forgot about the ttb. Will have to read up on what you can do with it.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div></div><div>One might fantasize about enabling migration from io:format() debugging to this, ideally by simply rewriting the debug macro: a handy wrapper that simulates the original printouts. There are some problems with this, so I’ve chosen not to go there.</div><div><br></div><div>To further generalize the issue …</div><div><br></div><div>What we ended up with at Ericsson was a variety of techniques for getting the most out of tracing:</div><div><br></div><div>- A script that inserted a ?DBG macro after each ->. This was a conditional debug printout, but could have been a trace event as above. The feature was to log the ‘branching’ in the code, e.g. noting which case function or receive clause was actually selected.</div><div>- Consistently breaking out case clauses etc as separate functions (since function calls can be traced). See e.g. the diameter application in OTP for examples of this style of coding.</div></div></blockquote><div><br></div><div>Tracing on all branches would indeed be neat to have. Not sure if it ever will be possible to do in the emulator without instrumenting the code beforehand.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>I think there is room for revisiting the ‘et’ concept in this context. The thing about ‘et’ was that it allowed for a ‘model-level’ trace, complete with sequence diagram presentation. Its main drawback was that few figured out how to use it. But I think the idea is brilliant: to be able to dynamically extract ‘model markers’ from executing code and displaying it in a way that can tie back to the conceptual design.</div><div><br></div><div><a href="http://jlouisramblings.blogspot.se/2011/10/using-event-tracer-tool-set-in-erlang.html" target="_blank">http://jlouisramblings.blogspot.se/2011/10/using-event-tracer-tool-set-in-erlang.html</a></div><div><a href="http://souja.net/2009/04/making-sense-of-erlangs-event-tracer" target="_blank">http://souja.net/2009/04/making-sense-of-erlangs-event-tracer</a></div><div><a href="http://sysmagazine.com/posts/131140/" target="_blank">http://sysmagazine.com/posts/131140/</a></div></div></blockquote><div><br></div><div>yet another tool I had forgotten about :) thanks for reminder!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Lastly, TTB has been greatly improved (ahem…) and is extremely useful for multi-node tracing. When improving the DBG documentation, make sure to show how TTB and DBG work together and what their respective roles are.</div></div></blockquote><div><br></div><div>We'll keep that in mind.</div><div><br></div><div>Thanks for your input!</div></div></div></div>