From 7b41323907607fd66c69916325296523b3ee3858 Mon Sep 17 00:00:00 2001 From: maxcharlamb Date: Wed, 25 Jun 2025 11:52:49 -0400 Subject: [PATCH 1/2] stop linking in native components --- .../Contracts/StackWalk/Context/Unwinder.cs | 172 ------------------ .../mscordaccore_universal.csproj | 12 -- 2 files changed, 184 deletions(-) delete mode 100644 src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs deleted file mode 100644 index 151614d1681182..00000000000000 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/Context/Unwinder.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Runtime.InteropServices; -using Microsoft.Diagnostics.DataContractReader.Contracts.StackWalkHelpers; -using System.Collections.Generic; -using System.Diagnostics; - -namespace Microsoft.Diagnostics.DataContractReader.Contracts; -internal static unsafe partial class Unwinder -{ - [LibraryImport("unwinder_cdac_arm64", EntryPoint = "arm64Unwind")] - private static partial int ARM64Unwind( - ref ARM64Context context, - delegate* unmanaged readFromTarget, - delegate* unmanaged getAllocatedBuffer, - delegate* unmanaged getStackWalkInfo, - delegate* unmanaged unwinderFail, - void* callbackContext); - - public static int ARM64Unwind( - ref ARM64Context context, - Target target) - { - using CallbackContext callbackContext = new(target); - - GCHandle handle = GCHandle.Alloc(callbackContext); - int ret = ARM64Unwind( - ref context, - &ReadFromTarget, - &GetAllocatedBuffer, - &GetStackWalkInfo, - &UnwinderFail, - GCHandle.ToIntPtr(handle).ToPointer()); - handle.Free(); - - return ret; - } - - [LibraryImport("unwinder_cdac_amd64", EntryPoint = "amd64Unwind")] - private static partial int AMD64Unwind( - ref AMD64Context context, - delegate* unmanaged readFromTarget, - delegate* unmanaged getAllocatedBuffer, - delegate* unmanaged getStackWalkInfo, - delegate* unmanaged unwinderFail, - void* callbackContext); - - public static int AMD64Unwind( - ref AMD64Context context, - Target target) - { - using CallbackContext callbackContext = new(target); - - GCHandle handle = GCHandle.Alloc(callbackContext); - int ret = AMD64Unwind( - ref context, - &ReadFromTarget, - &GetAllocatedBuffer, - &GetStackWalkInfo, - &UnwinderFail, - GCHandle.ToIntPtr(handle).ToPointer()); - handle.Free(); - - return ret; - } - - /// - /// Used to inject target into unwinder callbacks and track memory allocated for native unwinder. - /// - private sealed class CallbackContext(Target target) : IDisposable - { - private bool disposed; - public Target Target { get; } = target; - public List AllocatedRegions { get; } = []; - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - private void Dispose(bool disposing) - { - if (disposed) return; - - if (disposing) - { - foreach (IntPtr ptr in AllocatedRegions) - { - NativeMemory.Free(ptr.ToPointer()); - } - } - disposed = true; - } - } - - // ReadFromTarget allows the unwinder to read memory from the target process - // into an allocated buffer. This buffer is either allocated by the unwinder - // with its lifetime managed by the unwinder or allocated through GetAllocatedBuffer. - // In the latter case, the unwinder can only use the buffer for the duration of the - // unwind call. Once the call is over the cDAC will free all allocated buffers. - [UnmanagedCallersOnly] - private static unsafe int ReadFromTarget(ulong address, void* pBuffer, int bufferSize, void* context) - { - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - Span span = new Span(pBuffer, bufferSize); - try - { - callbackContext.Target.ReadBuffer(address, span); - } - catch (InvalidOperationException) - { - // if the read fails, the unwinder behavior changes. Return failing HR instead of throwing - return -1; - } - return 0; - } - - // GetAllocatedBuffer allows the unwinder to allocate a buffer that will be freed - // once the unwinder call is complete. - // Freeing is handeled in the Dispose method of CallbackContext. - [UnmanagedCallersOnly] - private static unsafe int GetAllocatedBuffer(int bufferSize, void** ppBuffer, void* context) - { - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - *ppBuffer = NativeMemory.Alloc((nuint)bufferSize); - callbackContext.AllocatedRegions.Add((IntPtr)(*ppBuffer)); - return 0; - } - - // cDAC version of GetRuntimeStackWalkInfo defined in codeman.cpp - // To maintain the same signature as the original function, this returns void. - // If the unwindInfoBase or funcEntry can not be found, both will be 0. - [UnmanagedCallersOnly] - private static unsafe void GetStackWalkInfo(ulong controlPC, void* pUnwindInfoBase, void* pFuncEntry, void* context) - { - if ((nuint)pUnwindInfoBase != 0) *(nuint*)pUnwindInfoBase = 0; - if ((nuint)pFuncEntry != 0) *(nuint*)pFuncEntry = 0; - - CallbackContext callbackContext = (CallbackContext)GCHandle.FromIntPtr((IntPtr)context).Target!; - - IExecutionManager eman = callbackContext.Target.Contracts.ExecutionManager; - try - { - if (eman.GetCodeBlockHandle(controlPC) is CodeBlockHandle cbh) - { - if ((nuint)pUnwindInfoBase != 0) - { - TargetPointer unwindInfoBase = eman.GetUnwindInfoBaseAddress(cbh); - *(nuint*)pUnwindInfoBase = (nuint)unwindInfoBase.Value; - } - if ((nuint)pFuncEntry != 0) - { - TargetPointer unwindInfo = eman.GetUnwindInfo(cbh); - *(nuint*)pFuncEntry = (nuint)unwindInfo.Value; - } - } - } - catch (System.Exception ex) - { - Console.WriteLine($"GetStackWalkInfo failed: {ex}"); - } - } - - [UnmanagedCallersOnly] - private static void UnwinderFail() - { - Debug.Fail("Native unwinder assertion failure."); - } -} diff --git a/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj b/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj index 23e689d16d9aa5..a9c40757f98657 100644 --- a/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj +++ b/src/native/managed/cdac/mscordaccore_universal/mscordaccore_universal.csproj @@ -31,18 +31,6 @@ - - - - - - - - - - - - From 4dad0949900aa3957f9ca57eec1e6b91df710452 Mon Sep 17 00:00:00 2001 From: maxcharlamb Date: Wed, 25 Jun 2025 11:53:03 -0400 Subject: [PATCH 2/2] revert changes to native components which allowed them to support cdac --- src/coreclr/unwinder/CMakeLists.txt | 117 ++---------------- src/coreclr/unwinder/amd64/unwinder.cpp | 156 +++++------------------- src/coreclr/unwinder/amd64/unwinder.h | 8 -- src/coreclr/unwinder/arm64/unwinder.cpp | 33 +---- src/coreclr/unwinder/arm64/unwinder.h | 7 -- src/coreclr/unwinder/baseunwinder.cpp | 26 ---- src/coreclr/unwinder/baseunwinder.h | 40 +----- src/coreclr/unwinder/stdafx.h | 9 +- 8 files changed, 52 insertions(+), 344 deletions(-) diff --git a/src/coreclr/unwinder/CMakeLists.txt b/src/coreclr/unwinder/CMakeLists.txt index 01c7bca64a7888..1c82808f0366a4 100644 --- a/src/coreclr/unwinder/CMakeLists.txt +++ b/src/coreclr/unwinder/CMakeLists.txt @@ -1,18 +1,19 @@ -# helper to add set of include directories to unwinder targets -macro(add_unwinder_include_directories TARGET) - target_include_directories(${TARGET} BEFORE PRIVATE ${VM_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) - target_include_directories(${TARGET} BEFORE PRIVATE ${CLR_DIR}/unwinder) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/debug/ee) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/gc) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/gcdump) - target_include_directories(${TARGET} PRIVATE ${CLR_DIR}/debug/daccess) - target_include_directories(${TARGET} PRIVATE ${ARCH_SOURCES_DIR}) -endmacro() +include_directories(BEFORE ${VM_DIR}) +include_directories(BEFORE ${VM_DIR}/${ARCH_SOURCES_DIR}) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(BEFORE ${CLR_DIR}/unwinder) +include_directories(${CLR_DIR}/debug/ee) +include_directories(${CLR_DIR}/gc) +include_directories(${CLR_DIR}/gcdump) +include_directories(${CLR_DIR}/debug/daccess) set(UNWINDER_SOURCES baseunwinder.cpp +) + +# Include platform specific unwinder for applicable (native and cross-target) builds. +include_directories(${ARCH_SOURCES_DIR}) +list(APPEND UNWINDER_SOURCES ${ARCH_SOURCES_DIR}/unwinder.cpp ) @@ -20,102 +21,10 @@ convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES}) if(CLR_CMAKE_HOST_UNIX) add_library_clr(unwinder_wks OBJECT ${UNWINDER_SOURCES}) - add_unwinder_include_directories(unwinder_wks) add_dependencies(unwinder_wks eventing_headers) endif(CLR_CMAKE_HOST_UNIX) add_library_clr(unwinder_dac ${UNWINDER_SOURCES}) -add_unwinder_include_directories(unwinder_dac) add_dependencies(unwinder_dac eventing_headers) set_target_properties(unwinder_dac PROPERTIES DAC_COMPONENT TRUE) target_compile_definitions(unwinder_dac PRIVATE FEATURE_NO_HOST) - -### cDAC Unwinders #### - -set(BASE_UNWINDER_SOURCES baseunwinder.cpp) -convert_to_absolute_path(BASE_UNWINDER_SOURCES ${BASE_UNWINDER_SOURCES}) -add_library_clr(unwinder_cdac_base STATIC ${BASE_UNWINDER_SOURCES}) - -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${VM_DIR}) -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(unwinder_cdac_base BEFORE PUBLIC ${CLR_DIR}/unwinder) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/debug/ee) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/gc) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/gcdump) -target_include_directories(unwinder_cdac_base PUBLIC ${CLR_DIR}/debug/daccess) -target_compile_definitions(unwinder_cdac_base PUBLIC FEATURE_NO_HOST FEATURE_CDAC_UNWINDER) - -if (CLR_CMAKE_TARGET_WIN32) - # cDAC unwinders are statically linked into the NativeAOT runtime which is built with - # release version of the statically linked CRT. Therefore we do the same here. - set_property(TARGET unwinder_cdac_base PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded) - - # _DEBUG is always passed as a parameter if the build is a debug build. - # This causes the debug CRT on MSVC to be used so we need to undefine it. - target_compile_options(unwinder_cdac_base PRIVATE -U_DEBUG) -endif() - -install_clr(TARGETS unwinder_cdac_base DESTINATIONS cdaclibs COMPONENT cdac) - -# Helper function for platform specific cDAC uwninder builds. -function(create_platform_unwinder) - set(oneValueArgs TARGET ARCH) - set(multiValueArgs DESTINATIONS) - cmake_parse_arguments(TARGETDETAILS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(TARGETDETAILS_ARCH STREQUAL "x64") - set(ARCH_SOURCES_DIR amd64) - elseif((TARGETDETAILS_ARCH STREQUAL "arm") OR (TARGETDETAILS_ARCH STREQUAL "armel")) - set(ARCH_SOURCES_DIR arm) - elseif(TARGETDETAILS_ARCH STREQUAL "x86") - set(ARCH_SOURCES_DIR i386) - elseif(TARGETDETAILS_ARCH STREQUAL "arm64") - set(ARCH_SOURCES_DIR arm64) - else() - clr_unknown_arch() - endif() - - set(UNWINDER_SOURCES ${ARCH_SOURCES_DIR}/unwinder.cpp) - convert_to_absolute_path(UNWINDER_SOURCES ${UNWINDER_SOURCES}) - add_library_clr(${TARGETDETAILS_TARGET} STATIC ${UNWINDER_SOURCES}) - - target_include_directories(${TARGETDETAILS_TARGET} BEFORE PRIVATE ${VM_DIR}/${ARCH_SOURCES_DIR}) - target_include_directories(${TARGETDETAILS_TARGET} PRIVATE ${ARCH_SOURCES_DIR}) - - target_link_libraries(${TARGETDETAILS_TARGET} PRIVATE unwinder_cdac_base) - if (CLR_CMAKE_TARGET_WIN32) - # cDAC unwinders are statically linked into the NativeAOT runtime which is built with - # release version of the statically linked CRT. Therefore we do the same here. - set_property(TARGET ${TARGETDETAILS_TARGET} PROPERTY MSVC_RUNTIME_LIBRARY MultiThreaded) - - # _DEBUG is always passed as a parameter if the build is a debug build. - # This causes the debug CRT on MSVC to be used so we need to undefine it. - target_compile_options(${TARGETDETAILS_TARGET} PRIVATE -U_DEBUG) - endif() - - # add the install targets - install_clr(TARGETS ${TARGETDETAILS_TARGET} DESTINATIONS ${TARGETDETAILS_DESTINATIONS} COMPONENT cdac) - - # Set the target to be built for the specified OS and ARCH - set_target_definitions_to_custom_os_and_arch(TARGET ${TARGETDETAILS_TARGET} OS win ARCH ${TARGETDETAILS_ARCH}) - - target_compile_definitions(${TARGETDETAILS_TARGET} PRIVATE FEATURE_NO_HOST FEATURE_CDAC_UNWINDER) -endfunction() - -if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - create_platform_unwinder(TARGET unwinder_cdac_amd64 ARCH x64 DESTINATIONS cdaclibs) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - -if(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - -if(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - create_platform_unwinder(TARGET unwinder_cdac_amd64 ARCH x64 DESTINATIONS cdaclibs) -endif(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_AMD64) - -if(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - create_platform_unwinder(TARGET unwinder_cdac_arm64 ARCH arm64 DESTINATIONS cdaclibs) -endif(NOT CLR_CMAKE_TARGET_WIN32 AND CLR_CMAKE_TARGET_ARCH_ARM64) - diff --git a/src/coreclr/unwinder/amd64/unwinder.cpp b/src/coreclr/unwinder/amd64/unwinder.cpp index 57acbd30ab06e8..7fadcefd758aa7 100644 --- a/src/coreclr/unwinder/amd64/unwinder.cpp +++ b/src/coreclr/unwinder/amd64/unwinder.cpp @@ -8,7 +8,6 @@ typedef DPTR(M128A) PTR_M128A; -#ifndef FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // // Read 64 bit unsigned value from the specified address. When the unwinder is built @@ -52,29 +51,9 @@ static M128A MemoryRead128(PM128A addr) { return *dac_cast((TADDR)addr); } -#else -// Read 64 bit unsigned value from the specified addres when the unwinder is build -// for the cDAC. This triggers a callback to the cDAC host to read the memory from -// the target process. -static ULONG64 MemoryRead64(PULONG64 addr) -{ - ULONG64 value; - t_pCallbacks->readFromTarget((uint64_t)addr, &value, sizeof(value), t_pCallbacks->callbackContext); - return value; -} -// Read 128 bit value from the specified addres when the unwinder is build -// for the cDAC. This triggers a callback to the cDAC host to read the memory from -// the target process. -static M128A MemoryRead128(PM128A addr) -{ - M128A value; - t_pCallbacks->readFromTarget((uint64_t)addr, &value, sizeof(value), t_pCallbacks->callbackContext); - return value; -} -#endif // FEATURE_CDAC_UNWINDER +#ifdef DACCESS_COMPILE -#if defined(DACCESS_COMPILE) || defined(FEATURE_CDAC_UNWINDER) //--------------------------------------------------------------------------------------- // // The InstructionBuffer class abstracts accessing assembler instructions in the function @@ -89,19 +68,6 @@ class InstructionBuffer UCHAR m_buffer[32]; // Load the instructions from the target process being debugged -#ifdef FEATURE_CDAC_UNWINDER - HRESULT Load() - { - HRESULT hr = t_pCallbacks->readFromTarget(m_address, m_buffer, sizeof(m_buffer), t_pCallbacks->callbackContext); - if (SUCCEEDED(hr)) - { - // TODO: Implement breakpoint patching for cDAC - // https://github.com/dotnet/runtime/issues/112273#issue-2838620747 - } - - return hr; - } -#else // FEATURE_CDAC_UNWINDER HRESULT Load() { HRESULT hr = DacReadAll(TO_TADDR(m_address), m_buffer, sizeof(m_buffer), false); @@ -116,7 +82,6 @@ class InstructionBuffer return hr; } -#endif // FEATURE_CDAC_UNWINDER public: @@ -161,7 +126,7 @@ class InstructionBuffer } // Get the byte at the given index from the current position - // Assert that the index is within the buffer + // Invoke DacError if the index is out of the buffer UCHAR operator[](int index) { int realIndex = m_offset + index; @@ -169,9 +134,7 @@ class InstructionBuffer return m_buffer[realIndex]; } }; -#endif // DACCESS_COMPILE || FEATURE_CDAC_UNWINDER -#ifdef DACCESS_COMPILE //--------------------------------------------------------------------------------------- // // Given the target address of an UNWIND_INFO structure, this function retrieves all the memory used for @@ -251,57 +214,47 @@ BOOL DacUnwindStackFrame(CONTEXT * pContext, KNONVOLATILE_CONTEXT_POINTERS* pCon return res; } -#elif defined(FEATURE_CDAC_UNWINDER) - -BOOL amd64Unwind(void* pContext, ReadFromTarget readFromTarget, GetAllocatedBuffer getAllocatedBuffer, GetStackWalkInfo getStackWalkInfo, UnwinderFail unwinderFail, void* callbackContext) -{ - CDACCallbacks callbacks { readFromTarget, getAllocatedBuffer, getStackWalkInfo, unwinderFail, callbackContext }; - t_pCallbacks = &callbacks; - BOOL res = OOPStackUnwinderAMD64::Unwind((CONTEXT*) pContext); - t_pCallbacks = nullptr; - - return res; -} +//--------------------------------------------------------------------------------------- +// +// Unwind the given CONTEXT to the caller CONTEXT. The given CONTEXT will be overwritten. +// +// Arguments: +// pContext - in-out parameter storing the specified CONTEXT on entry and the unwound CONTEXT on exit +// +// Return Value: +// TRUE if the unwinding is successful +// -UNWIND_INFO * OOPStackUnwinderAMD64::GetUnwindInfo(TADDR taUnwindInfo) +BOOL OOPStackUnwinderAMD64::Unwind(CONTEXT * pContext) { - UNWIND_INFO unwindInfo; - if(t_pCallbacks->readFromTarget((uint64_t)taUnwindInfo, &unwindInfo, sizeof(unwindInfo), t_pCallbacks->callbackContext) != S_OK) - { - return NULL; - } + HRESULT hr = E_FAIL; - DWORD cbUnwindInfo = offsetof(UNWIND_INFO, UnwindCode) + - unwindInfo.CountOfUnwindCodes * sizeof(UNWIND_CODE); + ULONG64 uControlPC = (DWORD64)dac_cast(::GetIP(pContext)); - // Check if there is a chained unwind info. If so, it has an extra RUNTIME_FUNCTION tagged to the end. - if ((unwindInfo.Flags & UNW_FLAG_CHAININFO) != 0) + // get the module base + ULONG64 uImageBase; + hr = GetModuleBase(uControlPC, &uImageBase); + if (FAILED(hr)) { - // If there is an odd number of UNWIND_CODE, we need to adjust for alignment. - if ((unwindInfo.CountOfUnwindCodes & 1) != 0) - { - cbUnwindInfo += sizeof(UNWIND_CODE); - } - cbUnwindInfo += sizeof(T_RUNTIME_FUNCTION); + return FALSE; } - // Allocate a buffer for the unwind info from cDAC callback. - // This buffer will be freed by the cDAC host once unwinding is done. - UNWIND_INFO* pUnwindInfo; - if(t_pCallbacks->getAllocatedBuffer(cbUnwindInfo, (void**)&pUnwindInfo, t_pCallbacks->callbackContext) != S_OK) + // get the function entry + IMAGE_RUNTIME_FUNCTION_ENTRY functionEntry; + hr = GetFunctionEntry(uControlPC, &functionEntry, sizeof(functionEntry)); + if (FAILED(hr)) { - return NULL; + return FALSE; } - if(t_pCallbacks->readFromTarget(taUnwindInfo, pUnwindInfo, cbUnwindInfo, t_pCallbacks->callbackContext) != S_OK) - { - return NULL; - } + // call VirtualUnwind() to do the real work + ULONG64 EstablisherFrame; + hr = VirtualUnwind(0, uImageBase, uControlPC, &functionEntry, pContext, NULL, &EstablisherFrame, NULL, NULL); - return pUnwindInfo; + return (hr == S_OK); } -#else // !DACCESS_COMPILE && !FEATURE_CDAC_UNWINDER +#else // DACCESS_COMPILE // For unwinding of the jitted code on non-Windows platforms, the Instruction buffer is // just a plain pointer to the instruction data. @@ -385,57 +338,13 @@ PEXCEPTION_ROUTINE RtlVirtualUnwind_Unsafe( ContextPointers, &handlerRoutine); - UNWINDER_ASSERT(SUCCEEDED(res)); + _ASSERTE(SUCCEEDED(res)); return handlerRoutine; } -#endif // !DACCESS_COMPILE && !FEATURE_CDAC_UNWINDER - -//--------------------------------------------------------------------------------------- -// -// Unwind the given CONTEXT to the caller CONTEXT. The given CONTEXT will be overwritten. -// -// Arguments: -// pContext - in-out parameter storing the specified CONTEXT on entry and the unwound CONTEXT on exit -// -// Return Value: -// TRUE if the unwinding is successful -// - -BOOL OOPStackUnwinderAMD64::Unwind(CONTEXT * pContext) -{ - HRESULT hr = E_FAIL; - - ULONG64 uControlPC = -#ifndef FEATURE_CDAC_UNWINDER - (DWORD64)dac_cast(::GetIP(pContext)); -#else // FEATURE_CDAC_UNWINDER - pContext->Rip; -#endif // FEATURE_CDAC_UNWINDER - // get the module base - ULONG64 uImageBase; - hr = GetModuleBase(uControlPC, &uImageBase); - if (FAILED(hr)) - { - return FALSE; - } - - // get the function entry - IMAGE_RUNTIME_FUNCTION_ENTRY functionEntry; - hr = GetFunctionEntry(uControlPC, &functionEntry, sizeof(functionEntry)); - if (FAILED(hr)) - { - return FALSE; - } - - // call VirtualUnwind() to do the real work - ULONG64 EstablisherFrame; - hr = VirtualUnwind(0, uImageBase, uControlPC, &functionEntry, pContext, NULL, &EstablisherFrame, NULL, NULL); - - return (hr == S_OK); -} +#endif // DACCESS_COMPILE // // @@ -1936,4 +1845,3 @@ Return Value: return Slots; } - diff --git a/src/coreclr/unwinder/amd64/unwinder.h b/src/coreclr/unwinder/amd64/unwinder.h index 1e990168921402..1c714224f32eb5 100644 --- a/src/coreclr/unwinder/amd64/unwinder.h +++ b/src/coreclr/unwinder/amd64/unwinder.h @@ -8,14 +8,6 @@ #include "baseunwinder.h" -#ifdef FEATURE_CDAC_UNWINDER -EXTERN_C BOOL amd64Unwind(void* pContext, - ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext); -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/arm64/unwinder.cpp b/src/coreclr/unwinder/arm64/unwinder.cpp index ed4238c98a6bf6..03351e02b41853 100644 --- a/src/coreclr/unwinder/arm64/unwinder.cpp +++ b/src/coreclr/unwinder/arm64/unwinder.cpp @@ -4,9 +4,7 @@ // #include "stdafx.h" -#ifndef FEATURE_CDAC_UNWINDER #include "utilcode.h" -#endif // FEATURE_CDAC_UNWINDER #include "crosscomp.h" #include "unwinder.h" @@ -166,25 +164,13 @@ typedef struct _ARM64_VFP_STATE // Macros for accessing memory. These can be overridden if other code // (in particular the debugger) needs to use them. -#if !defined(DEBUGGER_UNWIND) && !defined(FEATURE_CDAC_UNWINDER) +#if !defined(DEBUGGER_UNWIND) #define MEMORY_READ_BYTE(params, addr) (*dac_cast(addr)) -#define MEMORY_READ_WORD(params, addr) (*dac_cast(addr)) +#define MEMORY_READ_WORD(params, addr) (*dac_cast(addr)) #define MEMORY_READ_DWORD(params, addr) (*dac_cast(addr)) #define MEMORY_READ_QWORD(params, addr) (*dac_cast(addr)) -#elif defined(FEATURE_CDAC_UNWINDER) -template -T cdacRead(uint64_t addr) -{ - T t; - t_pCallbacks->readFromTarget(addr, &t, sizeof(t), t_pCallbacks->callbackContext); - return t; -} -#define MEMORY_READ_BYTE(params, addr) (cdacRead(addr)) -#define MEMORY_READ_WORD(params, addr) (cdacRead(addr)) -#define MEMORY_READ_DWORD(params, addr) (cdacRead(addr)) -#define MEMORY_READ_QWORD(params, addr) (cdacRead(addr)) #endif // @@ -2349,7 +2335,7 @@ Return Value: } // - // pac (11111100): function has pointer authentication + // pac (11111100): function has pointer authentication // else if (CurCode == 0xfc) { @@ -2773,7 +2759,6 @@ BOOL OOPStackUnwinderArm64::Unwind(T_CONTEXT * pContext) return TRUE; } -#ifdef DACCESS_COMPILE BOOL DacUnwindStackFrame(T_CONTEXT *pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers) { OOPStackUnwinderArm64 unwinder; @@ -2789,18 +2774,6 @@ BOOL DacUnwindStackFrame(T_CONTEXT *pContext, T_KNONVOLATILE_CONTEXT_POINTERS* p return res; } -#elif defined(FEATURE_CDAC_UNWINDER) -BOOL arm64Unwind(void* pContext, ReadFromTarget readFromTarget, GetAllocatedBuffer getAllocatedBuffer, GetStackWalkInfo getStackWalkInfo, UnwinderFail unwinderFail, void* callbackContext) -{ - CDACCallbacks callbacks { readFromTarget, getAllocatedBuffer, getStackWalkInfo, unwinderFail, callbackContext }; - t_pCallbacks = &callbacks; - OOPStackUnwinderArm64 unwinder; - BOOL res = unwinder.Unwind((T_CONTEXT*) pContext); - t_pCallbacks = nullptr; - - return res; -} -#endif // FEATURE_CDAC_UNWINDER #if defined(HOST_UNIX) diff --git a/src/coreclr/unwinder/arm64/unwinder.h b/src/coreclr/unwinder/arm64/unwinder.h index d85fdf6a09acc6..aa03c5a59fe9f1 100644 --- a/src/coreclr/unwinder/arm64/unwinder.h +++ b/src/coreclr/unwinder/arm64/unwinder.h @@ -8,13 +8,6 @@ #include "baseunwinder.h" -#ifdef FEATURE_CDAC_UNWINDER -EXTERN_C BOOL arm64Unwind(void* pContext, ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext); -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/baseunwinder.cpp b/src/coreclr/unwinder/baseunwinder.cpp index 2f2fecc7834045..b00c2aa114835e 100644 --- a/src/coreclr/unwinder/baseunwinder.cpp +++ b/src/coreclr/unwinder/baseunwinder.cpp @@ -6,15 +6,9 @@ #include "stdafx.h" #include "baseunwinder.h" -#ifndef FEATURE_CDAC_UNWINDER EXTERN_C void GetRuntimeStackWalkInfo(IN ULONG64 ControlPc, OUT UINT_PTR* pModuleBase, OUT UINT_PTR* pFuncEntry); -#endif // FEATURE_CDAC_UNWINDER - -#ifdef FEATURE_CDAC_UNWINDER -thread_local CDACCallbacks* t_pCallbacks; -#endif // FEATURE_CDAC_UNWINDER //--------------------------------------------------------------------------------------- // @@ -33,11 +27,7 @@ thread_local CDACCallbacks* t_pCallbacks; HRESULT OOPStackUnwinder::GetModuleBase( DWORD64 address, _Out_ PDWORD64 pdwBase) { -#ifndef FEATURE_CDAC_UNWINDER GetRuntimeStackWalkInfo(address, reinterpret_cast(pdwBase), NULL); -#else // FEATURE_CDAC_UNWINDER - t_pCallbacks->getStackWalkInfo(address, reinterpret_cast(pdwBase), NULL, t_pCallbacks->callbackContext); -#endif // FEATURE_CDAC_UNWINDER return ((*pdwBase == 0) ? E_FAIL : S_OK); } @@ -60,15 +50,12 @@ HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 addres _Out_writes_(cbBuffer) PVOID pBuffer, DWORD cbBuffer) { -#ifndef FEATURE_CDAC_UNWINDER if (cbBuffer < sizeof(T_RUNTIME_FUNCTION)) { return E_INVALIDARG; } -#endif // FEATURE_CDAC_UNWINDER PVOID pFuncEntry = NULL; -#ifndef FEATURE_CDAC_UNWINDER GetRuntimeStackWalkInfo(address, NULL, reinterpret_cast(&pFuncEntry)); if (pFuncEntry == NULL) { @@ -77,17 +64,4 @@ HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 addres memcpy(pBuffer, pFuncEntry, cbBuffer); return S_OK; -#else // FEATURE_CDAC_UNWINDER - t_pCallbacks->getStackWalkInfo(address, NULL, reinterpret_cast(&pFuncEntry), t_pCallbacks->callbackContext); - if (pFuncEntry == NULL) - { - return E_FAIL; - } - if (t_pCallbacks->readFromTarget((DWORD64)pFuncEntry, pBuffer, cbBuffer, t_pCallbacks->callbackContext) != S_OK) - { - return E_FAIL; - } - - return S_OK; -#endif } diff --git a/src/coreclr/unwinder/baseunwinder.h b/src/coreclr/unwinder/baseunwinder.h index f620bae944744b..d2ed5ac34ddda5 100644 --- a/src/coreclr/unwinder/baseunwinder.h +++ b/src/coreclr/unwinder/baseunwinder.h @@ -6,46 +6,12 @@ #ifndef __unwinder_h__ #define __unwinder_h__ -#ifdef FEATURE_CDAC_UNWINDER -using ReadFromTarget = LONG (*)(ULONG64 addr, PVOID pBuffer, LONG bufferSize, PVOID callbackContext); -using GetAllocatedBuffer = LONG (*)(LONG bufferSize, PVOID* ppBuffer, PVOID callbackContext); -using GetStackWalkInfo = VOID (*)(ULONG64 controlPC, UINT_PTR* pUnwindInfoBase, UINT_PTR* pFuncEntry, PVOID callbackContext); -using UnwinderFail = VOID (*)(); - -class CDACCallbacks -{ -public: - CDACCallbacks(ReadFromTarget readFromTarget, - GetAllocatedBuffer getAllocatedBuffer, - GetStackWalkInfo getStackWalkInfo, - UnwinderFail unwinderFail, - void* callbackContext) - : readFromTarget(readFromTarget), - getAllocatedBuffer(getAllocatedBuffer), - getStackWalkInfo(getStackWalkInfo), - unwinderFail(unwinderFail), - callbackContext(callbackContext) - { } - - ReadFromTarget readFromTarget; - GetAllocatedBuffer getAllocatedBuffer; - GetStackWalkInfo getStackWalkInfo; - UnwinderFail unwinderFail; - void* callbackContext; -}; - -// thread_local used to access cDAC callbacks outside of unwinder. -extern thread_local CDACCallbacks* t_pCallbacks; -#endif // FEATURE_CDAC_UNWINDER - // Report failure in the unwinder if the condition is FALSE -#if defined(FEATURE_CDAC_UNWINDER) -#define UNWINDER_ASSERT(Condition) if (!(Condition)) t_pCallbacks->unwinderFail() -#elif defined(DACCESS_COMPILE) +#ifdef DACCESS_COMPILE #define UNWINDER_ASSERT(Condition) if (!(Condition)) DacError(CORDBG_E_TARGET_INCONSISTENT) -#else // !DACCESS_COMPILE AND !FEATURE_CDAC_UNWINDER +#else // !DACCESS_COMPILE #define UNWINDER_ASSERT _ASSERTE -#endif +#endif // DACCESS_COMPILE //--------------------------------------------------------------------------------------- // diff --git a/src/coreclr/unwinder/stdafx.h b/src/coreclr/unwinder/stdafx.h index e0dc4fe44b3813..8decdc68562bd4 100644 --- a/src/coreclr/unwinder/stdafx.h +++ b/src/coreclr/unwinder/stdafx.h @@ -10,17 +10,10 @@ #define USE_COM_CONTEXT_DEF -#ifndef FEATURE_CDAC_UNWINDER #include + #include #include -#else // FEATURE_CDAC_UNWINDER -#include -#include -#include -#include -#endif // FEATURE_CDAC_UNWINDER - #ifdef DACCESS_COMPILE #include #include