<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7233.28">
<TITLE>RE: [Python-Dev] Unifying trace and profile</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>I, Robert, wrote:<BR>
&gt; 1. Allow trace hooks to receive c_call, c_return,<BR>
&gt; and c_exception events (like profile does).<BR>
<BR>
and Nicholas Bastin replied:<BR>
&gt; I can easily make this modification.&nbsp; You can also<BR>
&gt; register the same bound method for trace and profile,<BR>
&gt; which sort of eliminates this problem.<BR>
<BR>
Wonderful! It looked easy. :)<BR>
<BR>
I worked around this by registering one function for trace, and another for profile. The profile function rejects any non-C event and then calls the trace function.<BR>
<BR>
Robert:<BR>
&gt; 3. Expose new sys.gettrace() and getprofile() methods,<BR>
&gt; so trace and profile functions that want to play nice<BR>
&gt; can call sys.settrace/setprofile(None) only if they<BR>
&gt; are the current hook.<BR>
<BR>
Nicholas:<BR>
&gt; Not a bad idea, although are you really running into<BR>
&gt; this problem a lot?<BR>
<BR>
Well, not &quot;a lot&quot;, as I don't expect I'll write very many debuggers in my lifetime ;) But it's important when you have multiple, different debugging systems running at once, either to take advantage of the strengths of each, or to debug a debugger.<BR>
<BR>
Bob:<BR>
&gt; 4. Make &quot;the same move&quot; that sys.exitfunc -&gt; atexit made<BR>
&gt; (from a single function to multiple functions via<BR>
&gt; registration), so multiple tracers/profilers can play<BR>
&gt; nice together.<BR>
<BR>
Nick:<BR>
&gt; It seems very unlikely that you'll want to have a trace<BR>
&gt; hook and profile hook installed at the same time, given<BR>
&gt; the extreme unreliability this will introduce into the<BR>
&gt; profiler.<BR>
<BR>
True; this request is partly driven by the differing capabilities of each (only profile can handle C events at the moment). Being able to compose debuggers as described above is another reason. Anything else is just the usual (often ignorable) desire for elegance.<BR>
<BR>
Bob:<BR>
&gt; 5. Allow the core to filter on the &quot;event&quot; arg before<BR>
&gt; hook(frame, event, arg) is called.<BR>
<BR>
Nick:<BR>
&gt; What do you mean by this, exactly?&nbsp; How would you use<BR>
&gt; this feature?<BR>
<BR>
As you hinted, I mean that call_trace would only call the trace function if the current event were in a list of &quot;events I want to monitor&quot;; that list of events could be supplied, for example, with a new sys.settrace(func[, events]) signature, with &quot;events&quot; deafulting to all events for backward compatibility. A single int could be used internally, where each bit represents one of the event types.<BR>
<BR>
This would be necessary if trace and profile were unified (see next). If they're not, it's less compelling.<BR>
<BR>
Bob:<BR>
&gt; 6. Unify tracing and profiling, which would remove a<BR>
&gt; lot of redundant code in ceval and sysmodule and free<BR>
&gt; up some space in the PyThreadState struct to boot.<BR>
<BR>
Nick:<BR>
&gt; The more events you throw in profiling makes it slow,<BR>
&gt; however.&nbsp; Line events, while a nice thing to have,<BR>
&gt; theoretically, would probably make a profiler useless.<BR>
<BR>
Sure. If trace functions can receive C events, then there's no need to add that to profiling. I guess I just see profiling as a &quot;stripped down&quot; version of the general trace architecture, and wonder if it couldn't be that in reality as well as appearance; that is,<BR>
profiling becomes tracing with the 'line' events ignored (before they reach back into your Python trace function and slow everything down). But I also note that the current hotshot uses PyEval_SetTrace &quot;if (self-&gt;lineevents)&quot;, and PyEval_SetProfile otherwise.<BR>
<BR>
Bob:<BR>
&gt; 7. As if the above isn't enough of a dream, it would be nice<BR>
&gt; to have a bytecode tracer, which didn't bother with the<BR>
&gt; f_lineno logic in maybe_call_line_trace, but just called<BR>
&gt; the hook on every instruction.<BR>
<BR>
Nick:<BR>
&gt; I'm working on one, but given how much time I've had to<BR>
&gt; work on my profiler in the last year, I'm not even going<BR>
&gt; to guess when I'll get a real shot at looking at that.<BR>
&gt;<BR>
&gt; My long-term goal is to eliminate profiling and tracing<BR>
&gt; from the core interpreter entirely and implement the<BR>
&gt; functionality in such a way that they don't cost you<BR>
&gt; when not in use (i.e., implement profilers and debuggers<BR>
&gt; which poke into the process from the outside, rather<BR>
&gt; than be supported natively through events).&nbsp; This isn't<BR>
&gt; impossible, but it's difficult because of the large<BR>
&gt; variety of platforms.&nbsp; I have access to most of them,<BR>
&gt; but again, my time is hugely constrained right now for<BR>
&gt; python development work.<BR>
<BR>
Ah. Sorry to hear that. :/ But no worries on my end; if only #1 can be done someday, I'll be extremely happy. Find me at PyCon, I'll buy you a drink. :)<BR>
<BR>
<BR>
Robert Brewer<BR>
System Architect<BR>
Amor Ministries<BR>
fumanchu@amor.org</FONT>
</P>

</BODY>
</HTML>