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

Code before:
  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
#include <minipal/log.h>
extern "C" void LogCallstackForAndroidNativeCrash() __attribute__((weak));
VOID
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, bool serialize)
{
    // Preserve context pointer to prevent optimization
    DoNotOptimize(&context);

    if (LogCallstackForAndroidNativeCrash != nullptr)
    {
        minipal_log_write_fatal("\n=================================================================\n");
        minipal_log_write_fatal("\tManaged Stacktrace:\n");
        minipal_log_write_fatal("=================================================================\n");
        LogCallstackForAndroidNativeCrash();
        minipal_log_write_fatal("=================================================================\n");
    }

    // TODO: Dump stress log into logcat and/or file when enabled?
    minipal_log_write_fatal("Aborting process.\n");
}
#else
VOID
PROCCreateCrashDumpIfEnabled(int signal, siginfo_t* siginfo, void* context, bool serialize)
{
    // Preserve context pointer to prevent optimization
    DoNotOptimize(&context);

    // If enabled, launch the create minidump utility and wait until it completes
    if (g_argvCreateDump[0] != nullptr)
    {
        const char* argv[MAX_ARGV_ENTRIES];
        char* signalArg = nullptr;
        char* crashThreadArg = nullptr;
        char* signalCodeArg = nullptr;
        char* signalErrnoArg = nullptr;
        char* signalAddressArg = nullptr;


Review comment (bug):
This should something more self-explanatory than just "Managed stacktrace:". Maybe something like "Crash in native code".

Code after:

// Helper function to prevent compiler from optimizing away a variable
__attribute__((noinline,NOOPT_ATTRIBUTE))
static void DoNotOptimize(const void* p)
{
    // This function takes the address of a variable to ensure
    // it's preserved and available in crash dumps
    (void)p;
}

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