Repository: dotnet/runtime
File: src/coreclr/pal/src/thread/process.cpp (C++)

Code before:
Abstract:
  Signals that a crash report has already been logged for this crash.
  Android currently does not support CreateDump, so a crash report is manually logged.
  This prevents duplicate stack traces from being logged (e.g. unhandled exception)
--*/
VOID
PALAPI
PAL_MarkCrashReportAlreadyLogged()
{
    InterlockedExchange(&s_crashReportAlreadyLogged, TRUE);
}
#endif // HOST_ANDROID

VOID
PROCCreateCrashReportAndDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, bool serialize)
{
    // Preserve context pointer to prevent optimization
    DoNotOptimize(&context);

#ifdef HOST_ANDROID
    // Android CoreCLR currently does not support CreateDump, so log a crash report until then.
    // Use atomic exchange to ensure only one thread logs the crash report to avoid interleaved output.
    if (InterlockedCompareExchange(&s_crashReportAlreadyLogged, TRUE, FALSE) == FALSE &&
        LogCallstackForAndroidNativeCrash != nullptr)
    {
        minipal_log_write_fatal(".NET runtime crash report\n");
        LogCallstackForAndroidNativeCrash();
    }
#endif //HOST_ANDROID

    PROCCreateCrashDumpIfEnabled(signal, siginfo, context, serialize);
}

/*++
Function:
  PROCCreateCrashDumpIfEnabled

  Creates crash dump of the process (if enabled). Can be
  called from the unhandled native exception handler.

Parameters:
  signal - POSIX signal number
  siginfo - POSIX signal info or nullptr
  context - signal context or nullptr
  serialize - allow only one thread to generate core dump

(no return value)
--*/
#ifdef HOST_ANDROID
VOID
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, bool serialize)

Review comment (bug):
```suggestion
        minipal_log_write_fatal("Fatal error\n");
```
I would not call this ".NET runtime crash report". On Windows, we terminate the process with "Fatal error." message for this type of crashes so we may do the same here.

Code after:

static LPCWSTR GetSignalName(int signal)
{
    switch (signal)
    {
        case SIGSEGV: return W("SIGSEGV");
        case SIGBUS:  return W("SIGBUS");
        case SIGFPE:  return W("SIGFPE");
        case SIGILL:  return W("SIGILL");
        case SIGABRT: return W("SIGABRT");
        case SIGTRAP: return W("SIGTRAP");
        case SIGTERM: return W("SIGTERM");
        default:      return W("Unknown signal");
    }
}

/*++
Function:
  PROCLogManagedCallstackForSignal

  Invokes the registered callback to log the managed callstack for a signal.
  Used by Android since CreateDump is not supported there.

Parameters:
  signal - POSIX signal number

(no return value)
--*/
VOID
PROCLogManagedCallstackForSignal(int signal)
{
    if (g_logManagedCallstackForSignalCallback != nullptr)
    {
        LPCWSTR signalName = GetSignalName(signal);
        g_logManagedCallstackForSignalCallback(signalName);
    }
}

/*++
Function:
  PROCCreateCrashDumpIfEnabled

  Creates crash dump of the process (if enabled). Can be
  called from the unhandled native exception handler.

Parameters:
  signal - POSIX signal number
  siginfo - POSIX signal info or nullptr
  context - signal context or nullptr
  serialize - allow only one thread to generate core dump