<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Thu May 23 00:41:14 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='211'>
<header><title>Add Full Stack Trace Capability</title><author address="mailto:robert_seeger@users.sourceforge.net">Robert Seeger</author><author address="mailto:rseeger00@aol.com">Robert Seeger</author><author address="mailto:dgp@users.sourceforge.net">Don Porter</author><status type='project' state='withdrawn' tclversion="8.5" vote='prior'>$Revision: 1.6 $</status><history></history><created day='10' month='aug' year='2004' /><keyword>Tcl</keyword><obsoleted tip='280'/></header>
<abstract>This TIP proposes adding a new subcommand to the <emph style="bold">info</emph> command to get a list of all the frames on the current stack, rather than the limited list returned by <emph style="bold">info level</emph>.</abstract>
<body><section title="Rationale">
<para>Currently, there is no way to get a list of all the frames in the current stack managed by <emph style="bold">Tcl_PushCallFrame()</emph> and <emph style="bold">Tcl_PopCallFrame()</emph>. The <emph style="bold">info level</emph> command does not contain frames that are callers of <emph style="bold">uplevel</emph>, reporting only the frames that are accessible via another <emph style="bold">uplevel</emph> command. There are times when the lack of information can have a negative impact on code design. The difference in information can be seen with the following code snippets:</para>
<verbatim><vline encoding='base64'>JSBwcm9jIGJvYiB7YXJnc30geyA=</vline><vline encoding='base64'>ICAgIGpvZSB7ZXhwYW5kfSRhcmdz</vline><vline encoding='base64'>ICB9</vline><vline encoding='base64'>JSBwcm9jIGpvZSB7YXJnc30gew==</vline><vline encoding='base64'>ICAgIHVwbGV2ZWwgMSBkYXZlIHtleHBhbmR9JGFyZ3M=</vline><vline encoding='base64'>ICB9</vline><vline encoding='base64'>JSBwcm9jIGRhdmUge2FyZ3N9IHs=</vline><vline encoding='base64'>ICAgIHB1dHMgIkxldmVsOiBbaW5mbyBsZXZlbF0i</vline><vline encoding='base64'>ICAgIGZvciB7c2V0IGkgW2luZm8gbGV2ZWxdfSB7ICRpID4gMCB9IHtpbmNyIGkgLTEgfSB7</vline><vline encoding='base64'>ICAgICAgcHV0cyAiJHtpfTogW2luZm8gbGV2ZWwgJGldIg==</vline><vline encoding='base64'>ICAgIH0=</vline><vline encoding='base64'>ICB9</vline><vline encoding='base64'>JSBib2IgeCB5IHo=</vline><vline encoding='base64'>TGV2ZWw6IDI=</vline><vline encoding='base64'>MjogZGF2ZSB4IHkgeg==</vline><vline encoding='base64'>MTogYm9iIHggeSB6</vline><vline encoding='base64'>JSBwcm9jIGRhdmUge2FyZ3N9IHs=</vline><vline encoding='base64'>ICAgIHB1dHMgIkxldmVsOiBbaW5mbyBmcmFtZV0iIA==</vline><vline encoding='base64'>ICAgIGZvciB7c2V0IGkgW2luZm8gZnJhbWVdfSB7ICRpID4gMCB9IHtpbmNyIGkgLTEgfSB7</vline><vline encoding='base64'>ICAgICAgcHV0cyAiJHtpfTogW2luZm8gZnJhbWUgJGldIg==</vline><vline encoding='base64'>ICAgIH0=</vline><vline encoding='base64'>ICB9</vline><vline encoding='base64'>JSBib2I=</vline><vline encoding='base64'>TGV2ZWw6IDM=</vline><vline encoding='base64'>MzogZGF2ZSB4IHkgeg==</vline><vline encoding='base64'>Mjogam9lIHggeSB6</vline><vline encoding='base64'>MTogYm9iIHggeSB6</vline></verbatim>
<para>There are 3 reasons I see for bringing forth this TIP: </para>
<enumerate><item.e index='1'><para>It&apos;s an introspection ability that is currently lacking, with no good reason for that lack.</para></item.e><item.e index='2'><para>The more information that is available to the programmer, the easier it is to accomplish a goal in a straightforward, easily maintainable way.</para></item.e><item.e index='3'><para>I have code in which the impact of not having this information available is visible.</para></item.e></enumerate>
<subsection title="Use Cases">
<para>There are two cases I have run into where the ability to query all frames on the stack would have been particularly useful.</para>
<enumerate><item.e index='1'><para><emph style="bold">TclTest</emph></para><para>The first case is with Tcltest, where the complete lack of ability to gain access to that information means it is impossible to gain information about a test without modifying the Tcltest code itself. Being able to find out the name of the current test would be very handy, especially in naming test procs and logging information. Currently, there is no way to find out the name of the currently executing test, due to the fact that the code for the test is <emph style="bold">uplevel</emph>ed and, hence, not visible via <emph style="bold">info level</emph>.</para></item.e><item.e index='2'><para><emph style="bold">TestStubs Package</emph></para><para>The TestStubs package provides the ability to temporarily redefine commands, in particular for stubbing out or replacing functionality in a test case. There is a command in the package called <emph style="bold">chain</emph>, which is used within the code replacing a command (or part of a command) to call the original definition of the command. For example, one could do:</para><verbatim><vline encoding='base64'>c3R1YnM6OnN0dWIgZW5zZW1ibGUgYXJyYXkgbmFtZXMgew==</vline><vline encoding='base64'>ICAgIHJldHVybiBbbHNvcnQgW3VwbGV2ZWwgMSBjaGFpbiBuYW1lcyAkYXJnc11d</vline><vline encoding='base64'>fQ==</vline></verbatim><para>However, since the <emph style="bold">chain</emph> command is (and should be) limited to only running from within a stub definition, it needs to call <emph style="bold">info level</emph> to find out if its caller is one of the stubbed commands, and what the name of that command is. With <emph style="bold">info level</emph>, it would not have access to the level that is running inside the stubbed procedure. Hence, either it cannot check this constraint, or stubs cannot be allowed to use <emph style="bold">uplevel</emph> when calling it (which means things like the above either cannot work, or need to be rewritten in a considerably less clear manner).</para></item.e></enumerate>
</subsection>
</section>
<section title="Proposed Change">
<para>I propose to add a new subcommand to the info command with the following syntax:</para>
<quote><emph style="bold">info frame</emph> ?<emph style="italic">level</emph>?</quote>
<para>The new functionality will provide access to all frames on the stack rather than the current limited subset. The information to do so already exists within the Interp object that all commands are passed, and the code needed to expose it differs in only a few aspects from that of <emph style="bold">info level</emph>.</para>
<para>This TIP does <emph style="italic">not</emph> propose to alter <emph style="bold">uplevel</emph> or <emph style="bold">upvar</emph> so that they can see these hidden levels.</para>
<subsection title="Child Interps">
<para>The current implementation of <emph style="italic">info level</emph> only returns levels up to the top of the stack for the current interpreter. Such an approach puts limitations on what information can be retrieved, but allows for a certain level of <emph style="italic">&quot;security&quot;</emph> when running code in child interps, especially safe interps.</para>
<para>Given the security considerations of safe interps, and consistancy with regards to what information is returned across multiple circumstances, the stack trace returned will only return information up to the top level of the current interp, the same limit <emph style="italic">info level</emph> is bound by. </para>
</subsection>
</section>
<section title="Implementation">
<para>An implementation patch is available on SourceForge [<url ref="http://sourceforge.net/tracker/?func=detail&amp;aid=1503647&amp;group_id=10894&amp;atid=310894"/>].</para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
<para>Please note that any correspondence to the author concerning this TIP is considered in the public domain unless otherwise specifically requested by the individual(s) authoring said correspondence. This is to allow information about the TIP to be placed in a public forum for discussion.</para>
</section>
</body></TIP>
