mollusk 019f8e3064 Add: julia-0.6.2
Former-commit-id: ccc667cf67d569f3fb3df39aa57c2134755a7551
2018-02-10 10:27:19 -07:00

182 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>Stack Traces · The Julia Language</title><script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-28835595-6', 'auto');
ga('send', 'pageview');
</script><link href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css" rel="stylesheet" type="text/css"/><link href="https://fonts.googleapis.com/css?family=Lato|Roboto+Mono" rel="stylesheet" type="text/css"/><link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" type="text/css"/><script>documenterBaseURL=".."</script><script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js" data-main="../assets/documenter.js"></script><script src="../siteinfo.js"></script><script src="../../versions.js"></script><link href="../assets/highlightjs/default.css" rel="stylesheet" type="text/css"/><link href="../assets/documenter.css" rel="stylesheet" type="text/css"/></head><body><nav class="toc"><a href="../index.html"><img class="logo" src="../assets/logo.png" alt="The Julia Language logo"/></a><h1>The Julia Language</h1><select id="version-selector" onChange="window.location.href=this.value" style="visibility: hidden"></select><form class="search" action="../search.html"><input id="search-query" name="q" type="text" placeholder="Search docs"/></form><ul><li><a class="toctext" href="../index.html">Home</a></li><li><span class="toctext">Manual</span><ul><li><a class="toctext" href="introduction.html">Introduction</a></li><li><a class="toctext" href="getting-started.html">Getting Started</a></li><li><a class="toctext" href="variables.html">Variables</a></li><li><a class="toctext" href="integers-and-floating-point-numbers.html">Integers and Floating-Point Numbers</a></li><li><a class="toctext" href="mathematical-operations.html">Mathematical Operations and Elementary Functions</a></li><li><a class="toctext" href="complex-and-rational-numbers.html">Complex and Rational Numbers</a></li><li><a class="toctext" href="strings.html">Strings</a></li><li><a class="toctext" href="functions.html">Functions</a></li><li><a class="toctext" href="control-flow.html">Control Flow</a></li><li><a class="toctext" href="variables-and-scoping.html">Scope of Variables</a></li><li><a class="toctext" href="types.html">Types</a></li><li><a class="toctext" href="methods.html">Methods</a></li><li><a class="toctext" href="constructors.html">Constructors</a></li><li><a class="toctext" href="conversion-and-promotion.html">Conversion and Promotion</a></li><li><a class="toctext" href="interfaces.html">Interfaces</a></li><li><a class="toctext" href="modules.html">Modules</a></li><li><a class="toctext" href="documentation.html">Documentation</a></li><li><a class="toctext" href="metaprogramming.html">Metaprogramming</a></li><li><a class="toctext" href="arrays.html">Multi-dimensional Arrays</a></li><li><a class="toctext" href="linear-algebra.html">Linear algebra</a></li><li><a class="toctext" href="networking-and-streams.html">Networking and Streams</a></li><li><a class="toctext" href="parallel-computing.html">Parallel Computing</a></li><li><a class="toctext" href="dates.html">Date and DateTime</a></li><li><a class="toctext" href="interacting-with-julia.html">Interacting With Julia</a></li><li><a class="toctext" href="running-external-programs.html">Running External Programs</a></li><li><a class="toctext" href="calling-c-and-fortran-code.html">Calling C and Fortran Code</a></li><li><a class="toctext" href="handling-operating-system-variation.html">Handling Operating System Variation</a></li><li><a class="toctext" href="environment-variables.html">Environment Variables</a></li><li><a class="toctext" href="embedding.html">Embedding Julia</a></li><li><a class="toctext" href="packages.html">Packages</a></li><li><a class="toctext" href="profile.html">Profiling</a></li><li class="current"><a class="toctext" href="stacktraces.html">Stack Traces</a><ul class="internal"><li><a class="toctext" href="#Viewing-a-stack-trace-1">Viewing a stack trace</a></li><li><a class="toctext" href="#Extracting-useful-information-1">Extracting useful information</a></li><li><a class="toctext" href="#Error-handling-1">Error handling</a></li><li><a class="toctext" href="#Comparison-with-[backtrace()](@ref)-1">Comparison with <code>backtrace()</code></a></li></ul></li><li><a class="toctext" href="performance-tips.html">Performance Tips</a></li><li><a class="toctext" href="workflow-tips.html">Workflow Tips</a></li><li><a class="toctext" href="style-guide.html">Style Guide</a></li><li><a class="toctext" href="faq.html">Frequently Asked Questions</a></li><li><a class="toctext" href="noteworthy-differences.html">Noteworthy Differences from other Languages</a></li><li><a class="toctext" href="unicode-input.html">Unicode Input</a></li></ul></li><li><span class="toctext">Standard Library</span><ul><li><a class="toctext" href="../stdlib/base.html">Essentials</a></li><li><a class="toctext" href="../stdlib/collections.html">Collections and Data Structures</a></li><li><a class="toctext" href="../stdlib/math.html">Mathematics</a></li><li><a class="toctext" href="../stdlib/numbers.html">Numbers</a></li><li><a class="toctext" href="../stdlib/strings.html">Strings</a></li><li><a class="toctext" href="../stdlib/arrays.html">Arrays</a></li><li><a class="toctext" href="../stdlib/parallel.html">Tasks and Parallel Computing</a></li><li><a class="toctext" href="../stdlib/linalg.html">Linear Algebra</a></li><li><a class="toctext" href="../stdlib/constants.html">Constants</a></li><li><a class="toctext" href="../stdlib/file.html">Filesystem</a></li><li><a class="toctext" href="../stdlib/io-network.html">I/O and Network</a></li><li><a class="toctext" href="../stdlib/punctuation.html">Punctuation</a></li><li><a class="toctext" href="../stdlib/sort.html">Sorting and Related Functions</a></li><li><a class="toctext" href="../stdlib/pkg.html">Package Manager Functions</a></li><li><a class="toctext" href="../stdlib/dates.html">Dates and Time</a></li><li><a class="toctext" href="../stdlib/iterators.html">Iteration utilities</a></li><li><a class="toctext" href="../stdlib/test.html">Unit Testing</a></li><li><a class="toctext" href="../stdlib/c.html">C Interface</a></li><li><a class="toctext" href="../stdlib/libc.html">C Standard Library</a></li><li><a class="toctext" href="../stdlib/libdl.html">Dynamic Linker</a></li><li><a class="toctext" href="../stdlib/profile.html">Profiling</a></li><li><a class="toctext" href="../stdlib/stacktraces.html">StackTraces</a></li><li><a class="toctext" href="../stdlib/simd-types.html">SIMD Support</a></li></ul></li><li><span class="toctext">Developer Documentation</span><ul><li><a class="toctext" href="../devdocs/reflection.html">Reflection and introspection</a></li><li><span class="toctext">Documentation of Julia&#39;s Internals</span><ul><li><a class="toctext" href="../devdocs/init.html">Initialization of the Julia runtime</a></li><li><a class="toctext" href="../devdocs/ast.html">Julia ASTs</a></li><li><a class="toctext" href="../devdocs/types.html">More about types</a></li><li><a class="toctext" href="../devdocs/object.html">Memory layout of Julia Objects</a></li><li><a class="toctext" href="../devdocs/eval.html">Eval of Julia code</a></li><li><a class="toctext" href="../devdocs/callconv.html">Calling Conventions</a></li><li><a class="toctext" href="../devdocs/compiler.html">High-level Overview of the Native-Code Generation Process</a></li><li><a class="toctext" href="../devdocs/functions.html">Julia Functions</a></li><li><a class="toctext" href="../devdocs/cartesian.html">Base.Cartesian</a></li><li><a class="toctext" href="../devdocs/meta.html">Talking to the compiler (the <code>:meta</code> mechanism)</a></li><li><a class="toctext" href="../devdocs/subarrays.html">SubArrays</a></li><li><a class="toctext" href="../devdocs/sysimg.html">System Image Building</a></li><li><a class="toctext" href="../devdocs/llvm.html">Working with LLVM</a></li><li><a class="toctext" href="../devdocs/stdio.html">printf() and stdio in the Julia runtime</a></li><li><a class="toctext" href="../devdocs/boundscheck.html">Bounds checking</a></li><li><a class="toctext" href="../devdocs/locks.html">Proper maintenance and care of multi-threading locks</a></li><li><a class="toctext" href="../devdocs/offset-arrays.html">Arrays with custom indices</a></li><li><a class="toctext" href="../devdocs/libgit2.html">Base.LibGit2</a></li><li><a class="toctext" href="../devdocs/require.html">Module loading</a></li></ul></li><li><span class="toctext">Developing/debugging Julia&#39;s C code</span><ul><li><a class="toctext" href="../devdocs/backtraces.html">Reporting and analyzing crashes (segfaults)</a></li><li><a class="toctext" href="../devdocs/debuggingtips.html">gdb debugging tips</a></li><li><a class="toctext" href="../devdocs/valgrind.html">Using Valgrind with Julia</a></li><li><a class="toctext" href="../devdocs/sanitizers.html">Sanitizer support</a></li></ul></li></ul></li></ul></nav><article id="docs"><header><nav><ul><li>Manual</li><li><a href="stacktraces.html">Stack Traces</a></li></ul><a class="edit-page" href="https://github.com/JuliaLang/julia/tree/d386e40c17d43b79fc89d3e579fc04547241787c/doc/src/manual/stacktraces.md"><span class="fa"></span> Edit on GitHub</a></nav><hr/><div id="topbar"><span>Stack Traces</span><a class="fa fa-bars" href="#"></a></div></header><h1><a class="nav-anchor" id="Stack-Traces-1" href="#Stack-Traces-1">Stack Traces</a></h1><p>The <code>StackTraces</code> module provides simple stack traces that are both human readable and easy to use programmatically.</p><h2><a class="nav-anchor" id="Viewing-a-stack-trace-1" href="#Viewing-a-stack-trace-1">Viewing a stack trace</a></h2><p>The primary function used to obtain a stack trace is <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a>:</p><pre><code class="language-julia-repl">julia&gt; stacktrace()
4-element Array{StackFrame,1}:
eval(::Module, ::Any) at boot.jl:236
eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66
macro expansion at REPL.jl:97 [inlined]
(::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73</code></pre><p>Calling <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> returns a vector of <a href="../stdlib/stacktraces.html#Base.StackTraces.StackFrame"><code>StackFrame</code></a> s. For ease of use, the alias <a href="../stdlib/stacktraces.html#Base.StackTraces.StackTrace"><code>StackTrace</code></a> can be used in place of <code>Vector{StackFrame}</code>. (Examples with <code>[...]</code> indicate that output may vary depending on how the code is run.)</p><pre><code class="language-julia-repl">julia&gt; example() = stacktrace()
example (generic function with 1 method)
julia&gt; example()
5-element Array{StackFrame,1}:
example() at REPL[1]:1
eval(::Module, ::Any) at boot.jl:236
[...]
julia&gt; @noinline child() = stacktrace()
child (generic function with 1 method)
julia&gt; @noinline parent() = child()
parent (generic function with 1 method)
julia&gt; grandparent() = parent()
grandparent (generic function with 1 method)
julia&gt; grandparent()
7-element Array{StackFrame,1}:
child() at REPL[3]:1
parent() at REPL[4]:1
grandparent() at REPL[5]:1
[...]</code></pre><p>Note that when calling <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> you&#39;ll typically see a frame with <code>eval(...) at boot.jl</code>. When calling <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> from the REPL you&#39;ll also have a few extra frames in the stack from <code>REPL.jl</code>, usually looking something like this:</p><pre><code class="language-julia-repl">julia&gt; example() = stacktrace()
example (generic function with 1 method)
julia&gt; example()
5-element Array{StackFrame,1}:
example() at REPL[1]:1
eval(::Module, ::Any) at boot.jl:236
eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66
macro expansion at REPL.jl:97 [inlined]
(::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73</code></pre><h2><a class="nav-anchor" id="Extracting-useful-information-1" href="#Extracting-useful-information-1">Extracting useful information</a></h2><p>Each <a href="../stdlib/stacktraces.html#Base.StackTraces.StackFrame"><code>StackFrame</code></a> contains the function name, file name, line number, lambda info, a flag indicating whether the frame has been inlined, a flag indicating whether it is a C function (by default C functions do not appear in the stack trace), and an integer representation of the pointer returned by <a href="../stdlib/base.html#Base.backtrace"><code>backtrace()</code></a>:</p><pre><code class="language-julia-repl">julia&gt; top_frame = stacktrace()[1]
eval(::Module, ::Any) at boot.jl:236
julia&gt; top_frame.func
:eval
julia&gt; top_frame.file
Symbol(&quot;./boot.jl&quot;)
julia&gt; top_frame.line
236
julia&gt; top_frame.linfo
Nullable{Core.MethodInstance}(MethodInstance for eval(::Module, ::Any))
julia&gt; top_frame.inlined
false
julia&gt; top_frame.from_c
false</code></pre><pre><code class="language-julia-repl">julia&gt; top_frame.pointer
0x00007f390d152a59</code></pre><p>This makes stack trace information available programmatically for logging, error handling, and more.</p><h2><a class="nav-anchor" id="Error-handling-1" href="#Error-handling-1">Error handling</a></h2><p>While having easy access to information about the current state of the callstack can be helpful in many places, the most obvious application is in error handling and debugging.</p><pre><code class="language-julia-repl">julia&gt; @noinline bad_function() = undeclared_variable
bad_function (generic function with 1 method)
julia&gt; @noinline example() = try
bad_function()
catch
stacktrace()
end
example (generic function with 1 method)
julia&gt; example()
5-element Array{StackFrame,1}:
example() at REPL[2]:4
eval(::Module, ::Any) at boot.jl:236
[...]</code></pre><p>You may notice that in the example above the first stack frame points points at line 4, where <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> is called, rather than line 2, where <em>bad_function</em> is called, and <code>bad_function</code>&#39;s frame is missing entirely. This is understandable, given that <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> is called from the context of the <em>catch</em>. While in this example it&#39;s fairly easy to find the actual source of the error, in complex cases tracking down the source of the error becomes nontrivial.</p><p>This can be remedied by calling <a href="../stdlib/stacktraces.html#Base.StackTraces.catch_stacktrace"><code>catch_stacktrace()</code></a> instead of <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a>. Instead of returning callstack information for the current context, <a href="../stdlib/stacktraces.html#Base.StackTraces.catch_stacktrace"><code>catch_stacktrace()</code></a> returns stack information for the context of the most recent exception:</p><pre><code class="language-julia-repl">julia&gt; @noinline bad_function() = undeclared_variable
bad_function (generic function with 1 method)
julia&gt; @noinline example() = try
bad_function()
catch
catch_stacktrace()
end
example (generic function with 1 method)
julia&gt; example()
6-element Array{StackFrame,1}:
bad_function() at REPL[1]:1
example() at REPL[2]:2
[...]</code></pre><p>Notice that the stack trace now indicates the appropriate line number and the missing frame.</p><pre><code class="language-julia-repl">julia&gt; @noinline child() = error(&quot;Whoops!&quot;)
child (generic function with 1 method)
julia&gt; @noinline parent() = child()
parent (generic function with 1 method)
julia&gt; @noinline function grandparent()
try
parent()
catch err
println(&quot;ERROR: &quot;, err.msg)
catch_stacktrace()
end
end
grandparent (generic function with 1 method)
julia&gt; grandparent()
ERROR: Whoops!
7-element Array{StackFrame,1}:
child() at REPL[1]:1
parent() at REPL[2]:1
grandparent() at REPL[3]:3
[...]</code></pre><h2><a class="nav-anchor" id="Comparison-with-[backtrace()](@ref)-1" href="#Comparison-with-[backtrace()](@ref)-1">Comparison with <a href="../stdlib/base.html#Base.backtrace"><code>backtrace()</code></a></a></h2><p>A call to <a href="../stdlib/base.html#Base.backtrace"><code>backtrace()</code></a> returns a vector of <code>Ptr{Void}</code>, which may then be passed into <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> for translation:</p><pre><code class="language-julia-repl">julia&gt; trace = backtrace()
21-element Array{Ptr{Void},1}:
Ptr{Void} @0x00007f10049d5b2f
Ptr{Void} @0x00007f0ffeb4d29c
Ptr{Void} @0x00007f0ffeb4d2a9
Ptr{Void} @0x00007f1004993fe7
Ptr{Void} @0x00007f10049a92be
Ptr{Void} @0x00007f10049a823a
Ptr{Void} @0x00007f10049a9fb0
Ptr{Void} @0x00007f10049aa718
Ptr{Void} @0x00007f10049c0d5e
Ptr{Void} @0x00007f10049a3286
Ptr{Void} @0x00007f0ffe9ba3ba
Ptr{Void} @0x00007f0ffe9ba3d0
Ptr{Void} @0x00007f1004993fe7
Ptr{Void} @0x00007f0ded34583d
Ptr{Void} @0x00007f0ded345a87
Ptr{Void} @0x00007f1004993fe7
Ptr{Void} @0x00007f0ded34308f
Ptr{Void} @0x00007f0ded343320
Ptr{Void} @0x00007f1004993fe7
Ptr{Void} @0x00007f10049aeb67
Ptr{Void} @0x0000000000000000
julia&gt; stacktrace(trace)
5-element Array{StackFrame,1}:
backtrace() at error.jl:46
eval(::Module, ::Any) at boot.jl:236
eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66
macro expansion at REPL.jl:97 [inlined]
(::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73</code></pre><p>Notice that the vector returned by <a href="../stdlib/base.html#Base.backtrace"><code>backtrace()</code></a> had 21 pointers, while the vector returned by <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> only has 5. This is because, by default, <a href="../stdlib/stacktraces.html#Base.StackTraces.stacktrace"><code>stacktrace()</code></a> removes any lower-level C functions from the stack. If you want to include stack frames from C calls, you can do it like this:</p><pre><code class="language-julia-repl">julia&gt; stacktrace(trace, true)
27-element Array{StackFrame,1}:
jl_backtrace_from_here at stackwalk.c:103
backtrace() at error.jl:46
backtrace() at sys.so:?
jl_call_method_internal at julia_internal.h:248 [inlined]
jl_apply_generic at gf.c:2215
do_call at interpreter.c:75
eval at interpreter.c:215
eval_body at interpreter.c:519
jl_interpret_toplevel_thunk at interpreter.c:664
jl_toplevel_eval_flex at toplevel.c:592
jl_toplevel_eval_in at builtins.c:614
eval(::Module, ::Any) at boot.jl:236
eval(::Module, ::Any) at sys.so:?
jl_call_method_internal at julia_internal.h:248 [inlined]
jl_apply_generic at gf.c:2215
eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:66
ip:0x7f1c707f1846
jl_call_method_internal at julia_internal.h:248 [inlined]
jl_apply_generic at gf.c:2215
macro expansion at REPL.jl:97 [inlined]
(::Base.REPL.##1#2{Base.REPL.REPLBackend})() at event.jl:73
ip:0x7f1c707ea1ef
jl_call_method_internal at julia_internal.h:248 [inlined]
jl_apply_generic at gf.c:2215
jl_apply at julia.h:1411 [inlined]
start_task at task.c:261
ip:0xffffffffffffffff</code></pre><p>Individual pointers returned by <a href="../stdlib/base.html#Base.backtrace"><code>backtrace()</code></a> can be translated into <a href="../stdlib/stacktraces.html#Base.StackTraces.StackFrame"><code>StackFrame</code></a> s by passing them into <a href="../stdlib/stacktraces.html#Base.StackTraces.lookup"><code>StackTraces.lookup()</code></a>:</p><pre><code class="language-julia-repl">julia&gt; pointer = backtrace()[1];
julia&gt; frame = StackTraces.lookup(pointer)
1-element Array{StackFrame,1}:
jl_backtrace_from_here at stackwalk.c:103
julia&gt; println(&quot;The top frame is from $(frame[1].func)!&quot;)
The top frame is from jl_backtrace_from_here!</code></pre><footer><hr/><a class="previous" href="profile.html"><span class="direction">Previous</span><span class="title">Profiling</span></a><a class="next" href="performance-tips.html"><span class="direction">Next</span><span class="title">Performance Tips</span></a></footer></article></body></html>