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

Code before:
  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;

        // Copy the createdump argv
        int argc = 0;
        for (; argc < MAX_ARGV_ENTRIES && g_argvCreateDump[argc] != nullptr; argc++)

Review comment (bug):
@lateralusX I briefly looked into emitting the callstacks in the same manner that CrashInfo.cs does it. It seemed like its format was designed for managed exceptions, and I don't know if it'd be useful to stub in fields like the type, hr, message, etc. until we know what tools reading the adb log would expect.

If we did want to format it a particular way, it looed liked we'd be adding another API to CallStackLogger, for what seems like a temporary solution until Android CoreCLR can create a dump.

Code after:
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

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