From 7d74570d33823d4734fa287bc21a81ff12f7b40a Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Mon, 8 Feb 2016 17:47:31 -0800 Subject: Fix SOS managed breakpoints when coreclr symbols are stripped. Added a SOS DAC interface (ISOSDacInterface4::GetClrNotification) to get the exception notification arguments instead of using the GetLastExceptionInformation function from the lldb sosplugin that depends on coreclr symbols being present. On the coreclr side, the clr notification arguments are saved in a global variable that is DAC accessible. A critical section was added to protect this global variable while the special exception is raised. Setting the internal COMPlus_DebugBreakOnAssert environment variable causes 3 or 4 breaks in the debugger with no reason. It was breaking in the function that was determining whether it should break. I was using COMPlus_BreakOnEELoad=2 to break after coreclr was loaded and initialized to set managed breakpoints and on a debug build it generates an assert (on release just a DebugBreak). --- src/vm/util.cpp | 53 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'src/vm/util.cpp') diff --git a/src/vm/util.cpp b/src/vm/util.cpp index 6728e26a27..36c02128b9 100644 --- a/src/vm/util.cpp +++ b/src/vm/util.cpp @@ -3250,6 +3250,8 @@ BOOL GcNotifications::SetNotification(GcEvtArgs ev) return TRUE; } +GARY_IMPL(size_t, g_clrNotificationArguments, MAX_CLR_NOTIFICATION_ARGS); + #ifdef DACCESS_COMPILE GcNotification *GcNotifications::InitializeNotificationTable(UINT TableSize) @@ -3273,10 +3275,12 @@ BOOL GcNotifications::UpdateOutOfProcTable() { return ::UpdateOutOfProcTable(g_pGcNotificationTable, m_gcTable - 1, GetTableSize() + 1); } -#endif // DACCESS_COMPILE +#else // DACCESS_COMPILE + +static CrstStatic g_clrNotificationCrst; -void DACNotifyExceptionHelper(TADDR *args,UINT argCount) +void DACRaiseException(TADDR *args, UINT argCount) { struct Param { @@ -3287,18 +3291,40 @@ void DACNotifyExceptionHelper(TADDR *args,UINT argCount) param.argCount = argCount; PAL_TRY(Param *, pParam, ¶m) - { - if (IsDebuggerPresent() && !CORDebuggerAttached()) - { - RaiseException(CLRDATA_NOTIFY_EXCEPTION, 0, pParam->argCount, (ULONG_PTR *) pParam->args); - } + { + RaiseException(CLRDATA_NOTIFY_EXCEPTION, 0, pParam->argCount, (ULONG_PTR *)pParam->args); } PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { + { } PAL_ENDTRY } +void DACNotifyExceptionHelper(TADDR *args, UINT argCount) +{ + _ASSERTE(argCount <= MAX_CLR_NOTIFICATION_ARGS); + + if (IsDebuggerPresent() && !CORDebuggerAttached()) + { + CrstHolder lh(&g_clrNotificationCrst); + + for (UINT i = 0; i < argCount; i++) + { + g_clrNotificationArguments[i] = args[i]; + } + + DACRaiseException(args, argCount); + + g_clrNotificationArguments[0] = NULL; + } +} + +void InitializeClrNotifications() +{ + g_clrNotificationCrst.Init(CrstClrNotification); + g_clrNotificationArguments[0] = NULL; +} + // FIX IN BETA 2 // // g_dacNotificationFlags is only modified by the DAC and therefore the @@ -3318,18 +3344,19 @@ void DACNotifyExceptionHelper(TADDR *args,UINT argCount) #pragma warning(disable: 4748) #pragma optimize("", off) #endif // _MSC_VER - // called from the runtime + +// called from the runtime void DACNotify::DoJITNotification(MethodDesc *MethodDescPtr) { WRAPPER_NO_CONTRACT; TADDR Args[2] = { JIT_NOTIFICATION, (TADDR) MethodDescPtr }; - DACNotifyExceptionHelper(Args,2); + DACNotifyExceptionHelper(Args, 2); } void DACNotify::DoJITDiscardNotification(MethodDesc *MethodDescPtr) { TADDR Args[2] = { JIT_DISCARD_NOTIFICATION, (TADDR) MethodDescPtr }; - DACNotifyExceptionHelper(Args,2); + DACNotifyExceptionHelper(Args, 2); } void DACNotify::DoModuleLoadNotification(Module *ModulePtr) @@ -3387,7 +3414,9 @@ void DACNotify::DoExceptionCatcherEnterNotification(MethodDesc *MethodDescPtr, D #endif // _MSC_VER // - // called from the DAC +#endif // DACCESS_COMPILE + +// called from the DAC int DACNotify::GetType(TADDR Args[]) { // Type is an enum, and will thus fit into an int. -- cgit v1.2.3