211.md at [88e91886b2]

Login

File tip/211.md artifact 8841ec258e part of check-in 88e91886b2


# 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.