summaryrefslogtreecommitdiff
path: root/src/debug/ee
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/ee')
-rw-r--r--src/debug/ee/controller.cpp6
-rw-r--r--src/debug/ee/controller.h14
-rw-r--r--src/debug/ee/debugger.cpp13
-rw-r--r--src/debug/ee/debugger.h4
-rw-r--r--src/debug/ee/functioninfo.cpp43
-rw-r--r--src/debug/ee/i386/dbghelpers.S70
-rw-r--r--src/debug/ee/wks/CMakeLists.txt4
7 files changed, 115 insertions, 39 deletions
diff --git a/src/debug/ee/controller.cpp b/src/debug/ee/controller.cpp
index 7f4d44568d..3a87fdf166 100644
--- a/src/debug/ee/controller.cpp
+++ b/src/debug/ee/controller.cpp
@@ -2824,6 +2824,8 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
CrstHolderWithState lockController(&g_criticalSection);
+ TADDR originalAddress = 0;
+
#ifdef EnC_SUPPORTED
DebuggerControllerPatch *dcpEnCOriginal = NULL;
@@ -2878,7 +2880,7 @@ DPOSS_ACTION DebuggerController::DispatchPatchOrSingleStep(Thread *thread, CONTE
// If we setip, then that will change the address in the context.
// Remeber the old address so that we can compare it to the context's ip and see if it changed.
// If it did change, then don't dispatch our current event.
- TADDR originalAddress = (TADDR) address;
+ originalAddress = (TADDR) address;
#ifdef _DEBUG
// If we do a SetIP after this point, the value of address will be garbage. Set it to a distictive pattern now, so
@@ -4486,7 +4488,7 @@ void DebuggerPatchSkip::DebuggerDetachClean()
// THIS FIX IS INCOMPLETE!It attempts to update the IP in the cases we can easily detect.However,
// if a thread is in pre - emptive mode, and its filter context has been propagated to a VEH
// context, then the filter context we get will be NULL and this fix will not work.Our belief is
- // that this scenario is rare enough that it doesn’t justify the cost and risk associated with a
+ // that this scenario is rare enough that it doesnt justify the cost and risk associated with a
// complete fix, in which we would have to either :
// 1. Change the reference counting for DebuggerController and then change the exception handling
// logic in the debuggee so that we can handle the debugger event after detach.
diff --git a/src/debug/ee/controller.h b/src/debug/ee/controller.h
index 6611e044e5..a314874b8d 100644
--- a/src/debug/ee/controller.h
+++ b/src/debug/ee/controller.h
@@ -227,23 +227,23 @@ public:
LONG AddRef()
{
- InterlockedIncrement(&m_refCount);
- _ASSERTE(m_refCount > 0);
- return m_refCount;
+ LONG newRefCount = InterlockedIncrement(&m_refCount);
+ _ASSERTE(newRefCount > 0);
+ return newRefCount;
}
LONG Release()
{
- LONG result = InterlockedDecrement(&m_refCount);
- _ASSERTE(m_refCount >= 0);
+ LONG newRefCount = InterlockedDecrement(&m_refCount);
+ _ASSERTE(newRefCount >= 0);
- if (m_refCount == 0)
+ if (newRefCount == 0)
{
TRACE_FREE(this);
DeleteInteropSafeExecutable(this);
}
- return result;
+ return newRefCount;
}
// "PatchBypass" must be the first field of this class for alignment to be correct.
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index a06811c817..2aed8bd820 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -75,6 +75,9 @@ SVAL_IMPL_INIT(BOOL, Debugger, s_fCanChangeNgenFlags, TRUE);
bool g_EnableSIS = false;
+// The following instances are used for invoking overloaded new/delete
+InteropSafe interopsafe;
+InteropSafeExecutable interopsafeEXEC;
#ifndef DACCESS_COMPILE
@@ -594,8 +597,8 @@ void DoAssertOnType(DebuggerIPCEventType event, int count)
if (g_iDbgRuntimeCounter[event & 0x00ff] == count)
{
char tmpStr[256];
- sprintf(tmpStr, "%s == %d, break now!",
- IPCENames::GetName(event), count);
+ _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
+ IPCENames::GetName(event), count);
// fire the assertion
DbgAssertDialog(__FILE__, __LINE__, tmpStr);
@@ -608,8 +611,8 @@ void DoAssertOnType(DebuggerIPCEventType event, int count)
if (g_iDbgDebuggerCounter[event & 0x00ff] == count)
{
char tmpStr[256];
- sprintf(tmpStr, "%s == %d, break now!",
- IPCENames::GetName(event), count);
+ _snprintf_s(tmpStr, _countof(tmpStr), _TRUNCATE, "%s == %d, break now!",
+ IPCENames::GetName(event), count);
// fire the assertion
DbgAssertDialog(__FILE__, __LINE__, tmpStr);
@@ -11907,7 +11910,7 @@ HRESULT Debugger::GetAndSendInterceptCommand(DebuggerIPCEvent *event)
//
// Save off this breakpoint, so that if the exception gets unwound before we hit
- // the breakpoint - the exeception info can call back to remove it.
+ // the breakpoint - the exception info can call back to remove it.
//
pExState->GetDebuggerState()->SetDebuggerInterceptContext((void *)pBreakpoint);
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index 6368647946..9cdf546290 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -3512,10 +3512,10 @@ public:
* ------------------------------------------------------------------------ */
class InteropSafe {};
-#define interopsafe (*(InteropSafe*)NULL)
+extern InteropSafe interopsafe;
class InteropSafeExecutable {};
-#define interopsafeEXEC (*(InteropSafeExecutable*)NULL)
+extern InteropSafeExecutable interopsafeEXEC;
#ifndef DACCESS_COMPILE
inline void * __cdecl operator new(size_t n, const InteropSafe&)
diff --git a/src/debug/ee/functioninfo.cpp b/src/debug/ee/functioninfo.cpp
index 83c185cfc9..aa75b30407 100644
--- a/src/debug/ee/functioninfo.cpp
+++ b/src/debug/ee/functioninfo.cpp
@@ -890,7 +890,6 @@ DebuggerJitInfo::~DebuggerJitInfo()
LOG((LF_CORDB,LL_EVERYTHING, "DJI::~DJI : deleted at 0x%p\n", this));
}
-
// Lazy initialize the Debugger-Jit-Info
void DebuggerJitInfo::LazyInitBounds()
{
@@ -903,24 +902,22 @@ void DebuggerJitInfo::LazyInitBounds()
PRECONDITION(!g_pDebugger->HasDebuggerDataLock());
} CONTRACTL_END;
- //@todo: this method is not synchronized. Mei-chin's recent work should cover this one
+ LOG((LF_CORDB, LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x m_fAttemptInit %s\n", this, m_fAttemptInit == true ? "true": "false"));
+
// Only attempt lazy-init once
- // new LOG message
- LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x m_fAttemptInit %s\n", this, m_fAttemptInit == true? "true": "false"));
if (m_fAttemptInit)
{
return;
}
- m_fAttemptInit = true;
EX_TRY
{
- LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x Initing\n", this));
+ LOG((LF_CORDB, LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x Initing\n", this));
+
// Should have already been jitted
_ASSERTE(this->m_jitComplete);
MethodDesc * mdesc = this->m_fd;
-
DebugInfoRequest request;
_ASSERTE(this->m_addrOfCode != NULL); // must have address to disambguate the Enc cases.
@@ -928,7 +925,6 @@ void DebuggerJitInfo::LazyInitBounds()
// Note the MethodDesc may not yet have the jitted info, so we'll also use the starting address we got in the jit complete callback.
request.InitFromStartingAddr(mdesc, (PCODE)this->m_addrOfCode);
-
// Bounds info.
ULONG32 cMap = 0;
ICorDebugInfo::OffsetMapping *pMap = NULL;
@@ -940,12 +936,26 @@ void DebuggerJitInfo::LazyInitBounds()
InteropSafeNew, NULL, // allocator
&cMap, &pMap,
&cVars, &pVars);
+
LOG((LF_CORDB,LL_EVERYTHING, "DJI::LazyInitBounds: this=0x%x GetBoundariesAndVars success=0x%x\n", this, fSuccess));
- if (fSuccess)
+
+ Debugger::DebuggerDataLockHolder debuggerDataLockHolder(g_pDebugger);
+
+ if (!m_fAttemptInit)
{
- this->SetBoundaries(cMap, pMap);
- this->SetVars(cVars, pVars);
+ if (fSuccess)
+ {
+ this->SetBoundaries(cMap, pMap);
+ this->SetVars(cVars, pVars);
+ }
+ m_fAttemptInit = true;
}
+ else
+ {
+ DeleteInteropSafe(pMap);
+ DeleteInteropSafe(pVars);
+ }
+ // DebuggerDataLockHolder out of scope - release implied
}
EX_CATCH
{
@@ -963,10 +973,7 @@ void DebuggerJitInfo::SetVars(ULONG32 cVars, ICorDebugInfo::NativeVarInfo *pVars
{
LIMITED_METHOD_CONTRACT;
- if (m_varNativeInfo)
- {
- return;
- }
+ _ASSERTE(m_varNativeInfo == NULL);
m_varNativeInfo = pVars;
m_varNativeInfoCount = cVars;
@@ -1020,15 +1027,11 @@ void DebuggerJitInfo::SetBoundaries(ULONG32 cMap, ICorDebugInfo::OffsetMapping *
LOG((LF_CORDB,LL_EVERYTHING, "DJI::SetBoundaries: this=0x%x cMap=0x%x pMap=0x%x\n", this, cMap, pMap));
_ASSERTE((cMap == 0) == (pMap == NULL));
+ _ASSERTE(m_sequenceMap == NULL);
if (cMap == 0)
return;
- if (m_sequenceMap)
- {
- return;
- }
-
ULONG ilLast = 0;
#ifdef _DEBUG
// We assume that the map is sorted by native offset
diff --git a/src/debug/ee/i386/dbghelpers.S b/src/debug/ee/i386/dbghelpers.S
new file mode 100644
index 0000000000..d0a11011ca
--- /dev/null
+++ b/src/debug/ee/i386/dbghelpers.S
@@ -0,0 +1,70 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+.intel_syntax noprefix
+#include "unixasmmacros.inc"
+
+//extern FuncEvalHijackWorker:proc
+
+// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
+NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix
+ push eax // the ptr to the DebuggerEval
+ call C_FUNC(FuncEvalHijackWorker)
+ jmp eax // return is the patch addresss to jmp to
+
+NESTED_END FuncEvalHijack, _TEXT
+
+//
+// Flares for interop debugging.
+// Flares are exceptions (breakpoints) at well known addresses which the RS
+// listens for when interop debugging.
+//
+
+// This exception is from managed code.
+LEAF_ENTRY SignalHijackStartedFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,1
+ ret
+LEAF_END SignalHijackStartedFlare, _TEXT
+
+// Start the handoff
+LEAF_ENTRY ExceptionForRuntimeHandoffStartFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,2
+ ret
+LEAF_END ExceptionForRuntimeHandoffStartFlare, _TEXT
+
+// Finish the handoff.
+LEAF_ENTRY ExceptionForRuntimeHandoffCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,3
+ ret
+LEAF_END ExceptionForRuntimeHandoffCompleteFlare, _TEXT
+
+// Signal execution return to unhijacked state
+LEAF_ENTRY SignalHijackCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,4
+ ret
+LEAF_END SignalHijackCompleteFlare, _TEXT
+
+// This exception is from unmanaged code.
+LEAF_ENTRY ExceptionNotForRuntimeFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,5
+ ret
+LEAF_END ExceptionNotForRuntimeFlare, _TEXT
+
+// The Runtime is synchronized.
+LEAF_ENTRY NotifyRightSideOfSyncCompleteFlare, _TEXT
+ int 3
+ // make sure that the basic block is unique
+ test eax,6
+ ret
+LEAF_END NotifyRightSideOfSyncCompleteFlare, _TEXT
diff --git a/src/debug/ee/wks/CMakeLists.txt b/src/debug/ee/wks/CMakeLists.txt
index a096cbfca7..2b1aff57a1 100644
--- a/src/debug/ee/wks/CMakeLists.txt
+++ b/src/debug/ee/wks/CMakeLists.txt
@@ -55,9 +55,7 @@ else ()
add_compile_options(-fPIC)
-if(CLR_CMAKE_PLATFORM_ARCH_AMD64)
- add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
-elseif(CLR_CMAKE_PLATFORM_ARCH_ARM)
+if(CLR_CMAKE_PLATFORM_ARCH_AMD64 OR CLR_CMAKE_PLATFORM_ARCH_ARM OR CLR_CMAKE_PLATFORM_ARCH_I386)
add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64)
add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS})