GEnsureShowsCRC is not working in Editor

When I set `GEnsureShowsCRC` to `true` so that the Crash Report Client window appears every time an ensure event occurs, the window displays correctly on the first ensure, but on the second ensure, the Crash Report Client process hangs indefinitely, and the editor becomes unresponsive.

From debugging, it looks like the editor’s main thread is blocked while waiting for pipe I/O that never completes. My current suspicion is that the pipe / monitoring Crash Report Client state is not handled correctly after the first ensure report. Is this a known issue or a limitation of using GEnsureShowsCRC together with the monitoring Crash Report Client in the editor?

This feature works correctly when reporting in-game, repeated ensures can show the Crash Report Client window, apparently because the Crash Report Client is started when the ensure occurs rather than being reused in monitoring mode.

I would also like to understand the motivation behind using the monitoring Crash Report Client in the editor. Is this intended only for the editor, or is there a plan to support the monitoring Crash Report Client flow for game builds by default as well?

[Attachment Removed]

Steps to Reproduce
1) Set

GEnsureShowsCRC

to true.

2) Run editor

3) Report an ensure

4) Report another ensure

[Attachment Removed]

Hi Anna,

We only report the first ensure, as following ensures might be related to the first issue:

	if (ReportCrashCallCount > 0 || FDebug::HasAsserted())
	{
		// Don't report ensures after we've crashed/asserted, they simply may be a result of the crash as
		// the engine is already in a bad state.
		return;
	}

This should not work differently in Game versus editor.

[Attachment Removed]

I see, thanks for the expanded explanation. I was able to reproduce the issue by setting GEnsureShowsCRC and using `ensureAlways` (which forces the second ensure to be reported as well). Indeed this is an issue which only occurs when CRC is running in monitor mode. Unfortunately I don’t have bandwidth to fix this immediately. I would advice that you set `USE_CRASH_REPORTER_MONITOR=0` for your editor target as well.

Monitor mode was introduced because we suspected we were missing reports that in situations where the crashing application was unable to launch a new process (low memory, system pressure etc). The idea was that monitor mode would always be ready if a crash occurred. In addition to this late in UE4 lifetime we also introduced a “recovery feature” for the editor, that would record operations and was then able to “replay” unsaved work when editor was restarted. This service needed a place to live, so CRC(Editor) in monitor mode was a good fit. This feature proved too unreliable and was removed in UE5.

So in summary, CRC and CRCE targets are more or less identical today (CRASH_REPORT_WITH_MTBF is set in both for me), and both can run in monitor mode or “fire-and-forget” mode. The difference between the modes is only how the receive the reports and the lifetime of the process.

[Attachment Removed]

Hello Johan,

I’m afraid that we don’t mean the same thing. Ensure is a non-fatal error, and there is no reason not to report another (different) ensure after an ensure. The code snippet you sent is a case where a fatal error is reported (crash/assert); it makes sense that ensures after the fatal error are not reported then.

In UE, ensures are reported silently in the background by default, but we want to open CRC during each ensure. For this, we set the GEnsureShowsCRC property to true so that the CRC can be shown when an ensure occurs. That indeed works fine for the first encountered ensure, but both the editor and the CRC hang on the second one.

1) UE waits for the response from monitoring CRC; call stack:

FWindowsPlatformProcess::GetProcReturnCode(FProcHandle &, int *) WindowsPlatformProcess.cpp:1039
`anonymous namespace'::ReportCrashForMonitor(_EXCEPTION_POINTERS *, ECrashContextType, const wchar_t *, void *, void *, unsigned long, FProcHandle &, FSharedCrashContext *, void *, void *, EErrorReportUI) WindowsPlatformCrashContext.cpp:972
[Inlined] FCrashReportingThread::OnContinuableEvent(ECrashContextType, _EXCEPTION_POINTERS *, void *, unsigned int, void *, const wchar_t *, EErrorReportUI) WindowsPlatformCrashContext.cpp:1514
ReportContinuableEventUsingCrashReportClient(ECrashContextType, _EXCEPTION_POINTERS *, void *, unsigned int, void *, const wchar_t *, EErrorReportUI) WindowsPlatformCrashContext.cpp:1897
`ReportEventOnCallingThread'::`1'::filt$0(...) WindowsPlatformCrashContext.cpp:1914

2) CRC loops until the monitored process dies (but UE is still alive, waiting for CRC response, and the MonitoredProcess is valid.):

// Loop until the monitored process dies.
while (MonitoredProcess.IsValid() && FPlatformProcess::IsProcRunning(MonitoredProcess))
{...}

But in the CRC, the Engine exit was already requested (IsEngineExitRequested returns true, and it was set by default when the first CRC window was closed), so it skips reporting and loops indefinitely in idle. There is a comment about ignoring ensures as well, but as I mentioned, it should be just after a fatal error, not after an ensure.

// Check if the monitored process signaled a crash or an ensure, read the pipe data to avoid blocking the writer, but process the data only if CRC wasn't requested to exit.
// This purposedly ignores any ensure that could be piped out just after a crash. (The way concurrent crash/ensures are handled/reported make this unlikely, but possible).
FSharedCrashContext CrashContext;
if (IsCrashReportAvailable(MonitorPid, CrashContext, MonitorReadPipe) && !IsEngineExitRequested())
{...}

This is working differently in Game vs Editor, because Game does not use Monitoring CRC (CRASH_REPORT_WITH_MTBF). That was my follow-up question - do you plan to use the Monitoring CRC in Game in the future as well?

[Attachment Removed]