Is there a way to get the line number of the calling function?
I would like to encode the filename and the line number of a type.
so for example if I have
type foo
line::Int32
fname::String
end
what should be in the constructor so if I have
a = foo() in file “temp.jl” and in line 100 , this information will be present within the instance of foo stored in a.
This is meant as a way to provide better error messages for async tasks.
I accept any trickery using stacktraces or backtraces …
Maybe the Juno guys have an idea?
Check out the backtrace
and StackTraces.lookup
:
julia> bt = backtrace()
21-element Array{Ptr{Void},1}:
Ptr{Void} @0x00007fc2a2cbeb38
Ptr{Void} @0x00007fc29d1c8c7c
Ptr{Void} @0x00007fc29d1c8c89
Ptr{Void} @0x00007fc2a2c7b990
Ptr{Void} @0x00007fc2a2c9067e
Ptr{Void} @0x00007fc2a2c8f75e
Ptr{Void} @0x00007fc2a2c90d29
Ptr{Void} @0x00007fc2a2c9114f
Ptr{Void} @0x00007fc2a2caae5d
Ptr{Void} @0x00007fc2a2c8b27c
Ptr{Void} @0x00007fc29cf8009a
Ptr{Void} @0x00007fc29cf800b0
Ptr{Void} @0x00007fc2a2c7b990
Ptr{Void} @0x00007fc08d88edb7
Ptr{Void} @0x00007fc08d88f017
Ptr{Void} @0x00007fc2a2c7b990
Ptr{Void} @0x00007fc08d88bbff
Ptr{Void} @0x00007fc08d88bf10
Ptr{Void} @0x00007fc2a2c7b990
Ptr{Void} @0x00007fc2a2c9969f
Ptr{Void} @0x0000000000000000
julia> StackTraces.lookup.(bt)
21-element Array{Array{StackFrame,1},1}:
StackFrame[ in jl_backtrace_from_here at stackwalk.c:105]
StackFrame[ in backtrace() at error.jl:26]
StackFrame[ in backtrace() at sys.so:?]
StackFrame[ in jl_call_method_internal at julia_internal.h:189 [inlined], in jl_apply_generic at gf.c:1945]
StackFrame[ in do_call at interpreter.c:66]
StackFrame[ in eval at interpreter.c:190]
StackFrame[ in eval_body at interpreter.c:469]
StackFrame[ in jl_interpret_call at interpreter.c:573]
StackFrame[ in jl_toplevel_eval_flex at toplevel.c:572 [inlined], in jl_toplevel_eval at toplevel.c:580]
StackFrame[ in jl_toplevel_eval_in_warn at builtins.c:590]
StackFrame[ in eval(::Module, ::Any) at boot.jl:234]
StackFrame[ in eval(::Module, ::Any) at sys.so:?]
StackFrame[ in jl_call_method_internal at julia_internal.h:189 [inlined], in jl_apply_generic at gf.c:1945]
StackFrame[ in eval_user_input(::Any, ::Base.REPL.REPLBackend) at REPL.jl:64]
StackFrame[ in ip:0x7fc08d88f016]
StackFrame[ in jl_call_method_internal at julia_internal.h:189 [inlined], in jl_apply_generic at gf.c:1945]
StackFrame[ in macro expansion at REPL.jl:95 [inlined], in (::Base.REPL.##3#4{Base.REPL.REPLBackend})() at event.jl:68]
StackFrame[ in ip:0x7fc08d88bf0f]
StackFrame[ in jl_call_method_internal at julia_internal.h:189 [inlined], in jl_apply_generic at gf.c:1945]
StackFrame[ in jl_apply at julia.h:1392 [inlined], in start_task at task.c:253]
StackFrame[ in ip:0xffffffffffffffff]
1 Like
The stacktrace function works if the calling was done from within some function … then in that case
stacktrace[2] is the calling function.
However if the call is not wrapped in function then I am left with
include_from_node1(::String) at loading.jl:488
as the calling file and line…
So I am wondering whether it is possible to infer the calling line and file name even if the code is not wrapped
in a function … for example in scripts.
I’m not sure this is currently possible. You could create a special inner constructor and the caller could use Foo(line, fname, file=@__FILE__, line=@__LINE__)
. As long as it’s the caller that’s using @__FILE__
and @__LINE__
then I think you’ll get the information you need. Painful, I know.