# TIP 211: Add Full Stack Trace Capability
Author: Robert Seeger <[email protected]>
Author: Robert Seeger <[email protected]>
Author: Don Porter <[email protected]>
State: Withdrawn
Type: Project
Vote: Pending
Created: 10-Aug-2004
Post-History:
Keywords: Tcl
Tcl-Version: 8.5
Obsoleted-By: 280
-----
# Abstract
This TIP proposes adding a new subcommand to the **info** command
to get a list of all the frames on the current
stack, rather than the limited list returned
by **info level**.
# Rationale
Currently, there is no way to get a list of all the frames in
the current stack managed by **Tcl\_PushCallFrame\(\)** and
**Tcl\_PopCallFrame\(\)**. The **info level** command does not
contain frames that are callers of **uplevel**, reporting only the
frames that are accessible via another **uplevel**
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:
% proc bob {args} {
joe {expand}$args
}
% proc joe {args} {
uplevel 1 dave {expand}$args
}
% proc dave {args} {
puts "Level: [info level]"
for {set i [info level]} { $i > 0 } {incr i -1 } {
puts "${i}: [info level $i]"
}
}
% bob x y z
Level: 2
2: dave x y z
1: bob x y z
% proc dave {args} {
puts "Level: [info frame]"
for {set i [info frame]} { $i > 0 } {incr i -1 } {
puts "${i}: [info frame $i]"
}
}
% bob
Level: 3
3: dave x y z
2: joe x y z
1: bob x y z
There are 3 reasons I see for bringing forth this TIP:
1. It's an introspection ability that is currently lacking, with no
good reason for that lack.
2. The more information that is available to the programmer, the
easier it is to accomplish a goal in a straightforward, easily
maintainable way.
3. I have code in which the impact of not having this information
available is visible.
## Use Cases
There are two cases I have run into where the ability to query all
frames on the stack would have been particularly useful.
1. **TclTest**
> 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 **uplevel**ed and, hence, not visible via **info
level**.
2. **TestStubs Package**
> 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 **chain**, 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:
stubs::stub ensemble array names {
return [lsort [uplevel 1 chain names $args]]
}
> However, since the **chain** command is \(and should be\) limited
to only running from within a stub definition, it needs to call
**info level** to find out if its caller is one of the stubbed
commands, and what the name of that command is. With **info
level**, 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 **uplevel** when
calling it \(which means things like the above either cannot work,
or need to be rewritten in a considerably less clear manner\).
# Proposed Change
I propose to add a new subcommand to the info command with the
following syntax:
> **info frame** ?_level_?
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
**info level**.
This TIP does _not_ propose to alter **uplevel** or **upvar** so
that they can see these hidden levels.
## Child Interps
The current implementation of _info level_ 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 _"security"_ when running code in child interps, especially safe interps.
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 _info level_ is bound by.
# Implementation
An implementation patch is available on SourceForge
<http://sourceforge.net/tracker/?func=detail&aid=1503647&group_id=10894&atid=310894> .
# Copyright
This document has been placed in the public domain.
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.