# Inspecting the stack

**URL:** <https://discourse.julialang.org/t/inspecting-the-stack/376>\
**Category:** General Usage\
**Tags:** question\
**Created:** [November 17, 2016, 6:17am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376 "2016-11-17T06:17:45Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 17, 2016, 6:17am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/1 "2016-11-17T06:17:45Z")

</div>

Hello,

Is there any way to inspect the stack when an exception is thrown? This was my top debugging tool in Python and Common Lisp, and I really miss it in Julia. To be clear, I mean going up and down stack frames, and printing the value of local variables in those frames. Even just getting access to the function arguments would be invaluable.

Cédric

---

<div class="post-metadata">

**Author:** ![TsurHerman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tsurherman/32/1234_2.png) [@TsurHerman](https://discourse.julialang.org/u/TsurHerman)\
**Post date:** [November 17, 2016, 8:13am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/2 "2016-11-17T08:13:22Z")

</div>

I was thinking of a special mode in julia , where each function is replaced by an anonymous module or a closure  
(I don’t think thee is a big difference between the 2) .

I think what’s blocking this , is the fact there is no way to un-load modules.

---

<div class="post-metadata">

**Author:** ![martinholters](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/martinholters/32/3690_2.png) [@martinholters](https://discourse.julialang.org/u/martinholters)\
**Post date:** [November 17, 2016, 10:37am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/3 "2016-11-17T10:37:50Z")

</div>

[Gallium](https://github.com/Keno/Gallium.jl) (with `breakpoint_on_error()`) might be what you are looking for. I have no idea how stable it is, though.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 17, 2016, 1:32pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/4 "2016-11-17T13:32:08Z")

</div>

Gallium crashes on my system, but you’re right: it has a function to go to arbitrary frames.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 18, 2016, 4:29pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/5 "2016-11-18T16:29:14Z")

</div>

`catch_stacktrace()` can give me the latest error’s stack-trace. Is there any way to access a StackFrame’s local argument values? Or are they lost during the stack unwind? If so, how come the trace’s function signatures are recoverable?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 18, 2016, 5:08pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/6 "2016-11-18T17:08:33Z")

</div>

You can know the signature from the function pointer. Recovering local variables is much harder and can be impossible if we unwind through certain C libraries.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 18, 2016, 8:52pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/7 "2016-11-18T20:52:09Z")

</div>

That makes sense. I suppose the best starting point for this would be Gallium.jl?

I’d like to get a reality check. My understanding right now is that when an exception is triggered, the stack is unwound, meaning that all kinds of finalizer code is run on the way back down, and the stack pointer points to the base of the stack in the absence of exception handlers. Does Julia make a copy of the stack before unwinding the stack? If not, how can `catch_stracktrace` confidently recover the last trace, given that other functions (eg. finalizers) may have been called, and overwritten parts of the stack?

> [@yuyichao](#):
>
> Recovering local variables is much harder and can be impossible if we unwind through certain C libraries.

There are obvious candidates in my mind for “C libraries” (PyCall, RMath, …) Are there instances of “pure, non-mathematical Julia code” that get compiled into C-calls with Julia callbacks?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 18, 2016, 9:02pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/8 "2016-11-18T21:02:28Z")

</div>

> [@cstjean](#):
>
> My understanding right now is that when an exception is triggered, the stack is unwound

Yes.

> [@cstjean](#):
>
> meaning that all kinds of finalizer code is run on the way back down

In C++ yes, not in julia. Finalizers only run when the GC triggers.

> [@cstjean](#):
>
> Does Julia make a copy of the stack before unwinding the stack?

No.

> [@cstjean](#):
>
> If not, how can `catch_stracktrace` confidently recover the last trace, given that other functions (eg. finalizers) may have been called, and overwritten parts of the stack?

Finalizers are irrelevant. We do SJLJ exception handling and we collect a backtrace before unwinding. We are considering copying the stack instead since it could be faster when we don’t need the backtrace.

> [@cstjean](#):
>
> Are there instances of “pure, non-mathematical Julia code” that get compiled into C-calls with Julia callbacks?

Not really sure what you mean, julia code won’t be compiled into C code.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 19, 2016, 12:37am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/9 "2016-11-19T00:37:41Z")

</div>

Sorry, I misspoke, I didn’t mean GC finalizers; I meant the “finally” part of a try-catch-finally. Thank you for the SJLJ pointer, it makes sense.

> [@yuyichao](#):
>
> We are considering copying the stack instead since it could be faster when we don’t need the backtrace.

Couldn’t you compute the backtrace from the copy of the stack?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [November 21, 2016, 9:24pm UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/10 "2016-11-21T21:24:32Z")

</div>

> [@cstjean](#):
>
> I meant the “finally” part of a try-catch-finally

The `finally` is actually a `catch` and `rethrow`, in general though, by the time you unwind the stack the old stack is destroyed so it doesn’t really need to run anything to destroy it (the code you run to inspect the stack after unwinding will destroy the old stack for you).

> [@cstjean](#):
>
> Couldn’t you compute the backtrace from the copy of the stack?

Yes? And that’s why we are considering it.

---

<div class="post-metadata">

**Author:** ![the\_duke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/the_duke/32/206628_2.png) [@the\_duke](https://discourse.julialang.org/u/the_duke)\
**Post date:** [July 30, 2025, 11:03am UTC](https://discourse.julialang.org/t/inspecting-the-stack/376/11 "2025-07-30T11:03:56Z")

</div>

Update for visitors: as of 2025 catch\_stacktrace() seem to be gone.

stacktrace(catch\_backtrace())  
Seem to be working instead.
