Stack traces: Difference between revisions
Content deleted Content added
PascalABC.NET |
|||
(15 intermediate revisions by 8 users not shown) | |||
Line 19:
The provided solution is specific to the [[GNAT]] Ada compiler. Further it is restricted to some platforms. See the description of the package GNAT.Traceback supplied with [[GNAT]]. The switch -g must be used in order to include debug information into the executable.
<
with GNAT.Traceback;
with GNAT.Traceback.Symbolic;
Line 49:
begin
Outer (2,3,5);
end Test_Stack_Trace;</
Sample output:
<pre>
Line 70:
ListLines can be turned on or off... with:
<br> ListLines, On|Off
<
return
Line 86:
msgbox, variable bindings
}
#Persistent</
Output:
<
006: Return,g()
011: ListLines (0.05)
Line 102:
0[1 of 3]: 0
ErrorLevel[1 of 3]: 0
</syntaxhighlight>
=={{header|BASIC}}==
Line 183:
In order to be able to see the symbols, we need to link with an option telling to export symbols names in the dynamic section (for ELF and targets supporting it); for gcc, it means using the option <tt>-rdynamic</tt> (or <tt>-export-dynamic</tt> in the GNU linker). Otherwise we see only addresses. Static functions will always have their names "hidden".
<
#include <stdlib.h>
#include <unistd.h>
Line 221:
outer(2,3,5);
return EXIT_SUCCESS;
}</
Sample output on my system:
Line 251:
'''==> stack_trace.h <=='''
<syntaxhighlight lang="c">
/* stack_trace.c - macros for hinting/tracing where a program crashed
on a system _without_ any form of debugger.
Line 330:
#define END }
#endif</
'''==> stack_trace.c <=='''
<
#include <stddef.h>
Line 416:
print_indent(); fprintf(stderr, "--- (depth %d) ---\n", stack_trace.stack.depth);
}
}</
'''==> stack_trace_test.c <=='''
Line 422:
The following code demonstrates the usage of the macros. Note that the initial and last curly brackets have been changed to BEGIN(procedure_name) and END. This is sometimes called '''macro magic''' and is unfashionable.
<
#include <stdlib.h>
Line 450:
stack_trace.on = FALSE;
RETURN(EXIT_SUCCESS);
END</
{{out}}
Line 469:
=={{header|C sharp|C#}}==
<
using System.Diagnostics;
Line 493:
Outer();
}
}</
Sample output:
<syntaxhighlight lang="text">at Program.Inner()
at Program.Middle()
at Program.Outer()
at Program.Main()</
=={{header|Clojure}}==
Line 505:
[http://docs.oracle.com/javase/8/docs/api/java/lang/management/ThreadMXBean.html ThreadMXBean] can be used to show you the stack of all live threads.
<
(doall
(map println (.dumpAllThreads (java.lang.management.ManagementFactory/getThreadMXBean) false false)))
</syntaxhighlight>
{{out}}
<pre>
Line 529:
Here we use SWANK, which a component of SLIME, a Common Lisp IDE (it is the library loaded into the target Lisp system to enable interaction and remote debugging), to make use of its portable debugging facilities:
<
(lambda ()
(swank:backtrace 0 nil)))</
Here are a few lines of the result when running under [[SBCL]], the rest is omitted since it's long and boring:
<
(1 "(SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT (LAMBDA () (SWANK:BACKTRACE 0 NIL))) #<NULL-LEXENV>)")
(2 "(SWANK::EVAL-REGION \"(swank-backend:call-with-debugging-environment\\n (lambda ()\\n (swank:backtrace 0 nil)))\\n\\n\")")
(3 "((LAMBDA ()))") ...)</
Note that this is a data structure containing the backtrace, not a format intended for presentation. In [[SBCL]], executing <code>(sb-debug:backtrace 7)</code> produces output like this (run from the SLIME-REPL, which is why it still contains mentions of SWANK):
<
0: (SB-DEBUG::MAP-BACKTRACE
#<CLOSURE (LAMBDA (SB-DEBUG::FRAME)) {1193EFCD}>)[:EXTERNAL]
Line 557:
6: (SWANK::CALL-WITH-RETRY-RESTART
"Retry SLIME REPL evaluation request."
#<CLOSURE (LAMBDA ()) {1193EC4D}>)</
SBCL's backtraces consist entirely of lists of the form <code>(<var>function-name</var> <var>args...</var>)</code>.
Line 564:
Compiled with the dmd compiler using the -g switch.
{{trans|Java}}
<
void inner() { defaultTraceHandler.writeln; }
Line 573:
outer;
"After the stack trace.".writeln;
}</
{{out}}
<pre>0x00404FBE in core.sys.windows.stacktrace.StackTrace core.sys.windows.stacktrace.StackTrace.__ctor(uint, core.sys.windows.windows.CONTEXT*) at E:\dmd2\src\druntime\import\core\sys\windows\stacktrace.d(69)
Line 594:
=={{header|DWScript}}==
Stack traces can be obtained from exception objects
<
begin
try
Line 614:
end;
Outer;</
Output:<pre>Inner [line: 4, column: 23]
Middle [line: 13, column: 4]
Outer [line: 18, column: 4]
[line: 21, column: 1]</pre>
=={{header|Elena}}==
{{trans|C#}}
ELENA
<
public singleton program
Line 646 ⟶ 647:
program.outer()
}
}</
{{out}}
<pre>
system'$private'entry.function:#invoke
system'$private'entrySymbol#
</pre>
=={{header|Elixir}}==
{{trans|Erlang}}
<
def main do
{:ok, a} = outer
Line 683 ⟶ 684:
end
Stack_traces.main</
{{out}}
Line 701 ⟶ 702:
{{trans|Java}}
Stack traces only can be obtained inside a catch block. Additionally, it doesn't work for tail calls.
<
-export([main/0]).
Line 718 ⟶ 719:
inner() ->
try throw(42) catch 42 -> {ok,erlang:get_stacktrace()} end.</
{{out}}
<pre>[{stack_traces,inner,0,[{file,"stack_traces.erl"},{line,18}]},
Line 729 ⟶ 730:
=={{header|F_Sharp|F#}}==
{{trans|C#}}
<
type myClass() =
Line 740 ⟶ 741:
let that = new myClass()
that.outer()
0</
Output
<pre> at Rosetta.myClass.inner()
Line 749 ⟶ 750:
=={{header|Factor}}==
This stack trace shows the listener — Factor's Read-Eval-Print-Loop. The current execution point in each call frame is indicated by <code>=></code>. Press ctrl+w in the listener to walk through the call stack one step at a time and watch how it affects the data stack. You can even step backward in most cases. This is handy for debugging.
<
get-callstack callstack.</
{{out}}
<pre>
Line 774 ⟶ 775:
{{works with|4tH|3.60.0}}
<
\ Return stack counterpart of DEPTH
\ Note the STACK-CELLS correction is there to hide RDEPTH itself
Line 787 ⟶ 788:
BEGIN DUP WHILE ROT DUP . >R 1- REPEAT DROP
THEN ." (TORS) " DROP >R ;
[THEN]</
=={{header|Fortran}}==
Line 808 ⟶ 809:
Should a fatal error be declared by the run-time system, none of this will happen, but if while running, some unrecoverable or a should-never-happen but I'll check anyway type of problem be noted, then a possibly informative output will follow.
=={{header|FreeBASIC}}==
Code extracted from FreeBAsic Forum
[https://freebasic.net/forum/viewtopic.php?t=31371 https://freebasic.net/forum/viewtopic.php?t=31371]
<syntaxhighlight lang="vb">#include "windows.bi"
Private Function Fn2() As Long
Dim frames(0 To 60) As Any Ptr
Dim framesPtr As Any Ptr Ptr = @frames(0)
Dim hash As DWORD
Dim As Long caught = CaptureStackBackTrace(0, 61, framesPtr, @hash)
Print Using "Caught & frames using stack capture"; caught
For i As Long = 0 To caught - 1
Print Using "&) &"; caught - i; Hex(frames(i))
Next
Return caught
End Function
Private Sub Fn1(num As Ulong)
Dim As Long numFn2 = Fn2()
Print Using "Fn2 returned & with num = &"; numFn2; num
End Sub
Fn1(87)
Sleep</syntaxhighlight>
{{out}}
<pre>Caught 7 frames using stack capture
7) 4016FE
6) 40185E
5) 4015BA
4) 4013B4
3) 40150B
2) 7FFBD6AC7614
1) 7FFBD7B226A1
Fn2 returned 7 with num = 87</pre>
=={{header|Go}}==
<
import (
Line 823 ⟶ 860:
fmt.Printf("%s\n", stackTrace)
fmt.Printf("(%d bytes)\n", len(stackTrace))
}</
outputs:
<pre>
Line 841 ⟶ 878:
=={{header|Groovy}}==
Solution:
<
Test: (demonstrates, among other things, continued execution after generating stack trace)
<
def props = it.properties
def keys = (it.properties.keySet() - (new Object().properties.keySet()))
Line 857 ⟶ 894:
trace.each {
propNames.eachWithIndex{ name, i -> printf("%-${propWidths[i]}s ", it[name].toString()) }; println ''
}</
Output:
Line 931 ⟶ 968:
{{libheader|Unicon Code Library}}
[http://tapestry.tucson.az.us/unilib/pack_Utils.html the following code for buildStackTrace in Utils is taken verbatim and shown below the main program]
<syntaxhighlight lang="unicon">
import Utils # for buildStackTrace
Line 947 ⟶ 984:
# Using 1 as argument omits the trace of buildStackTrace itself
every write("\t",!buildStackTrace(1))
end</
<syntaxhighlight lang="unicon">#<p>
# Compute the current stack trace. Starting at level <i>n</i> above
# the current procedure. Here, <i>n</i> defaults to 0, which will
Line 970 ⟶ 1,007:
}
return L
end</
The output of this example is:
Line 987 ⟶ 1,024:
To enable suspension and record subsequent stack frames:
<syntaxhighlight lang
To retrieve a current stack trace:
<syntaxhighlight lang
See also: http://www.jsoftware.com/help/dictionary/dx013.htm
Line 996 ⟶ 1,033:
Example:
<
g=:13!:13 bind ''
f 7 NB. empty stack trace because debugging has not been enabled
Line 1,009 ⟶ 1,046:
│ │ │ │ │ │││7││ │ │
│ │ │ │ │ ││└─┘│ │ │
└─┴─┴─┴─┴─────────────┴┴───┴──┴─┘</
Technical note: the stack trace is not displayed, here, until after the stack has been discarded. This is because we have returned the stack trace as a result and relied on J's implicit display of the result of an expression to display the stack trace.
Line 1,015 ⟶ 1,052:
=={{header|Java}}==
{{works with|Java|1.5+}}
<
public static void printStackTrace() {
StackTraceElement[] elems = Thread.currentThread().getStackTrace();
Line 1,025 ⟶ 1,062:
}
}
}</
Demonstration code:
<
static void inner() {
StackTracer.printStackTrace();
Line 1,040 ⟶ 1,077:
outer();
}
}</
Output:
<pre>Stack trace:
Line 1,051 ⟶ 1,088:
There is no standard way to do this, but some implementations provide it.<br />
{{works with|Firefox}}
<
throw new Error;
} catch(e) {
alert(e.stack);
}</
The following version works in many browsers but it infinitely loops when there is recursion:
<
var stack = "Stack trace:";
for (var f = arguments.callee // current function
Line 1,066 ⟶ 1,103:
alert(stack);
}
foo();</
=={{header|Julia}}==
{{works with|Julia|0.6}}
<
g() = println.(stacktrace())
f()</
{{out}}
Line 1,088 ⟶ 1,125:
=={{header|Kotlin}}==
<
fun myFunc() {
Line 1,097 ⟶ 1,134:
myFunc()
println("\nContinuing ... ")
}</
{{out}}
Line 1,105 ⟶ 1,142:
Continuing ...
</pre>
=={{header|Lang}}==
<syntaxhighlight lang="lang">
# fn.getStackTrace() returns a text-based stack trace
fp.printStackTrace = () -> fn.println(fn.getStackTrace())
# Example
fp.f1 = () -> {
fn.println(F1:)
fp.printStackTrace()
}
fp.f2 = () -> {
fn.println(F2:)
fp.printStackTrace()
fp.f1()
}
fp.f2()
fn.combA0(fp.f2)
# Partially called combinator functions' names are represented as "<comb...-func(...)>"
fn.combA(fn.combC(fn.combAE(), x), fp.f2)
</syntaxhighlight>
{{out}}
The file paths were redacted. If ":x" is outputted as the line number, no line number information is available (e.g. If Lang is implemented with an interpreter, predefined functions are written in the host language)
<pre>
F2:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:11" in function "fp.f2"
at "[redacted]:14" in function "main"
F1:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:7" in function "fp.f1"
at "[redacted]:12" in function "fp.f2"
at "[redacted]:14" in function "main"
F2:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:11" in function "fp.f2"
at "[redacted]:x" in function "combA0"
at "[redacted]:16" in function "main"
F1:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:7" in function "fp.f1"
at "[redacted]:12" in function "fp.f2"
at "[redacted]:x" in function "combA0"
at "[redacted]:16" in function "main"
F2:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:11" in function "fp.f2"
at "[redacted]:x" in function "<combAE-func()>"
at "[redacted]:x" in function "<combC-func(<combAE-func()>, <arg>)>"
at "[redacted]:x" in function "combA"
at "[redacted]:19" in function "main"
F1:
at "[redacted]:x" in function "getStackTrace"
at "[redacted]:2" in function "fp.printStackTrace"
at "[redacted]:7" in function "fp.f1"
at "[redacted]:12" in function "fp.f2"
at "[redacted]:x" in function "<combAE-func()>"
at "[redacted]:x" in function "<combC-func(<combAE-func()>, <arg>)>"
at "[redacted]:x" in function "combA"
at "[redacted]:19" in function "main"
</pre>
Line 1,110 ⟶ 1,215:
By default Lasso tracks the file path, line and column numbers. You can create a trace method to track type and method names illustrated below or use one of the public libraries like L-Debug [https://github.com/zeroloop/l-debug].
<
define trace => {
local(gb) = givenblock
Line 1,133 ⟶ 1,238:
)
return #gb()
}</
;Use Trace:
<
public oncreate => trace => { return self }
public inner => trace => { }
Line 1,144 ⟶ 1,249:
}
stackexample->outer</
{{out}}
Line 1,154 ⟶ 1,259:
=={{header|Lua}}==
<
print( debug.traceback() )
print "Program continues..."
Line 1,167 ⟶ 1,272:
end
Outer( 2, 3, 5 )</
<pre>stack traceback:
./prog:4: in function 'Inner'
Line 1,176 ⟶ 1,281:
Program continues...</pre>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
Built-in function Stack does the task, example I:
<
prints, gives back:
<
f[g[1, 2]]</
Example II:
<
prints, gives back:
<
f[g[1, 2]]</
Related and similar functions are: Trace, TracePrint, TraceScan,TraceDialog, Monitor, StackInhibit, StackBegin, StackComplete. In the manual look for 'guide/SymbolicExecutionHistory'.
=={{header|Nanoquery}}==
__calls__ contains a list that represents a trace of calls that have been made.
<
global __calls__
Line 1,208 ⟶ 1,313:
println
println "The program would continue."</
{{out}}
<pre>stack trace:
Line 1,221 ⟶ 1,326:
=={{header|NetRexx}}==
{{trans|Java}}
<
options replace format comments java crossref symbols nobinary
Line 1,243 ⟶ 1,348:
j_ = j_ + 2
end i_
</syntaxhighlight>
'''Output:'''
<pre>
Line 1,255 ⟶ 1,360:
=={{header|Nim}}==
In (normal) debug builds stacktraces are enabled, while in release builds stacktraces are disabled by default, but can be enabled like this: <code>nim c -d:release --stacktrace:on --linetrace:on file.nim</code>
<
# Writes the current stack trace to stderr.
writeStackTrace()
Line 1,266 ⟶ 1,371:
g()
f()</
{{out}}
For a release build:
Line 1,281 ⟶ 1,386:
=={{header|Objective-C}}==
<
void *frames[128];
Line 1,289 ⟶ 1,394:
NSLog(@"%s", symbols[i]);
}
free(symbols);</
Or in Mac OS X 10.6+:
<
for (NSString *symbol in symbols) {
NSLog(@"%@", symbol);
}</
=={{header|OCaml}}==
{{works with|OCaml|3.11+}}
<
let () =
Line 1,306 ⟶ 1,411:
prerr_endline(Printexc.to_string e);
Printexc.print_backtrace stderr;
;;</
outputs:
Line 1,317 ⟶ 1,422:
Then the code doesn't need additional statements:
<
let () =
let _ = div 3 0 in ()
;;</
outputs:
Fatal error: exception Division_by_zero
Line 1,336 ⟶ 1,441:
Otherwise no stack trace is available nor printed.
<
Integer method: f2 self f1 ;
: f3 f2 ;
: f4 f3 ;
10 f4</
{{out}}
Line 1,354 ⟶ 1,459:
=={{header|OxygenBasic}}==
<
'32bit x86
Line 1,435 ⟶ 1,540:
0017FE1C 07 00000000
*/
</syntaxhighlight>
=={{header|Oz}}==
System exceptions contain the current stack at the nested feature <code>debug.stack</code>. For example:
<
proc {Test}
_ = 1 div 0
Line 1,448 ⟶ 1,553:
catch E then
{Inspect E}
end</
Output:
[[File:Oz_stacktrace1.png|center|Stack trace of a system exception in Oz.]]
Line 1,455 ⟶ 1,560:
To access the stack trace directly, you can use the undocumented internal Debug module. Its <code>getTaskStack</code> function takes a thread, a depth value and a boolean "verbose" flag. It returns a list of stack frames. Example:
<
\switch +controlflowinfo
Line 1,469 ⟶ 1,574:
end
in
{F}</
Output:
[[File:Oz_stacktrace2.png|center|Stack trace created by the Debug module.]]
=={{header|PascalABC.NET}}==
<syntaxhighlight lang="perl">
procedure qqq;
begin
var st := new System.Diagnostics.StackTrace();
Print(st);
end;
procedure ppp;
begin
qqq;
end;
begin
ppp
end.
</syntaxhighlight>
{{out}}
<pre>
at Rosetta_StackTrace.Program.qqq()
at Rosetta_StackTrace.Program.ppp()
at Rosetta_StackTrace.Program.$Main()
at Rosetta_StackTrace.Program.Main()
</pre>
=={{header|Perl}}==
<
sub g {cluck 'Hello from &g';}
sub f {g;}
f;</
This prints:
Line 1,487 ⟶ 1,619:
main::g() called at Print a Stack Trace line 4
main::f() called at Print a Stack Trace line 6</pre>
=={{header|Phix}}==
There no standard method of obtaining a stack trace mid-run (as yet, non-fatally that is), but we can quickly cobble something together:
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">W</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">machine_word</span><span style="color: #0000FF;">(),</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">RTN</span><span style="color: #0000FF;">,</span><span style="color: #000000;">PREVEBP</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">W</span><span style="color: #0000FF;">=</span><span style="color: #000000;">4</span><span style="color: #0000FF;">?{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">}:{</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">40</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show_stack</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">symtab</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">symtabN</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">rtn</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">prev_ebp</span>
lea edi,[symtab]
mov
mov eax,[
mov
lea rdi,[symtab]
mov
mov rax,[
mov
}
<span style="color: #008080;">while</span> <span style="color: #000000;">rtn</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">21</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- (T_maintls, main top level routine, always present)</span>
<span style="color: #000000;">symtabN</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">symtab</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rtn</span><span style="color: #0000FF;">]</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">symtabN</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">prev_ebp</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peekNS</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prev_ebp</span><span style="color: #0000FF;">+</span><span style="color: #000000;">PREVEBP</span><span style="color: #0000FF;">,</span><span style="color: #000000;">W</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">rtn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peekNS</span><span style="color: #0000FF;">(</span><span style="color: #000000;">prev_ebp</span><span style="color: #0000FF;">+</span><span style="color: #000000;">RTN</span><span style="color: #0000FF;">,</span><span style="color: #000000;">W</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">three</span><span style="color: #0000FF;">(</span><span style="color: #004080;">bool</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">die</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">show_stack</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">two</span><span style="color: #0000FF;">(</span><span style="color: #004080;">bool</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">three</span><span style="color: #0000FF;">(</span><span style="color: #000000;">die</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">one</span><span style="color: #0000FF;">(</span><span style="color: #004080;">bool</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">two</span><span style="color: #0000FF;">(</span><span style="color: #000000;">die</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"dummy"</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- see note below</span>
<span style="color: #000000;">one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
During compilation, the symbol table entries hold an integer ternary tree index rather than a string name, and normally
things are left like that during interpretation (the proper string names are always written out when an executable is
Line 1,588 ⟶ 1,712:
Alternatively, but only when interpreting (whereas the above works as shown both when interpreting and pre-compiled), the debugger is
started with the much saner
<!--<syntaxhighlight lang="phix">-->
<span style="color: #008080;">trace</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
though as yet it offers no means of examining the stack trace (resume-ably), the above suggests it should be relative easy to add.
=={{header|PHP}}==
<
class StackTraceDemo {
static function inner() {
Line 1,606 ⟶ 1,732:
StackTraceDemo::outer();
?></
<pre>#0 StackTraceDemo::inner() called at [/home/cweiske/Dev/cvs/test/php-stacktrace.php:7]
#1 StackTraceDemo::middle() called at [/home/cweiske/Dev/cvs/test/php-stacktrace.php:10]
#2 StackTraceDemo::outer() called at [/home/cweiske/Dev/cvs/test/php-stacktrace.php:14]</pre>
=={{header|PicoLisp}}==
Line 1,629 ⟶ 1,744:
As this mechanism uses 'let' to hold the stack frames, it is robust also across catch/throw, coroutines and error handling.
<
(de $$ "Prg"
Line 1,664 ⟶ 1,779:
(de dumpStack ()
(more (reverse (cdr "Stack")))
T )</
Test:
<
(let C 3
(bar (inc 'A) (inc 'B) (inc 'C)) ) )
Line 1,674 ⟶ 1,789:
(! println A B C) ) ) # Set a breakpoint before (println A B C)
(stackAll)</
<pre>: (foo 1 2) # Call 'foo'
(println A B C) # Stopped at breakpoint in 'bar'
Line 1,685 ⟶ 1,800:
-> 9
:</pre>
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
/* The SNAP option in the ON statement is sufficient to obtain */
/* a traceback. The SYSTEM option specifies that standard */
/* system action is to occur, which resume execution after the */
/* SIGNAL statement. */
on condition(traceback) snap system;
...
signal condition(traceback);
</syntaxhighlight>
=={{header|PureBasic}}==
The [http://www.purebasic.com/documentation/debugger/showcallstack.html ShowCallstack()]command opens a interactive display allowing viewing of the procedures in the calling path an all their local variables.
<
a=7
ShowCallstack()
Line 1,704 ⟶ 1,830:
EndProcedure
One()</
=={{header|Python}}==
See the [http://docs.python.org/library/traceback.html traceback] module
<
def f(): return g()
def g(): traceback.print_stack()
f()</
Sample output from a session in the Idle IDE:
Line 1,729 ⟶ 1,855:
def g(): traceback.print_stack()
</pre>
=={{header|Quackery}}==
Quackery has two system stacks, the call or return stack and a data stack. The words <code>echoreturn</code> and <code>echostack</code> display the current state of them. Each call to a word or nest places two entries on the return stack, a pointer to the word or nest, and an index into that word or nest. These are displayed as the name of the word, or <code>[...]</code> for an unnamed nest, and the index into the word or nest as an integer. Pairs of entries are displayed wrapped in braces, e.g. <code>{shell 5}</code>.
This is illustrated with a Quackery shell dialogue. The Quackery shell is written in Quackery, and as can be seen, occupies five pairs of entries on the return stack. After each interaction with the user the data stack is automatically displayed. Here the user opens the Quackery shell, displays the return stack, defines a naive recursive Fibonacci word that displays the return and data stack at the start of each call, and uses it to compute and display the fifth Fibonacci number (5).
<pre> > quackery
Welcome to Quackery.
Enter "leave" to leave the shell.
Building extensions.
/O> echoreturn
...
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 0}
Stack empty.
/O> [ cr echoreturn
... cr echostack
... dup 2 < if done
... dup 1 - swap 2 -
... recurse swap recurse + ] is fib
...
Stack empty.
/O> 5 fib echo
...
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 1}
Stack: 5
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 3
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 2 1
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 4 1 2
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 1 1 0
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 4 1 0 1
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 4
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 3 2
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 3 1 0
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 3 0 1
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 3
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 1 2 1
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 1 2
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 1 1 1 0
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 1 0 1
5
Stack empty.
/O></pre>
=={{header|R}}==
<
{
bar <- function()
Line 1,740 ⟶ 1,947:
}
foo()</
<nowiki>[[1]]</nowiki>
foo()
Line 1,748 ⟶ 1,955:
You can also see the stack trace when a function is called (or as it exits) using the trace function.
<
foo()</
<pre>
Tracing foo() on entry
Line 1,759 ⟶ 1,966:
Selection:
</pre>
=={{header|Racket}}==
<syntaxhighlight lang="racket">
#lang racket
;; To see these calls we do two things: mutate the binding to prevent
;; Racket from inlining the value; use a (void) call at the end so the
;; calls are not tail calls (which will otherwise not show on the
;; stack).
(define foo #f)
(set! foo (λ() (bar) (void)))
(define bar #f)
(set! bar (λ() (show-stacktrace) (void)))
(define (show-stacktrace)
(for ([s (continuation-mark-set->context (current-continuation-marks))]
[i (in-naturals)])
;; show just the names, not the full source information
(when (car s) (printf "~s: ~s\n" i (car s)))))
(foo)
</syntaxhighlight>
Output:
<pre>
0: show-stacktrace
1: bar
2: foo
3: |[running body]|
</pre>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2013-03-03}}
<syntaxhighlight lang="raku" line>sub g { say Backtrace.new.concise }
sub f { g }
sub MAIN { f }</syntaxhighlight>
{{out}}
<pre> in sub g at bt:1
in sub f at bt:2
in sub MAIN at bt:3</pre>
=={{header|Raven}}==
<syntaxhighlight lang="raven"> [1 2 3 4] 42 { 'a' 1 'b' 2 'c' 3 } 34.1234 ( -1 -2 -3 ) "The quick brown fox" FILE dump</syntaxhighlight>
{{out}}
<pre>hash (4 items)
usage => 1
index => 65836
flags => 256
buffer => " 98252f8 73 74 64 69 6e 00 stdin."
The quick brown fox
28.1234
hash (3 items)
a => 1
b => 2
c => 3
42
list (4 items)
0 => 1
1 => 2
2 => 3
3 => 4</pre>
=={{header|REXX}}==
{{works with|Regina}}
<
say 'Call A'
call A '123'
Line 1,791 ⟶ 2,059:
say format(line, 3) ':' left(func, 9) ': source "' || sourceline(line) || '"'
end
return cs.0</
{{out}}
Line 1,809 ⟶ 2,077:
Regina will also dump a call stack during certain error conditions. For instance, if the code listing above raised an unhandled signal (simulated here with "signal noname" in routine C). This is not a recoverable scenario though, and the program will not continue.
<
signal noname
call callstack
return ARG(1)</
{{out}}
Line 1,825 ⟶ 2,093:
Error 16 running "/demos/callstack.rexx", line 20: Label not found
Error 16.1: Label "NONAME" not found</pre>
=={{header|Ruby}}==
<
middle a+b, b+c
end
Line 1,890 ⟶ 2,108:
end
outer 2,3,5</
<pre>$ ruby stacktrace.rb
stacktrace.rb:10:in `inner'
Line 1,899 ⟶ 2,117:
Exceptions caught in a rescue clause contain the trace information:
<
middle a+b, b+c
end
Line 1,917 ⟶ 2,135:
puts e.backtrace
end
puts "continuing after the rescue..."</
<pre>stacktrace.rb:10:in `inner'
stacktrace.rb:6:in `middle'
Line 1,924 ⟶ 2,142:
continuing after the rescue...</pre>
Thread has a backtrace method:
<syntaxhighlight lang
=={{header|Scala}}==
Line 1,930 ⟶ 2,148:
the way, could be used from Java as well, with minor modifications.
<
def printStackTrace = callStack drop 1 /* don't print ourselves! */ foreach println</
Usage example:
Line 1,985 ⟶ 2,203:
The following #printCurrentStack is already defined in the base slate image but it is replicated here.
<
[
d clone `>> [baseFramePointer: (d interpreter framePointerOf: #printCurrentStack).
Line 1,992 ⟶ 2,210:
].
Defining function 'printCurrentStack' on: 'Debugger traits'
[printCurrentStack &limit: &stream: &showLocation:]</
The output from calling the function:
<
Backtrace (method @ source):
frame: 0 [printCurrentStack &limit: &stream: &showLocation:] @ stdin:0
Line 2,009 ⟶ 2,227:
frame: 9 [start &resource:] @ src/lib/repl.slate:185
frame: 10 [start] @ src/mobius/prelude.slate:38
Nil</
=={{header|Smalltalk}}==
Line 2,016 ⟶ 2,234:
A backtrace is normally sent when some error occurs; however, it can be "forced":
<
Container class >> outer: a and: b and: c [
self middle: (a+b) and: (b+c)
Line 2,030 ⟶ 2,248:
Container outer: 2 and: 3 and: 5.
'Anyway, we continue with it' displayNl.</
Output:
Line 2,041 ⟶ 2,259:
=={{header|Tcl}}==
<
puts "Stack trace:"
for {set i 1} {$i < [info level]} {incr i} {
puts [string repeat " " $i][info level $i]
}
}</
Demonstration code:
<
middle [expr {$a+$b}] [expr {$b+$c}]
}
Line 2,057 ⟶ 2,275:
printStackTrace
}
outer 2 3 5</
Produces this output:
<pre>Stack trace:
Line 2,066 ⟶ 2,284:
=={{header|VBA}}==
In VBE the VBA Editor hitting Control+L while stepping through your code in debug mode will pop up a window which displays the call stack.
=={{header|Wren}}==
You can always force Wren CLI to produce a stack trace by either engineering an actual error or calling Fiber.abort() at the relevant part of the script.
However, it is not possible to continue execution of the script afterwards. Whilst one can 'catch' such an error using Fiber.try() this will only allow you to inspect the error itself, not the chain of function calls that led up to it.
<syntaxhighlight lang="wren">var func2 = Fn.new {
Fiber.abort("Forced error.")
}
var func1 = Fn.new {
func2.call()
}
func1.call()</syntaxhighlight>
{{out}}
<pre>
Forced error.
[./stack_trace line 2] in new(_) block argument
[./stack_trace line 6] in new(_) block argument
[./stack_trace line 9] in (script)
</pre>
=={{header|zkl}}==
<
f();g();</
{{out}}
stackTrace just returns a string. You don't get to futz with the stack.
|