Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AssertOnFailFast, W("AssertOnFailFast")
RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_legacyCorruptedStateExceptionsPolicy, W("legacyCorruptedStateExceptionsPolicy"), 0, "Enabled Pre-V4 CSE behavior", CLRConfig::FavorConfigFile)
CONFIG_DWORD_INFO_EX(INTERNAL_SuppressLostExceptionTypeAssert, W("SuppressLostExceptionTypeAssert"), 0, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_FailFastOnCorruptedStateException, W("FailFastOnCorruptedStateException"), 0, "Failfast if a CSE is encountered", CLRConfig::FavorConfigFile)
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_UseEntryPointFilter, W("UseEntryPointFilter"), 0, "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_Corhost_Swallow_Uncaught_Exceptions, W("Corhost_Swallow_Uncaught_Exceptions"), 0, "", CLRConfig::REGUTIL_default)

///
/// Garbage collector
Expand Down
19 changes: 16 additions & 3 deletions src/vm/corhost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,10 +460,23 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,
arguments->SetAt(i, argument);
}

DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
if (pReturnValue)
if(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Corhost_Swallow_Uncaught_Exceptions))
{
*pReturnValue = retval;
EX_TRY
DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
if (pReturnValue)
{
*pReturnValue = retval;
}
EX_CATCH_HRESULT (hr)
}
else
{
DWORD retval = pAssembly->ExecuteMainMethod(&arguments, TRUE /* waitForOtherThreads */);
if (pReturnValue)
{
*pReturnValue = retval;
}
}

GCPROTECT_END();
Expand Down
20 changes: 16 additions & 4 deletions src/vm/excep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5139,17 +5139,29 @@ LONG InternalUnhandledExceptionFilter(

} // LONG InternalUnhandledExceptionFilter()

static bool s_useEntryPointFilter = false;

// Represent the value of USE_ENTRYPOINT_FILTER as passed in the property bag to the host during construction
static bool s_useEntryPointFilterCorhostProperty = false;

void ParseUseEntryPointFilter(LPCWSTR value)
{
#ifdef PLATFORM_WINDOWS // This feature has only been tested on Windows, keep it disabled on other platforms
// set s_useEntryPointFilter true if value != "0"
if (value && (_wcsicmp(value, W("0")) != 0))
{
s_useEntryPointFilter = true;
s_useEntryPointFilterCorhostProperty = true;
}
}

bool GetUseEntryPointFilter()
{
#ifdef PLATFORM_WINDOWS // This feature has only been tested on Windows, keep it disabled on other platforms
static bool s_useEntryPointFilterEnv = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_UseEntryPointFilter) != 0;

return s_useEntryPointFilterCorhostProperty || s_useEntryPointFilterEnv;
#else
return false;
#endif

}

// This filter is used to trigger unhandled exception processing for the entrypoint thread
Expand All @@ -5172,7 +5184,7 @@ LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData)
return ret;
}

if (!s_useEntryPointFilter)
if (!GetUseEntryPointFilter())
{
return EXCEPTION_CONTINUE_SEARCH;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,20 @@ private static string RandomCookie()
.Select(s => s[random.Next(s.Length)]).ToArray());
}

private static bool LaunchTest(string testName, string[] logEntriesToCheck, string randomCookie)
private static bool LaunchTest(string testName, string[] logEntriesToCheck, string randomCookie, bool swallowExcep = false, bool useEntryPointFilter = false)
{
EventLog logBefore = new EventLog("Application");
int logBeforeCount = logBefore.Entries.Count;

DateTime dt = DateTime.Now;

Process testProcess = new Process();
string currentPath = Directory.GetCurrentDirectory();
string corerunPath = Environment.GetEnvironmentVariable("CORE_ROOT") + "\\corerun.exe";

testProcess.StartInfo.FileName = corerunPath;
testProcess.StartInfo.Arguments = currentPath + "\\WindowsEventLog.exe " + testName + " " + randomCookie;
testProcess.StartInfo.EnvironmentVariables["CORE_ROOT"] = Environment.GetEnvironmentVariable("CORE_ROOT");
testProcess.StartInfo.EnvironmentVariables["COMPlus_Corhost_Swallow_Uncaught_Exceptions"] = swallowExcep ? "1" : "0";
testProcess.StartInfo.EnvironmentVariables["COMPlus_UseEntryPointFilter"] = useEntryPointFilter ? "1" : "0";
testProcess.StartInfo.UseShellExecute = false;

testProcess.Start();
Expand All @@ -75,32 +75,31 @@ private static bool LaunchTest(string testName, string[] logEntriesToCheck, stri

Console.WriteLine("Found {0} entries in Event Log", logAfter.Entries.Count);

foreach (EventLogEntry entry in logAfter.Entries)
for (int i = logAfter.Entries.Count - 1; i >= logBeforeCount; --i)
{
EventLogEntry entry = logAfter.Entries[i];
int checkCount = 0;
if (entry.TimeGenerated > dt.AddMinutes(-3)) // Grant some leeway in the time error was logged
{
String source = entry.Source;
String message = entry.Message;

String source = entry.Source;
String message = entry.Message;

if (source.Contains(".NET Runtime"))
{
Console.WriteLine("*** Event Log ***");
Console.WriteLine(message);
foreach (string logEntry in logEntriesToCheck)
{
Console.WriteLine("Checking for existence of : " + logEntry);
if (message.Contains(logEntry))
checkCount += 1;
else
Console.WriteLine("Couldn't find it in: " + message);
Console.WriteLine("!!! Couldn't find it !!!");
}

if (source.Contains(".NET Runtime") && checkCount == logEntriesToCheck.Length && logBeforeCount < logAfter.Entries.Count)
if (checkCount == logEntriesToCheck.Length)
{
return true;
}
else if (source.Contains(".NET Runtime"))
{
Console.WriteLine("*** Event Log ***");
Console.WriteLine(message);
}
}
}
return false;
Expand All @@ -117,11 +116,11 @@ private static void DisableErrorDialog()
}
#endif

private static bool RunUnhandledExceptionTest()
private static bool RunUnhandledExceptionTest(bool swallowExcep = false, bool useEntryPointFilter = false)
{
string cookie = RandomCookie();
string[] logEntriesToCheck = { "unhandled exception", "ArgumentException", cookie };
return LaunchTest("UnhandledException", logEntriesToCheck, cookie);
return LaunchTest("UnhandledException", logEntriesToCheck, cookie, swallowExcep, useEntryPointFilter);
}

private static bool RunFailFastTest()
Expand All @@ -131,7 +130,6 @@ private static bool RunFailFastTest()
return LaunchTest("FailFast", logEntriesToCheck, cookie);
}


public static int Main(string[] args)
{
if (args.Length == 0) // When invoked with no args, launch itself with appropriate args to cause various exceptions
Expand All @@ -144,7 +142,30 @@ public static int Main(string[] args)

if (!RunUnhandledExceptionTest())
{
Console.WriteLine("WindowsEventLog Test: UnhandledExceptionTest failed.");
Console.WriteLine("WindowsEventLog Test: UnhandledExceptionTest() failed.");
return 1;
}

if (RunUnhandledExceptionTest(swallowExcep:true))
{
// Swallowing exceptions is reported to prevent logging to the Windows log.
// This is more of a test configuration sanity check than a requirement
Console.WriteLine("WindowsEventLog Test: UnhandledExceptionTest(swallowExcep:true) should have failed.");
return 1;
}

if (!RunUnhandledExceptionTest(swallowExcep:true, useEntryPointFilter:true))
{
// Logging should be the same with useEntryPointFilter
Console.WriteLine("WindowsEventLog Test: UnhandledExceptionTest(swallowExcep:true, useEntryPointFilter:true) failed.");
return 1;
}

if (!RunUnhandledExceptionTest(swallowExcep:false, useEntryPointFilter:true))
{
// Logging should be the same with useEntryPointFilter even without swallowing exception handler
// This is more of a test configuration sanity check than a requirement
Console.WriteLine("WindowsEventLog Test: UnhandledExceptionTest(swallowExcep:false, useEntryPointFilter:true) failed.");
return 1;
}

Expand Down