From 9254eff4904f31bbe529d5803234d25780df02e8 Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 7 Oct 2022 11:43:22 +0100 Subject: [PATCH] Track IDs created in functions and empty them when they leave scope * This prevents a use-after-free issue when pointers are stored and the backing storage is deallocated, if the function is entered again we try to get the previous value to show a variable change an dereference it. --- renderdoc/driver/shaders/spirv/spirv_debug.cpp | 8 ++++++++ renderdoc/driver/shaders/spirv/spirv_debug.h | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.cpp b/renderdoc/driver/shaders/spirv/spirv_debug.cpp index 89a7126e2..7543e1a23 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_debug.cpp @@ -342,6 +342,11 @@ void ThreadState::SetDst(Id id, const ShaderVariable &val) ShaderVariable prev = ids[id]; + // if this id didn't exist before it's not a global so it's a local variable, function parameter, + // or plain id. Track it in the current frame so it's emptied upon return + if(prev.name.empty() && prev.type == VarType::Unknown) + callstack.back()->idsCreated.push_back(id); + ids[id] = val; ids[id].name = GetRawName(id); @@ -3037,6 +3042,9 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray live = callstack.back()->live; } + for(Id id : exitingFrame->idsCreated) + ids[id] = ShaderVariable(); + delete exitingFrame; break; diff --git a/renderdoc/driver/shaders/spirv/spirv_debug.h b/renderdoc/driver/shaders/spirv/spirv_debug.h index 372109a94..e00ac8797 100644 --- a/renderdoc/driver/shaders/spirv/spirv_debug.h +++ b/renderdoc/driver/shaders/spirv/spirv_debug.h @@ -143,6 +143,12 @@ struct StackFrame // allocated storage for locals rdcarray locals; + // list of Ids we created, either variables/function parameters in this function, or IDs created + // in this function. When we return from this frame they will be emptied. + // This prevents a use-after-free with ShaderVariableChanges if we re-enter the same function + // and want to show the previous value of an id + rdcarray idsCreated; + // as a hack for scoping without proper debug info, we track locals from their first use rdcarray localsUsed;