summaryrefslogtreecommitdiff
path: root/src/vm/stackwalk.cpp
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2015-02-16 15:43:50 +0100
committerJan Vorlicek <janvorli@microsoft.com>2015-02-16 15:43:50 +0100
commitfb11bcafc8bae0924b51ed4483ed35d884852dc4 (patch)
treed3433a943bcf8e277cd2618be3e411e17a1db617 /src/vm/stackwalk.cpp
parent0e20a9e34ad2b861460c2772865653082ca06dfd (diff)
downloadcoreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.tar.gz
coreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.tar.bz2
coreclr-fb11bcafc8bae0924b51ed4483ed35d884852dc4.zip
Implement native stack unwinding for Linux
This change implements native stack unwinding using the libunwind on Linux. I have also fixed bunch of issues / details in the related code: 1) 0x in front of %p inside format string 2) Subtraction of -1 from dl_info.dli_sname 3) Added .cfi_xxxx annotation to the CallDescrWorkerInternal and the LEAF_ENTRY / LEAF_END macros. 4) Changed local labels in the CallDescrWorkerInternal to be prefixed by .L to see the CallDescrWorkerInternal in the stack trace 5) Changed moveOWord to use movdqu - it was being called with one of the parameters unaligned
Diffstat (limited to 'src/vm/stackwalk.cpp')
-rw-r--r--src/vm/stackwalk.cpp45
1 files changed, 21 insertions, 24 deletions
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index eb12aea750..fe3b99a98f 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -576,6 +576,7 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo /
return pRD->ControlPC;
}
+
// static
PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers /*= NULL*/,
@@ -593,8 +594,6 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
CONTRACTL_END;
PCODE uControlPc = GetIP(pContext);
-
-#ifndef FEATURE_PAL
#if !defined(DACCESS_COMPILE)
UINT_PTR uImageBase;
@@ -602,9 +601,16 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
if (pCodeInfo == NULL)
{
+#ifndef FEATURE_PAL
pFunctionEntry = RtlLookupFunctionEntry(uControlPc,
ARM_ONLY((DWORD*))(&uImageBase),
NULL);
+#else // !FEATURE_PAL
+ // For PAL, this method should never be called without valid pCodeInfo, since there is no
+ // other way to get the function entry.
+ pFunctionEntry = NULL;
+ UNREACHABLE_MSG("VirtualUnwindCallFrame called with NULL pCodeInfo");
+#endif // !FEATURE_PAL
}
else
{
@@ -615,7 +621,7 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
// expects this indirection to be resolved, so we use RUNTIME_FUNCTION of the hot code even
// if we are in cold code.
-#if defined(_DEBUG)
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
UINT_PTR uImageBaseFromOS;
PRUNTIME_FUNCTION pFunctionEntryFromOS;
@@ -623,7 +629,7 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
ARM_ONLY((DWORD*))(&uImageBaseFromOS),
NULL);
_ASSERTE( (uImageBase == uImageBaseFromOS) && (pFunctionEntry == pFunctionEntryFromOS) );
-#endif // _DEBUG
+#endif // _DEBUG && !FEATURE_PAL
}
if (pFunctionEntry)
@@ -647,8 +653,6 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
}
#endif // !DACCESS_COMPILE
-#endif // !FEATURE_PAL
-
return uControlPc;
}
@@ -670,10 +674,9 @@ UINT_PTR Thread::VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext)
// static
PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
{
-#ifndef FEATURE_PAL
-
PCODE uControlPc;
-#ifdef _DEBUG
+
+#if defined(_DEBUG) && !defined(FEATURE_PAL)
UINT_PTR uImageBase;
PRUNTIME_FUNCTION pFunctionEntry = RtlLookupFunctionEntry((UINT_PTR)GetIP(pContext),
@@ -681,12 +684,11 @@ PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
NULL);
CONSISTENCY_CHECK(NULL == pFunctionEntry);
-#endif // _DEBUG
+#endif // _DEBUG && !FEATURE_PAL
#if defined(_TARGET_AMD64_)
uControlPc = *(ULONGLONG*)pContext->Rsp;
- pContext->Rip = uControlPc;
pContext->Rsp += sizeof(ULONGLONG);
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
@@ -700,10 +702,8 @@ PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
SetIP(pContext, uControlPc);
+
return uControlPc;
-#else // !FEATURE_PAL
- PORTABILITY_ASSERT("UNIXTODO: Implement for PAL");
-#endif
}
// static
@@ -721,8 +721,6 @@ PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CO
}
CONTRACTL_END;
-#ifndef FEATURE_PAL
-
PCODE uControlPc = GetIP(pContext);
#if defined(_WIN64)
UINT64 EstablisherFrame;
@@ -736,9 +734,11 @@ PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CO
if (NULL == pFunctionEntry)
{
+#ifndef FEATURE_PAL
pFunctionEntry = RtlLookupFunctionEntry(uControlPc,
ARM_ONLY((DWORD*))(&uImageBase),
NULL);
+#endif
if (NULL == pFunctionEntry)
{
return NULL;
@@ -756,9 +756,6 @@ PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CO
uControlPc = GetIP(pContext);
return uControlPc;
-#else // !FEATURE_PAL
- PORTABILITY_ASSERT("UNIXTODO: Implement for PAL");
-#endif
}
// static
@@ -772,21 +769,21 @@ UINT_PTR Thread::VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext)
}
CONTRACTL_END;
-#ifndef FEATURE_PAL
-
PCODE uControlPc = GetIP(pContext);
// unwind out of this function and out of our caller to
// get our caller's PSP, or our caller's caller's SP.
while (!ExecutionManager::IsManagedCode(uControlPc))
{
+#ifndef FEATURE_PAL
uControlPc = VirtualUnwindCallFrame(pContext);
+#else // !FEATURE_PAL
+ VirtualUnwind(pContext, NULL);
+ uControlPc = GetIP(pContext);
+#endif // !FEATURE_PAL
}
return uControlPc;
-#else // !FEATURE_PAL
- PORTABILITY_ASSERT("TODO: Implement for PAL");
-#endif
}
#endif // DACCESS_COMPILE