From c045cbea973ea4aeab0cfbb41dac1d54b0c176c9 Mon Sep 17 00:00:00 2001 From: Jameson Nash Date: Sun, 16 Dec 2018 21:09:56 -0500 Subject: [PATCH] stacktrace: prevent OOB-error in sysimage lookup (#30369) Previously, with a multi-versioned system image, there might be additional entries at the end of the clone list that do not correspond to an actual method (such as jlplt thunks). Also some code cleanup for clarity. fix #28648 (cherry picked from commit e51a7075d74e86274d694b9b9f5e475b57c05439) --- src/debuginfo.cpp | 3 ++- src/staticdata.c | 1 + stdlib/Profile/src/Profile.jl | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/debuginfo.cpp b/src/debuginfo.cpp index 737508301776a..c092bbf458a93 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -1087,7 +1087,8 @@ static int jl_getDylibFunctionInfo(jl_frame_t **frames, size_t pointer, int skip for (size_t i = 0; i < sysimg_fptrs.nclones; i++) { if (diff == sysimg_fptrs.clone_offsets[i]) { uint32_t idx = sysimg_fptrs.clone_idxs[i] & jl_sysimg_val_mask; - frame0->linfo = sysimg_fvars_linfo[idx]; + if (idx < sysimg_fvars_n) // items after this were cloned but not referenced directly by a method (such as our ccall PLT thunks) + frame0->linfo = sysimg_fvars_linfo[idx]; break; } } diff --git a/src/staticdata.c b/src/staticdata.c index 921abb4b770be..363e0d716c3bb 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1016,6 +1016,7 @@ static void jl_update_all_fptrs(jl_serializer_state *s) for (i = 0; i < sysimg_fvars_max; i++) { uintptr_t val = (uintptr_t)&linfos[i]; uint32_t offset = load_uint32(&val); + linfos[i] = NULL; if (offset != 0) { int specfunc = 1; if (offset & ((uintptr_t)1 << (8 * sizeof(uint32_t) - 1))) { diff --git a/stdlib/Profile/src/Profile.jl b/stdlib/Profile/src/Profile.jl index 5cb34e132942f..8ae9542c2c2f4 100644 --- a/stdlib/Profile/src/Profile.jl +++ b/stdlib/Profile/src/Profile.jl @@ -514,6 +514,7 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI # jump forward to the end of the inlining chain # avoiding an extra (slow) lookup of `ip` in `lidict` # and an extra chain of them in `down` + # note that we may even have this === parent (if we're ignoring this frame ip) this = builder_value[fastkey] let this = this while this !== parent @@ -532,8 +533,7 @@ function tree!(root::StackFrameTree{T}, all::Vector{UInt64}, lidict::Union{LineI frame = (frames isa Vector ? frames[i] : frames) !C && frame.from_c && continue key = (T === UInt64 ? ip : frame) - down = parent.down - this = get!(down, key) do + this = get!(parent.down, key) do return StackFrameTree{T}() end this.frame = frame