Skip to content

Commit 47282b1

Browse files
author
rhamlett_microsoft
committed
Updates to crash generation to bypass ANCM interception.
1 parent 069ea98 commit 47282b1

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

src/PerfProblemSimulator/Models/CrashRequest.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,17 @@ public class CrashRequest
3737

3838
/// <summary>
3939
/// If true, crash happens during the HTTP request (no response sent).
40-
/// This is more likely to be captured by Azure Crash Monitoring.
41-
/// Default: false (crash after response for better UX)
40+
/// This is required for Azure Crash Monitoring to capture the crash.
41+
/// Default: true (optimized for Azure Crash Monitoring)
4242
/// </summary>
4343
/// <remarks>
4444
/// <para>
45-
/// <strong>Azure Crash Monitoring Note:</strong> Set this to true for Azure Crash Monitoring
45+
/// <strong>Azure Crash Monitoring Note:</strong> This must be true for Azure Crash Monitoring
4646
/// to properly capture the crash. When false, the crash happens on a background thread
4747
/// after the HTTP response is sent, which Azure may not associate with a request.
4848
/// </para>
4949
/// </remarks>
50-
public bool Synchronous { get; set; } = false;
50+
public bool Synchronous { get; set; } = true;
5151
}
5252

5353
/// <summary>
@@ -84,5 +84,12 @@ public enum CrashType
8484
/// Allocates memory until the process runs out and crashes.
8585
/// Different from memory pressure - this is meant to be fatal.
8686
/// </summary>
87-
OutOfMemory = 4
87+
OutOfMemory = 4,
88+
89+
/// <summary>
90+
/// Uses RtlFailFast to trigger an unbypassable native crash.
91+
/// This bypasses all .NET and ANCM exception handlers and guarantees
92+
/// a Windows Error Report is generated. Best option for Azure Crash Monitoring.
93+
/// </summary>
94+
NativeCrash = 5
8895
}

src/PerfProblemSimulator/Services/CrashService.cs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ private void ExecuteCrash(CrashType crashType, string message)
117117
ExecuteOutOfMemory();
118118
break;
119119

120+
case CrashType.NativeCrash:
121+
ExecuteNativeCrash();
122+
break;
123+
120124
default:
121125
throw new ArgumentOutOfRangeException(nameof(crashType), crashType, "Unknown crash type");
122126
}
@@ -232,6 +236,38 @@ private void ExecuteAccessViolation()
232236
[DllImport("kernel32.dll", SetLastError = true)]
233237
private static extern void RaiseException(uint dwExceptionCode, uint dwExceptionFlags, uint nNumberOfArguments, IntPtr lpArguments);
234238

239+
/// <summary>
240+
/// Uses RtlFailFast to trigger an unbypassable crash that guarantees WER capture.
241+
/// </summary>
242+
/// <remarks>
243+
/// <para>
244+
/// <strong>Educational Note:</strong> RtlFailFast (the underlying implementation of __fastfail)
245+
/// is the nuclear option for crash generation. It:
246+
/// </para>
247+
/// <list type="bullet">
248+
/// <item>Bypasses ALL exception handlers (including ANCM in IIS InProcess mode)</item>
249+
/// <item>Generates a Windows Error Report that Crash Monitoring can capture</item>
250+
/// <item>Cannot be caught, filtered, or intercepted by any managed or unmanaged code</item>
251+
/// <item>Is what the CLR itself uses for internal fatal errors</item>
252+
/// </list>
253+
/// <para>
254+
/// Use this crash type if other crash types are not being captured by Azure Crash Monitoring.
255+
/// The error code 7 (FAST_FAIL_FATAL_APP_EXIT) is specifically designed for application crashes.
256+
/// </para>
257+
/// </remarks>
258+
private void ExecuteNativeCrash()
259+
{
260+
_logger.LogCritical("Triggering RtlFailFast - this will bypass all exception handlers!");
261+
262+
// FAST_FAIL_FATAL_APP_EXIT (7) - Indicates a fatal application error
263+
// This generates an unbypassable crash that Windows Error Reporting will capture
264+
const uint FAST_FAIL_FATAL_APP_EXIT = 7;
265+
RtlFailFast(FAST_FAIL_FATAL_APP_EXIT);
266+
}
267+
268+
[DllImport("ntdll.dll")]
269+
private static extern void RtlFailFast(uint Code);
270+
235271
/// <summary>
236272
/// Allocates memory until the process runs out and crashes.
237273
/// </summary>
@@ -311,7 +347,8 @@ public Dictionary<CrashType, string> GetCrashTypeDescriptions()
311347
[CrashType.StackOverflow] = "Triggers StackOverflowException via infinite recursion. Cannot be caught. Creates interesting stack traces for analysis.",
312348
[CrashType.UnhandledException] = "Throws an unhandled exception on a background thread, demonstrating the importance of proper exception handling.",
313349
[CrashType.AccessViolation] = "Writes to invalid memory (null pointer). Demonstrates native-level crashes common in P/Invoke or unsafe code bugs.",
314-
[CrashType.OutOfMemory] = "Allocates memory until the process crashes. Useful for learning memory dump analysis techniques."
350+
[CrashType.OutOfMemory] = "Allocates memory until the process crashes. Useful for learning memory dump analysis techniques.",
351+
[CrashType.NativeCrash] = "Uses RtlFailFast to bypass ALL exception handlers including ANCM. Guarantees WER capture - use this if other types aren't detected by Azure Crash Monitoring."
315352
};
316353
}
317354
}

0 commit comments

Comments
 (0)