From 0ab6919c327de2a8de8cdef24d465f7fa0db99d8 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 15c33f86524cd..06664623dc7f5 100644 --- a/src/debuginfo.cpp +++ b/src/debuginfo.cpp @@ -1101,7 +1101,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 0f1aa9d1356ae..85496b6d07ed3 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -1015,6 +1015,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