diff --git a/src/CodeTracking.jl b/src/CodeTracking.jl index 07997b0..2b6a1ac 100644 --- a/src/CodeTracking.jl +++ b/src/CodeTracking.jl @@ -42,17 +42,11 @@ function whereis(method::Method) end end if lin === nothing - file, line = maybe_fixup_stdlib_path(String(method.file)), method.line + file, line = String(method.file), method.line else file, line = fileline(lin[1]) end - if !isabspath(file) - # This may be a Base or Core method - newfile = Base.find_source_file(file) - if isa(newfile, AbstractString) - file = normpath(newfile) - end - end + file = maybe_fix_path(file) return file, line end @@ -77,7 +71,21 @@ was compiled. The current location is returned. """ function whereis(lineinfo, method::Method) file, line1 = whereis(method) - return file, lineinfo.line-method.line+line1 + # We could be in an expanded macro. Apply the correction only if the filename checks out. + # (We're not super-fastidious here because of symlinks and other path ambiguities) + samefile = basename(file) == basename(String(lineinfo.file)) + if !samefile + return maybe_fix_path(String(lineinfo.file)), lineinfo.line + end + return file, lineinfo.line - method.line + line1 +end +function whereis(lineinfo::Core.LineInfoNode, method::Method) + # With LineInfoNode we have certainty about whether we're in a macro expansion + if lineinfo.method == Symbol("macro expansion") + return maybe_fix_path(String(lineinfo.file)), lineinfo.line + end + file, line1 = whereis(method) + return file, lineinfo.line - method.line + line1 end """ diff --git a/src/utils.jl b/src/utils.jl index 1e836ad..0f3ad87 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -46,6 +46,22 @@ function basepath(id::PkgId) return dirname(dirname(loc)) end +""" + path = maybe_fix_path(path) + +Return a normalized, absolute path for a source file `path`. +""" +function maybe_fix_path(file) + if !isabspath(file) + # This may be a Base or Core method + newfile = Base.find_source_file(file) + if isa(newfile, AbstractString) + file = normpath(newfile) + end + end + return maybe_fixup_stdlib_path(file) +end + const BUILDBOT_STDLIB_PATH = dirname(abspath(joinpath(String((@which uuid1()).file), "..", "..", ".."))) replace_buildbot_stdlibpath(str::String) = replace(str, BUILDBOT_STDLIB_PATH => Sys.STDLIB) """ @@ -54,7 +70,7 @@ replace_buildbot_stdlibpath(str::String) = replace(str, BUILDBOT_STDLIB_PATH => Return `path` corrected for julia issue [#26314](https://github.com/JuliaLang/julia/issues/26314) if applicable. Otherwise, return the input `path` unchanged. -Due to the issue mentioned above, location info for methods defined one of Julia's standard libraries +Due to the issue mentioned above, location info for methods defined one of Julia's standard libraries are, for non source Julia builds, given as absolute paths on the worker that built the `julia` executable. This function corrects such a path to instead refer to the local path on the users drive. """ @@ -64,4 +80,4 @@ function maybe_fixup_stdlib_path(path) isfile(maybe_stdlib_path) && return maybe_stdlib_path end return path -end \ No newline at end of file +end diff --git a/test/runtests.jl b/test/runtests.jl index 5828cc9..24fcc71 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -56,4 +56,16 @@ include("script.jl") m = first(methods(Test.eval)) @test occursin(Sys.STDLIB, whereis(m)[1]) + + # https://github.com/JuliaDebug/JuliaInterpreter.jl/issues/150 + function f150() + x = 1 + 1 + @info "hello" + end + m = first(methods(f150)) + src = Base.uncompressed_ast(m) + idx = findfirst(lin -> String(lin.file) != @__FILE__, src.linetable) + lin = src.linetable[idx] + file, line = whereis(lin, m) + @test endswith(file, String(lin.file)) end