diff options
author | Eugene <Eugene.Zemtsov@microsoft.com> | 2015-08-20 21:11:31 -0700 |
---|---|---|
committer | Eugene Zemtsov <Eugene.Zemtsov@microsoft.com> | 2015-09-15 13:44:42 -0700 |
commit | d0f71d0b22e9012263e4a078d24738c75e384a90 (patch) | |
tree | 0bb4840e2f42e39592bcbe18d0c0c68a4db0f376 | |
parent | eb3260e67bc653b56a80fbf0e8a07d78e3a404c1 (diff) | |
download | coreclr-d0f71d0b22e9012263e4a078d24738c75e384a90.tar.gz coreclr-d0f71d0b22e9012263e4a078d24738c75e384a90.tar.bz2 coreclr-d0f71d0b22e9012263e4a078d24738c75e384a90.zip |
Use out-of-proc libunwind to unwind native stack from DAC
Implementation of PAL_VirtualUnwindOutOfProc that uses ptrace libunwind
to be able to unwind native stack in debugee. This allows to get valid managed
stack for threads that passed HelperMethodFrames.
-rw-r--r-- | src/debug/daccess/dacfn.cpp | 19 | ||||
-rw-r--r-- | src/debug/di/shimdatatarget.cpp | 14 | ||||
-rw-r--r-- | src/debug/di/shimdatatarget.h | 12 | ||||
-rw-r--r-- | src/debug/di/shimprocess.cpp | 16 | ||||
-rw-r--r-- | src/inc/cordebug.idl | 19 | ||||
-rw-r--r-- | src/inc/daccess.h | 1 | ||||
-rw-r--r-- | src/pal/inc/pal.h | 9 | ||||
-rw-r--r-- | src/pal/inc/rt/palrt.h | 2 | ||||
-rw-r--r-- | src/pal/prebuilt/idl/cordebug_i.c | 3 | ||||
-rw-r--r-- | src/pal/prebuilt/inc/cordebug.h | 255 | ||||
-rw-r--r-- | src/pal/src/CMakeLists.txt | 9 | ||||
-rw-r--r-- | src/pal/src/exception/seh-unwind.cpp | 231 | ||||
-rw-r--r-- | src/vm/amd64/gmsamd64.cpp | 26 |
13 files changed, 517 insertions, 99 deletions
diff --git a/src/debug/daccess/dacfn.cpp b/src/debug/daccess/dacfn.cpp index 1ad5b20ab0..5bec3b4ca1 100644 --- a/src/debug/daccess/dacfn.cpp +++ b/src/debug/daccess/dacfn.cpp @@ -218,6 +218,25 @@ DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx) return S_OK; } +HRESULT +DacGetPid(DWORD *pid) +{ + if (!g_dacImpl) + { + DacError(E_UNEXPECTED); + UNREACHABLE(); + } + + ReleaseHolder<ICorDebugDataTarget4> dt; + HRESULT hr = g_dacImpl->m_pTarget->QueryInterface(IID_ICorDebugDataTarget4, (void **)&dt); + if (SUCCEEDED(hr)) + { + hr = dt->GetPid(pid); + } + + return hr; +} + // DacAllocVirtual - Allocate memory from the target process // Note: this is only available to clients supporting the legacy // ICLRDataTarget2 interface. It's currently used by SOS for notification tables. diff --git a/src/debug/di/shimdatatarget.cpp b/src/debug/di/shimdatatarget.cpp index 59f56e798e..d7bfbdc11d 100644 --- a/src/debug/di/shimdatatarget.cpp +++ b/src/debug/di/shimdatatarget.cpp @@ -36,6 +36,10 @@ HRESULT STDMETHODCALLTYPE ShimDataTarget::QueryInterface( { *pInterface = static_cast<ICorDebugMutableDataTarget *>(this); } + else if (InterfaceId == IID_ICorDebugDataTarget4) + { + *pInterface = static_cast<ICorDebugDataTarget4 *>(this); + } else { *pInterface = NULL; @@ -71,9 +75,15 @@ ULONG STDMETHODCALLTYPE ShimDataTarget::Release() // // Return Value: // The OS PID of the process this data target is representing. -DWORD ShimDataTarget::GetPid() +HRESULT STDMETHODCALLTYPE ShimDataTarget::GetPid(DWORD *pdwProcessId) { - return m_processId; + if (pdwProcessId == NULL) + { + return E_INVALIDARG; + } + + *pdwProcessId = m_processId; + return S_OK; } //--------------------------------------------------------------------------------------- diff --git a/src/debug/di/shimdatatarget.h b/src/debug/di/shimdatatarget.h index 1fabad4778..9e3502bb48 100644 --- a/src/debug/di/shimdatatarget.h +++ b/src/debug/di/shimdatatarget.h @@ -21,7 +21,7 @@ typedef HRESULT (*FPContinueStatusChanged)(void * pUserData, DWORD dwThreadId, C //--------------------------------------------------------------------------------------- // Data target for a live process. This is used by Shim. // -class ShimDataTarget : public ICorDebugMutableDataTarget +class ShimDataTarget : public ICorDebugMutableDataTarget, ICorDebugDataTarget4 { public: virtual ~ShimDataTarget() {} @@ -36,9 +36,6 @@ public: // is unavailable because it's running void SetError(HRESULT hr); - // Get the OS Process ID that this DataTarget is for. - DWORD GetPid(); - // // IUnknown. // @@ -85,6 +82,13 @@ public: // @dbgtodo - add Native Patch Table support + // + // ICorDebugDataTarget4 + // + + // Get the OS Process ID that this DataTarget is for. + virtual HRESULT STDMETHODCALLTYPE GetPid(DWORD *pdwProcessId); + protected: // Pid of the target process. DWORD m_processId; diff --git a/src/debug/di/shimprocess.cpp b/src/debug/di/shimprocess.cpp index 6e0350b8eb..e4b511abec 100644 --- a/src/debug/di/shimprocess.cpp +++ b/src/debug/di/shimprocess.cpp @@ -133,7 +133,9 @@ void ShimProcess::SetProcess(ICorDebugProcess * pProcess) if (pProcess != NULL) { // Verify that DataTarget + new process have the same pid? - _ASSERTE(m_pProcess->GetPid() == m_pLiveDataTarget->GetPid()); + DWORD pid = 0; + _ASSERTE(SUCCEEDED(m_pLiveDataTarget->GetPid(&pid))); + _ASSERTE(m_pProcess->GetPid() == pid); } } @@ -738,7 +740,11 @@ HRESULT ShimProcess::HandleWin32DebugEvent(const DEBUG_EVENT * pEvent) // This assert could be our only warning of various catastrophic failures in the left-side. if (!dwFirstChance && (pRecord->ExceptionCode == STATUS_BREAKPOINT) && !m_fIsInteropDebugging) { - DWORD pid = (m_pLiveDataTarget == NULL) ? 0 : m_pLiveDataTarget->GetPid(); + DWORD pid = 0; + if (m_pLiveDataTarget != NULL) + { + m_pLiveDataTarget->GetPid(&pid); + } CONSISTENCY_CHECK_MSGF(false, ("Unhandled breakpoint exception in debuggee (pid=%d (0x%x)) on thread %d(0x%x)\n" "This may mean there was an assert in the debuggee on that thread.\n" @@ -1742,7 +1748,11 @@ void ShimProcess::PreDispatchEvent(bool fRealCreateProcessEvent /*= false*/) CORDB_ADDRESS ShimProcess::GetCLRInstanceBaseAddress() { CORDB_ADDRESS baseAddress = CORDB_ADDRESS(NULL); - DWORD dwPid = m_pLiveDataTarget->GetPid(); + DWORD dwPid = 0; + if (FAILED(m_pLiveDataTarget->GetPid(&dwPid))) + { + return baseAddress; + } #if defined(FEATURE_CORESYSTEM) // Debugger attaching to CoreCLR via CoreCLRCreateCordbObject should have already specified CLR module address. // Code that help to find it now lives in dbgshim. diff --git a/src/inc/cordebug.idl b/src/inc/cordebug.idl index 3ba81c32af..f5f975bf26 100644 --- a/src/inc/cordebug.idl +++ b/src/inc/cordebug.idl @@ -811,6 +811,24 @@ interface ICorDebugDataTarget3 : IUnknown }; /* + * Data target that knows how to obtain debugee's process id. + * Debugee is not necessarily a living process at that time or on the same machine. + */ +[ + object, + uuid(E799DC06-E099-4713-BDD9-906D3CC02CF2), + local, + pointer_default(unique) +] +interface ICorDebugDataTarget4 : IUnknown +{ + /* + * gives back a process id + */ + HRESULT GetPid([out] DWORD *pdwProcessId); +}; + +/* * Mutable extension to the data target. This version of ICorDebugDataTarget * can be implemented by targets that wish to support modification of the target * process (such as for live invasive debugging). @@ -879,6 +897,7 @@ interface ICorDebugMutableDataTarget : ICorDebugDataTarget }; + /* * Interface used by the data access services layer to locate metadata * of assemblies in a target. diff --git a/src/inc/daccess.h b/src/inc/daccess.h index 704a1ea425..241c25ea21 100644 --- a/src/inc/daccess.h +++ b/src/inc/daccess.h @@ -663,6 +663,7 @@ HRESULT DacFreeVirtual(TADDR mem, ULONG32 size, ULONG32 typeFlags, PVOID DacInstantiateTypeByAddress(TADDR addr, ULONG32 size, bool throwEx); PVOID DacInstantiateTypeByAddressNoReport(TADDR addr, ULONG32 size, bool throwEx); PVOID DacInstantiateClassByVTable(TADDR addr, ULONG32 minSize, bool throwEx); +HRESULT DacGetPid(DWORD *pid); // Copy a null-terminated ascii or unicode string from the target to the host. // Note that most of the work here is to find the null terminator. If you know the exact length, diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 43fc0694f5..4ed5e9267e 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -3442,6 +3442,15 @@ size_t PALAPI PAL_GetLogicalProcessorCacheSizeFromOS(); +typedef BOOL (*ReadMemoryWordCallback)(SIZE_T address, SIZE_T *value); + +PALIMPORT BOOL PALAPI PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers); + +PALIMPORT BOOL PALAPI PAL_VirtualUnwindOutOfProc(CONTEXT *context, + KNONVOLATILE_CONTEXT_POINTERS *contextPointers, + DWORD pid, + ReadMemoryWordCallback readMemCallback); + #define GetLogicalProcessorCacheSizeFromOS PAL_GetLogicalProcessorCacheSizeFromOS #ifdef PLATFORM_UNIX diff --git a/src/pal/inc/rt/palrt.h b/src/pal/inc/rt/palrt.h index 7f3cdbdc14..2d67e108b3 100644 --- a/src/pal/inc/rt/palrt.h +++ b/src/pal/inc/rt/palrt.h @@ -1710,8 +1710,6 @@ typedef LONG (WINAPI *PTOP_LEVEL_EXCEPTION_FILTER)( ); typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; -BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextPointers); - /******************* ntdef ************************************/ #ifndef ANYSIZE_ARRAY diff --git a/src/pal/prebuilt/idl/cordebug_i.c b/src/pal/prebuilt/idl/cordebug_i.c index 2b8b1f5c02..8a947ccf49 100644 --- a/src/pal/prebuilt/idl/cordebug_i.c +++ b/src/pal/prebuilt/idl/cordebug_i.c @@ -98,6 +98,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugLoadedModule,0x817F343A,0x6630,0x4578,0x96,0x MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget3,0xD05E60C3,0x848C,0x4E7D,0x89,0x4E,0x62,0x33,0x20,0xFF,0x6A,0xFA); +MIDL_DEFINE_GUID(IID, IID_ICorDebugDataTarget4,0xE799DC06,0xE099,0x4713,0xBD,0xD9,0x90,0x6D,0x3C,0xC0,0x2C,0xF2); + + MIDL_DEFINE_GUID(IID, IID_ICorDebugMutableDataTarget,0xA1B8A756,0x3CB6,0x4CCB,0x97,0x9F,0x3D,0xF9,0x99,0x67,0x3A,0x59); diff --git a/src/pal/prebuilt/inc/cordebug.h b/src/pal/prebuilt/inc/cordebug.h index db8bf6d24d..153d3901ee 100644 --- a/src/pal/prebuilt/inc/cordebug.h +++ b/src/pal/prebuilt/inc/cordebug.h @@ -122,6 +122,13 @@ typedef interface ICorDebugDataTarget3 ICorDebugDataTarget3; #endif /* __ICorDebugDataTarget3_FWD_DEFINED__ */ +#ifndef __ICorDebugDataTarget4_FWD_DEFINED__ +#define __ICorDebugDataTarget4_FWD_DEFINED__ +typedef interface ICorDebugDataTarget4 ICorDebugDataTarget4; + +#endif /* __ICorDebugDataTarget4_FWD_DEFINED__ */ + + #ifndef __ICorDebugMutableDataTarget_FWD_DEFINED__ #define __ICorDebugMutableDataTarget_FWD_DEFINED__ typedef interface ICorDebugMutableDataTarget ICorDebugMutableDataTarget; @@ -2831,6 +2838,86 @@ EXTERN_C const IID IID_ICorDebugDataTarget3; #endif /* __ICorDebugDataTarget3_INTERFACE_DEFINED__ */ +#ifndef __ICorDebugDataTarget4_INTERFACE_DEFINED__ +#define __ICorDebugDataTarget4_INTERFACE_DEFINED__ + +/* interface ICorDebugDataTarget4 */ +/* [unique][local][uuid][object] */ + + +EXTERN_C const IID IID_ICorDebugDataTarget4; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("E799DC06-E099-4713-BDD9-906D3CC02CF2") + ICorDebugDataTarget4 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetPid( + /* [out] */ DWORD *pdwProcessId) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ICorDebugDataTarget4Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ICorDebugDataTarget4 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ICorDebugDataTarget4 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ICorDebugDataTarget4 * This); + + HRESULT ( STDMETHODCALLTYPE *GetPid )( + ICorDebugDataTarget4 * This, + /* [out] */ DWORD *pdwProcessId); + + END_INTERFACE + } ICorDebugDataTarget4Vtbl; + + interface ICorDebugDataTarget4 + { + CONST_VTBL struct ICorDebugDataTarget4Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ICorDebugDataTarget4_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ICorDebugDataTarget4_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ICorDebugDataTarget4_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ICorDebugDataTarget4_GetPid(This,pdwProcessId) \ + ( (This)->lpVtbl -> GetPid(This,pdwProcessId) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ICorDebugDataTarget4_INTERFACE_DEFINED__ */ + + #ifndef __ICorDebugMutableDataTarget_INTERFACE_DEFINED__ #define __ICorDebugMutableDataTarget_INTERFACE_DEFINED__ @@ -3063,15 +3150,15 @@ EXTERN_C const IID IID_ICorDebugMetaDataLocator; #endif /* __ICorDebugMetaDataLocator_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0014 */ +/* interface __MIDL_itf_cordebug_0000_0015 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0014_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0014_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_s_ifspec; #ifndef __ICorDebugManagedCallback_INTERFACE_DEFINED__ #define __ICorDebugManagedCallback_INTERFACE_DEFINED__ @@ -3525,15 +3612,15 @@ EXTERN_C const IID IID_ICorDebugManagedCallback; #endif /* __ICorDebugManagedCallback_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0015 */ +/* interface __MIDL_itf_cordebug_0000_0016 */ /* [local] */ #pragma warning(pop) #pragma warning(push) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0015_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0016_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0016_v0_0_s_ifspec; #ifndef __ICorDebugManagedCallback3_INTERFACE_DEFINED__ #define __ICorDebugManagedCallback3_INTERFACE_DEFINED__ @@ -3617,14 +3704,14 @@ EXTERN_C const IID IID_ICorDebugManagedCallback3; #endif /* __ICorDebugManagedCallback3_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0016 */ +/* interface __MIDL_itf_cordebug_0000_0017 */ /* [local] */ #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0016_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0016_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0017_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0017_v0_0_s_ifspec; #ifndef __ICorDebugManagedCallback2_INTERFACE_DEFINED__ #define __ICorDebugManagedCallback2_INTERFACE_DEFINED__ @@ -3839,14 +3926,14 @@ EXTERN_C const IID IID_ICorDebugManagedCallback2; #endif /* __ICorDebugManagedCallback2_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0017 */ +/* interface __MIDL_itf_cordebug_0000_0018 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0017_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0017_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_s_ifspec; #ifndef __ICorDebugUnmanagedCallback_INTERFACE_DEFINED__ #define __ICorDebugUnmanagedCallback_INTERFACE_DEFINED__ @@ -3930,7 +4017,7 @@ EXTERN_C const IID IID_ICorDebugUnmanagedCallback; #endif /* __ICorDebugUnmanagedCallback_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0018 */ +/* interface __MIDL_itf_cordebug_0000_0019 */ /* [local] */ typedef @@ -3950,8 +4037,8 @@ enum CorDebugHandleType #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0018_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0019_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0019_v0_0_s_ifspec; #ifndef __ICorDebug_INTERFACE_DEFINED__ #define __ICorDebug_INTERFACE_DEFINED__ @@ -4139,14 +4226,14 @@ EXTERN_C const IID IID_ICorDebug; #endif /* __ICorDebug_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0019 */ +/* interface __MIDL_itf_cordebug_0000_0020 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0019_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0019_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0020_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0020_v0_0_s_ifspec; #ifndef __ICorDebugRemoteTarget_INTERFACE_DEFINED__ #define __ICorDebugRemoteTarget_INTERFACE_DEFINED__ @@ -4358,7 +4445,7 @@ EXTERN_C const IID IID_ICorDebugRemote; #endif /* __ICorDebugRemote_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0021 */ +/* interface __MIDL_itf_cordebug_0000_0022 */ /* [local] */ typedef struct _COR_VERSION @@ -4371,8 +4458,8 @@ typedef struct _COR_VERSION -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0021_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0021_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0022_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0022_v0_0_s_ifspec; #ifndef __ICorDebug2_INTERFACE_DEFINED__ #define __ICorDebug2_INTERFACE_DEFINED__ @@ -4534,7 +4621,7 @@ EXTERN_C const IID IID_ICorDebug2; #endif /* __ICorDebug2_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0022 */ +/* interface __MIDL_itf_cordebug_0000_0023 */ /* [local] */ typedef @@ -4546,8 +4633,8 @@ enum CorDebugThreadState -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0022_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0022_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0023_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0023_v0_0_s_ifspec; #ifndef __ICorDebugController_INTERFACE_DEFINED__ #define __ICorDebugController_INTERFACE_DEFINED__ @@ -4729,15 +4816,15 @@ EXTERN_C const IID IID_ICorDebugController; #endif /* __ICorDebugController_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0023 */ +/* interface __MIDL_itf_cordebug_0000_0024 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0023_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0023_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0024_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0024_v0_0_s_ifspec; #ifndef __ICorDebugAppDomain_INTERFACE_DEFINED__ #define __ICorDebugAppDomain_INTERFACE_DEFINED__ @@ -4989,14 +5076,14 @@ EXTERN_C const IID IID_ICorDebugAppDomain; #endif /* __ICorDebugAppDomain_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0024 */ +/* interface __MIDL_itf_cordebug_0000_0025 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0024_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0024_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0025_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0025_v0_0_s_ifspec; #ifndef __ICorDebugAppDomain2_INTERFACE_DEFINED__ #define __ICorDebugAppDomain2_INTERFACE_DEFINED__ @@ -5494,15 +5581,15 @@ EXTERN_C const IID IID_ICorDebugAppDomain4; #endif /* __ICorDebugAppDomain4_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0028 */ +/* interface __MIDL_itf_cordebug_0000_0029 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0028_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0028_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0029_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0029_v0_0_s_ifspec; #ifndef __ICorDebugAssembly_INTERFACE_DEFINED__ #define __ICorDebugAssembly_INTERFACE_DEFINED__ @@ -5632,14 +5719,14 @@ EXTERN_C const IID IID_ICorDebugAssembly; #endif /* __ICorDebugAssembly_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0029 */ +/* interface __MIDL_itf_cordebug_0000_0030 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0029_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0029_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0030_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0030_v0_0_s_ifspec; #ifndef __ICorDebugAssembly2_INTERFACE_DEFINED__ #define __ICorDebugAssembly2_INTERFACE_DEFINED__ @@ -5811,7 +5898,7 @@ EXTERN_C const IID IID_ICorDebugAssembly3; #endif /* __ICorDebugAssembly3_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0031 */ +/* interface __MIDL_itf_cordebug_0000_0032 */ /* [local] */ #ifndef _DEF_COR_TYPEID_ @@ -5832,8 +5919,8 @@ typedef struct _COR_HEAPOBJECT -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0031_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0031_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0032_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0032_v0_0_s_ifspec; #ifndef __ICorDebugHeapEnum_INTERFACE_DEFINED__ #define __ICorDebugHeapEnum_INTERFACE_DEFINED__ @@ -5947,7 +6034,7 @@ EXTERN_C const IID IID_ICorDebugHeapEnum; #endif /* __ICorDebugHeapEnum_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0032 */ +/* interface __MIDL_itf_cordebug_0000_0033 */ /* [local] */ typedef @@ -5985,8 +6072,8 @@ typedef struct _COR_HEAPINFO -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0032_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0032_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0033_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0033_v0_0_s_ifspec; #ifndef __ICorDebugHeapSegmentEnum_INTERFACE_DEFINED__ #define __ICorDebugHeapSegmentEnum_INTERFACE_DEFINED__ @@ -6100,7 +6187,7 @@ EXTERN_C const IID IID_ICorDebugHeapSegmentEnum; #endif /* __ICorDebugHeapSegmentEnum_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0033 */ +/* interface __MIDL_itf_cordebug_0000_0034 */ /* [local] */ typedef @@ -6136,8 +6223,8 @@ typedef struct COR_GC_REFERENCE #endif // _DEF_COR_GC_REFERENCE_ -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0033_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0033_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0034_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0034_v0_0_s_ifspec; #ifndef __ICorDebugGCReferenceEnum_INTERFACE_DEFINED__ #define __ICorDebugGCReferenceEnum_INTERFACE_DEFINED__ @@ -6251,7 +6338,7 @@ EXTERN_C const IID IID_ICorDebugGCReferenceEnum; #endif /* __ICorDebugGCReferenceEnum_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0034 */ +/* interface __MIDL_itf_cordebug_0000_0035 */ /* [local] */ #ifndef _DEF_COR_ARRAY_LAYOUT_ @@ -6296,8 +6383,8 @@ typedef struct COR_FIELD #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0034_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0034_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0035_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0035_v0_0_s_ifspec; #ifndef __ICorDebugProcess_INTERFACE_DEFINED__ #define __ICorDebugProcess_INTERFACE_DEFINED__ @@ -6647,14 +6734,14 @@ EXTERN_C const IID IID_ICorDebugProcess; #endif /* __ICorDebugProcess_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0035 */ +/* interface __MIDL_itf_cordebug_0000_0036 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0035_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0035_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0036_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0036_v0_0_s_ifspec; #ifndef __ICorDebugProcess2_INTERFACE_DEFINED__ #define __ICorDebugProcess2_INTERFACE_DEFINED__ @@ -7098,7 +7185,7 @@ EXTERN_C const IID IID_ICorDebugProcess5; #endif /* __ICorDebugProcess5_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0038 */ +/* interface __MIDL_itf_cordebug_0000_0039 */ /* [local] */ typedef @@ -7134,8 +7221,8 @@ enum CorDebugStateChange -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0038_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0038_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0039_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0039_v0_0_s_ifspec; #ifndef __ICorDebugDebugEvent_INTERFACE_DEFINED__ #define __ICorDebugDebugEvent_INTERFACE_DEFINED__ @@ -7227,7 +7314,7 @@ EXTERN_C const IID IID_ICorDebugDebugEvent; #endif /* __ICorDebugDebugEvent_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0039 */ +/* interface __MIDL_itf_cordebug_0000_0040 */ /* [local] */ typedef @@ -7249,8 +7336,8 @@ enum CorDebugCodeInvokePurpose -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0039_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0039_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0040_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0040_v0_0_s_ifspec; #ifndef __ICorDebugProcess6_INTERFACE_DEFINED__ #define __ICorDebugProcess6_INTERFACE_DEFINED__ @@ -7398,7 +7485,7 @@ EXTERN_C const IID IID_ICorDebugProcess6; #endif /* __ICorDebugProcess6_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0040 */ +/* interface __MIDL_itf_cordebug_0000_0041 */ /* [local] */ typedef @@ -7410,8 +7497,8 @@ enum WriteableMetadataUpdateMode -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0040_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0040_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0041_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0041_v0_0_s_ifspec; #ifndef __ICorDebugProcess7_INTERFACE_DEFINED__ #define __ICorDebugProcess7_INTERFACE_DEFINED__ @@ -10493,7 +10580,7 @@ EXTERN_C const IID IID_ICorDebugILFrame3; #endif /* __ICorDebugILFrame3_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0064 */ +/* interface __MIDL_itf_cordebug_0000_0065 */ /* [local] */ typedef @@ -10505,8 +10592,8 @@ enum ILCodeKind -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0064_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0064_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0065_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0065_v0_0_s_ifspec; #ifndef __ICorDebugILFrame4_INTERFACE_DEFINED__ #define __ICorDebugILFrame4_INTERFACE_DEFINED__ @@ -10870,15 +10957,15 @@ EXTERN_C const IID IID_ICorDebugNativeFrame; #endif /* __ICorDebugNativeFrame_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0066 */ +/* interface __MIDL_itf_cordebug_0000_0067 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0066_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0066_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0067_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0067_v0_0_s_ifspec; #ifndef __ICorDebugNativeFrame2_INTERFACE_DEFINED__ #define __ICorDebugNativeFrame2_INTERFACE_DEFINED__ @@ -11448,14 +11535,14 @@ EXTERN_C const IID IID_ICorDebugModule; #endif /* __ICorDebugModule_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0070 */ +/* interface __MIDL_itf_cordebug_0000_0071 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0070_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0070_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0071_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0071_v0_0_s_ifspec; #ifndef __ICorDebugModule2_INTERFACE_DEFINED__ #define __ICorDebugModule2_INTERFACE_DEFINED__ @@ -14252,15 +14339,15 @@ EXTERN_C const IID IID_ICorDebugBoxValue; #endif /* __ICorDebugBoxValue_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0094 */ +/* interface __MIDL_itf_cordebug_0000_0095 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0094_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0094_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_s_ifspec; #ifndef __ICorDebugStringValue_INTERFACE_DEFINED__ #define __ICorDebugStringValue_INTERFACE_DEFINED__ @@ -14400,14 +14487,14 @@ EXTERN_C const IID IID_ICorDebugStringValue; #endif /* __ICorDebugStringValue_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0095 */ +/* interface __MIDL_itf_cordebug_0000_0096 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0095_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0096_v0_0_s_ifspec; #ifndef __ICorDebugArrayValue_INTERFACE_DEFINED__ #define __ICorDebugArrayValue_INTERFACE_DEFINED__ @@ -16840,15 +16927,15 @@ EXTERN_C const IID IID_ICorDebugBlockingObjectEnum; #endif /* __ICorDebugBlockingObjectEnum_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0116 */ +/* interface __MIDL_itf_cordebug_0000_0117 */ /* [local] */ #pragma warning(push) #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0116_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0116_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_s_ifspec; #ifndef __ICorDebugMDA_INTERFACE_DEFINED__ #define __ICorDebugMDA_INTERFACE_DEFINED__ @@ -16988,7 +17075,7 @@ EXTERN_C const IID IID_ICorDebugMDA; #endif /* __ICorDebugMDA_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0117 */ +/* interface __MIDL_itf_cordebug_0000_0118 */ /* [local] */ #pragma warning(pop) @@ -16996,8 +17083,8 @@ EXTERN_C const IID IID_ICorDebugMDA; #pragma warning(disable:28718) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0117_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_s_ifspec; #ifndef __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ #define __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ @@ -17113,14 +17200,14 @@ EXTERN_C const IID IID_ICorDebugEditAndContinueErrorInfo; #endif /* __ICorDebugEditAndContinueErrorInfo_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_cordebug_0000_0118 */ +/* interface __MIDL_itf_cordebug_0000_0119 */ /* [local] */ #pragma warning(pop) -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0118_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_cordebug_0000_0119_v0_0_s_ifspec; #ifndef __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__ #define __ICorDebugEditAndContinueSnapshot_INTERFACE_DEFINED__ diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt index ce364b3c64..c814e10aac 100644 --- a/src/pal/src/CMakeLists.txt +++ b/src/pal/src/CMakeLists.txt @@ -207,6 +207,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux) if(PAL_CMAKE_PLATFORM_ARCH_ARM) target_link_libraries(coreclrpal gcc_s + unwind-arm + ) + endif() + + if(PAL_CMAKE_PLATFORM_ARCH_AMD64) + target_link_libraries(coreclrpal + unwind-x86_64 ) endif() @@ -215,6 +222,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux) rt dl unwind + unwind-ptrace + unwind-generic ) endif(CMAKE_SYSTEM_NAME STREQUAL Linux) diff --git a/src/pal/src/exception/seh-unwind.cpp b/src/pal/src/exception/seh-unwind.cpp index 465c459dda..cf899f7f7f 100644 --- a/src/pal/src/exception/seh-unwind.cpp +++ b/src/pal/src/exception/seh-unwind.cpp @@ -26,12 +26,20 @@ Abstract: #endif // !FEATURE_PAL_SXS #include "pal/context.h" +#include "pal.h" #include <dlfcn.h> #include <exception> + #if HAVE_LIBUNWIND_H +#ifndef __LINUX__ #define UNW_LOCAL_ONLY +#endif // !__LINUX__ #include <libunwind.h> -#endif +#ifdef __LINUX__ +#include <libunwind-ptrace.h> +#endif // __LINUX__ +#endif // HAVE_LIBUNWIND_H + //---------------------------------------------------------------------- // Virtual Unwinding @@ -226,6 +234,7 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP int st; unw_context_t unwContext; unw_cursor_t cursor; + #if defined(__APPLE__) || defined(__FreeBSD__) || defined(_ARM64_) DWORD64 curPc; #endif @@ -251,7 +260,6 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP return FALSE; } #endif - st = unw_init_local(&cursor, &unwContext); if (st < 0) { @@ -308,13 +316,230 @@ BOOL PAL_VirtualUnwind(CONTEXT *context, KNONVOLATILE_CONTEXT_POINTERS *contextP { GetContextPointers(&cursor, &unwContext, contextPointers); } - return TRUE; } + #else #error don't know how to unwind on this platform #endif + +#ifdef __LINUX__ + + +static struct LibunwindCallbacksInfoType +{ + CONTEXT *Context; + ReadMemoryWordCallback readMemCallback; +} LibunwindCallbacksInfo; + +static int get_dyn_info_list_addr(unw_addr_space_t as, unw_word_t *dilap, void *arg) +{ + return -UNW_ENOINFO; +} + +static int access_mem(unw_addr_space_t as, unw_word_t addr, unw_word_t *valp, int write, void *arg) +{ + if (write) + { + ASSERT("Memory write must never be called by libunwind during stackwalk"); + return -UNW_EINVAL; + } + + // access_mem sometimes gets called by _UPT_find_proc_info, in such cases arg has a pointer to libunwind internal data + // returned by _UPT_create. It makes it impossible to use arg for passing readMemCallback. That's why we have to use global variable. + if (LibunwindCallbacksInfo.readMemCallback((SIZE_T)addr, (SIZE_T *)valp)) + { + return UNW_ESUCCESS; + } + else + { + return -UNW_EUNSPEC; + } +} + +static int access_reg(unw_addr_space_t as, unw_regnum_t regnum, unw_word_t *valp, int write, void *arg) +{ + if (write) + { + ASSERT("Register write must never be called by libunwind during stackwalk"); + return -UNW_EREADONLYREG; + } + + CONTEXT *winContext = LibunwindCallbacksInfo.Context; + + switch (regnum) + { +#if defined(_AMD64_) + case UNW_REG_IP: *valp = (unw_word_t) winContext->Rip; break; + case UNW_REG_SP: *valp = (unw_word_t) winContext->Rsp; break; + case UNW_X86_64_RBP: *valp = (unw_word_t) winContext->Rbp; break; + case UNW_X86_64_RBX: *valp = (unw_word_t) winContext->Rbx; break; + case UNW_X86_64_R12: *valp = (unw_word_t) winContext->R12; break; + case UNW_X86_64_R13: *valp = (unw_word_t) winContext->R13; break; + case UNW_X86_64_R14: *valp = (unw_word_t) winContext->R14; break; + case UNW_X86_64_R15: *valp = (unw_word_t) winContext->R15; break; +#elif defined(_ARM_) + case UNW_ARM_R13: *valp = (unw_word_t) winContext->Sp; break; + case UNW_ARM_R14: *valp = (unw_word_t) winContext->Lr; break; + case UNW_ARM_R15: *valp = (unw_word_t) winContext->Pc; break; + case UNW_ARM_R4: *valp = (unw_word_t) winContext->R4; break; + case UNW_ARM_R5: *valp = (unw_word_t) winContext->R5; break; + case UNW_ARM_R6: *valp = (unw_word_t) winContext->R6; break; + case UNW_ARM_R7: *valp = (unw_word_t) winContext->R7; break; + case UNW_ARM_R8: *valp = (unw_word_t) winContext->R8; break; + case UNW_ARM_R9: *valp = (unw_word_t) winContext->R9; break; + case UNW_ARM_R10: *valp = (unw_word_t) winContext->R10; break; + case UNW_ARM_R11: *valp = (unw_word_t) winContext->R11; break; +#elif defined(_ARM64_) + case UNW_REG_IP: *valp = (unw_word_t) winContext->Pc; break; + case UNW_REG_SP: *valp = (unw_word_t) winContext->Sp; break; + case UNW_AARCH64_X29: *valp = (unw_word_t) winContext->Fp; break; + case UNW_AARCH64_X30: *valp = (unw_word_t) winContext->Lr; break; + case UNW_AARCH64_X19: *valp = (unw_word_t) winContext->X19; break; + case UNW_AARCH64_X20: *valp = (unw_word_t) winContext->X20; break; + case UNW_AARCH64_X21: *valp = (unw_word_t) winContext->X21; break; + case UNW_AARCH64_X22: *valp = (unw_word_t) winContext->X22; break; + case UNW_AARCH64_X23: *valp = (unw_word_t) winContext->X23; break; + case UNW_AARCH64_X24: *valp = (unw_word_t) winContext->X24; break; + case UNW_AARCH64_X25: *valp = (unw_word_t) winContext->X25; break; + case UNW_AARCH64_X26: *valp = (unw_word_t) winContext->X26; break; + case UNW_AARCH64_X27: *valp = (unw_word_t) winContext->X27; break; + case UNW_AARCH64_X28: *valp = (unw_word_t) winContext->X28; break; +#else +#error unsupported architecture +#endif + default: + ASSERT("Attempt to read an unknown register."); + return -UNW_EBADREG; + } + return UNW_ESUCCESS; +} + +static int access_fpreg(unw_addr_space_t as, unw_regnum_t regnum, unw_fpreg_t *fpvalp, int write, void *arg) +{ + ASSERT("Not supposed to be ever called"); + return -UNW_EINVAL; +} + +static int resume(unw_addr_space_t as, unw_cursor_t *cp, void *arg) +{ + ASSERT("Not supposed to be ever called"); + return -UNW_EINVAL; +} + +static int get_proc_name(unw_addr_space_t as, unw_word_t addr, char *bufp, size_t buf_len, unw_word_t *offp, void *arg) +{ + ASSERT("Not supposed to be ever called"); + return -UNW_EINVAL; +} + +static unw_accessors_t unwind_accessors = +{ + .find_proc_info = _UPT_find_proc_info, + .put_unwind_info = _UPT_put_unwind_info, + .get_dyn_info_list_addr = get_dyn_info_list_addr, + .access_mem = access_mem, + .access_reg = access_reg, + .access_fpreg = access_fpreg, + .resume = resume, + .get_proc_name = get_proc_name +}; + +BOOL PAL_VirtualUnwindOutOfProc(CONTEXT *context, + KNONVOLATILE_CONTEXT_POINTERS *contextPointers, + DWORD pid, + ReadMemoryWordCallback readMemCallback) +{ + // This function can be executed only by one thread at a time. + // The reason for this is that we need to pass context and read mem function to libunwind callbacks + // but "arg" is already used by the pointer returned from _UPT_create(). + // So we resort to using global variables and a lock. + struct Lock + { + CRITICAL_SECTION cs; + Lock() + { + // ctor of a static variable is a thread-safe way to initialize critical section exactly once (clang,gcc) + InitializeCriticalSection(&cs); + } + }; + struct LockHolder + { + CRITICAL_SECTION *cs; + LockHolder(CRITICAL_SECTION *cs) + { + this->cs = cs; + EnterCriticalSection(cs); + } + + ~LockHolder() + { + LeaveCriticalSection(cs); + cs = NULL; + } + }; + static Lock lock; + LockHolder lockHolder(&lock.cs); + + int st; + unw_context_t unwContext; + unw_cursor_t cursor; + unw_addr_space_t addrSpace = 0; + void *libunwindUptPtr = NULL; + BOOL result = FALSE; + + LibunwindCallbacksInfo.Context = context; + LibunwindCallbacksInfo.readMemCallback = readMemCallback; + WinContextToUnwindContext(context, &unwContext); + addrSpace = unw_create_addr_space(&unwind_accessors, 0); + libunwindUptPtr = _UPT_create(pid); + st = unw_init_remote(&cursor, addrSpace, libunwindUptPtr); + if (st < 0) + { + result = FALSE; + goto Exit; + } + + st = unw_step(&cursor); + if (st < 0) + { + result = FALSE; + goto Exit; + } + + UnwindContextToWinContext(&cursor, context); + + if (contextPointers != NULL) + { + GetContextPointers(&cursor, &unwContext, contextPointers); + } + result = TRUE; + +Exit: + if (libunwindUptPtr != nullptr) + { + _UPT_destroy(libunwindUptPtr); + } + if (addrSpace != 0) + { + unw_destroy_addr_space(addrSpace); + } + return result; +} +#else // __LINUX__ + +BOOL PAL_VirtualUnwindOutOfProc(CONTEXT *context, + KNONVOLATILE_CONTEXT_POINTERS *contextPointers, + DWORD pid, + ReadMemoryWordCallback readMemCallback) +{ + //UNIXTODO: Implement for Mac flavor of libunwind + return FALSE; +} + +#endif // !__LINUX__ + /*++ Function: RtlpRaiseException diff --git a/src/vm/amd64/gmsamd64.cpp b/src/vm/amd64/gmsamd64.cpp index 197e8fde24..49f45c96e5 100644 --- a/src/vm/amd64/gmsamd64.cpp +++ b/src/vm/amd64/gmsamd64.cpp @@ -10,7 +10,13 @@ #include "common.h" #include "gmscpu.h" - +#if defined(DACCESS_COMPILE) +static BOOL DacReadAllAdapter(SIZE_T address, SIZE_T *value) +{ + HRESULT hr = DacReadAll((TADDR)address, (PVOID)value, sizeof(*value), false); + return SUCCEEDED(hr); +} +#endif //DACCESS_COMPILE void LazyMachState::unwindLazyState(LazyMachState* baseState, MachState* unwoundState, @@ -56,7 +62,25 @@ void LazyMachState::unwindLazyState(LazyMachState* baseState, #ifndef FEATURE_PAL pvControlPc = Thread::VirtualUnwindCallFrame(&ctx, &nonVolRegPtrs); #else // !FEATURE_PAL + +#if defined(DACCESS_COMPILE) + DWORD pid; + HRESULT hr = DacGetPid(&pid); + if (SUCCEEDED(hr)) + { + if (!PAL_VirtualUnwindOutOfProc(&ctx, &nonVolRegPtrs, pid, DacReadAllAdapter)) + { + DacError(E_FAIL); + } + } + else + { + DacError(hr); + } +#else PAL_VirtualUnwind(&ctx, &nonVolRegPtrs); +#endif // DACCESS_COMPILE + pvControlPc = GetIP(&ctx); #endif // !FEATURE_PAL |