/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "tools/CrashHandler.h"

#include "include/private/SkDebug.h"
#include "src/core/SkLeanWindows.h"

#include <array>  // for std::size
#include <stdlib.h>

#if defined(SK_BUILD_FOR_MAC)
    // We only use local unwinding, so we can define this to select a faster implementation.
    #define UNW_LOCAL_ONLY
    #include <libunwind.h>
    #include <cxxabi.h>

    static void handler(int sig) {
        unw_context_t context;
        unw_getcontext(&context);

        unw_cursor_t cursor;
        unw_init_local(&cursor, &context);

        SkDebugf("\nSignal %d:\n", sig);
        while (unw_step(&cursor) > 0) {
            static const size_t kMax = 256;
            char mangled[kMax], demangled[kMax];
            unw_word_t offset;
            unw_get_proc_name(&cursor, mangled, kMax, &offset);

            int ok;
            size_t len = kMax;
            abi::__cxa_demangle(mangled, demangled, &len, &ok);

            SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
        }
        SkDebugf("\n");

        // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
        _Exit(sig);
    }

#elif defined(SK_BUILD_FOR_UNIX)
    // We'd use libunwind here too, but it's a pain to get installed for
    // both 32 and 64 bit on bots.  Doesn't matter much: catchsegv is best anyway.
    #include <cxxabi.h>
    #include <dlfcn.h>
    #include <string.h>
#if defined(__Fuchsia__)
    #include <stdint.h>

    // syslog crash reporting from Fuchsia's backtrace_request.h
    //
    // Special value we put in the first register to let the exception handler know
    // that we are just requesting a backtrace and we should resume the thread.
    #define BACKTRACE_REQUEST_MAGIC ((uint64_t)0xee726573756d65ee)

    // Prints a backtrace, resuming the thread without killing the process.
    __attribute__((always_inline)) static inline void backtrace_request(void) {
      // Two instructions: one that sets a software breakpoint ("int3" on x64,
      // "brk" on arm64) and one that writes the "magic" value in the first
      // register ("a" on x64, "x0" on arm64).
      //
      // We set a software breakpoint to trigger the exception handling in
      // crashsvc, which will print the debug info, including the backtrace.
      //
      // We write the "magic" value in the first register so that the exception
      // handler can check for it and resume the thread if present.
      #ifdef __x86_64__
        __asm__("int3" : : "a"(BACKTRACE_REQUEST_MAGIC));
      #endif
      #ifdef __aarch64__
        // This is what gdb uses.
        __asm__(
            "mov x0, %0\n"
            "\tbrk 0"
            :
            : "r"(BACKTRACE_REQUEST_MAGIC)
            : "x0");
      #endif
    }
#else
    #include <execinfo.h>
#endif

    static void handler(int sig) {
#if defined(__Fuchsia__)
        backtrace_request();
#else
        void* stack[64];
        const int count = backtrace(stack, std::size(stack));
        char** symbols = backtrace_symbols(stack, count);

        SkDebugf("\nSignal %d [%s]:\n", sig, strsignal(sig));
        for (int i = 0; i < count; i++) {
            Dl_info info;
            if (dladdr(stack[i], &info) && info.dli_sname) {
                char demangled[256];
                size_t len = std::size(demangled);
                int ok;

                abi::__cxa_demangle(info.dli_sname, demangled, &len, &ok);
                if (ok == 0) {
                    SkDebugf("    %s\n", demangled);
                    continue;
                }
            }
            SkDebugf("    %s\n", symbols[i]);
        }
#endif
        // Exit NOW.  Don't notify other threads, don't call anything registered with
        // atexit().
        _Exit(sig);
    }
#endif

#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_UNIX)
    #include <signal.h>

    void SetupCrashHandler() {
        static const int kSignals[] = {
            SIGABRT,
            SIGBUS,
            SIGFPE,
            SIGILL,
            SIGSEGV,
            SIGTRAP,
        };

        for (size_t i = 0; i < sizeof(kSignals) / sizeof(kSignals[0]); i++) {
            // Register our signal handler unless something's already done so (e.g. catchsegv).
            void (*prev)(int) = signal(kSignals[i], handler);
            if (prev != SIG_DFL) {
                signal(kSignals[i], prev);
            }
        }
    }

#elif defined(SK_BUILD_FOR_WIN)

    #include <DbgHelp.h>
    #include <stdint.h>
    #include "include/private/SkMalloc.h"

    static const struct {
        const char* name;
        const DWORD code;
    } kExceptions[] = {
    #define _(E) {#E, E}
        _(EXCEPTION_ACCESS_VIOLATION),
        _(EXCEPTION_BREAKPOINT),
        _(EXCEPTION_INT_DIVIDE_BY_ZERO),
        _(EXCEPTION_STACK_OVERFLOW),
        // TODO: more?
    #undef _
    };

    static LONG WINAPI handler(EXCEPTION_POINTERS* e) {
        const DWORD code = e->ExceptionRecord->ExceptionCode;
        SkDebugf("\nCaught exception %lu", code);
        for (size_t i = 0; i < std::size(kExceptions); i++) {
            if (kExceptions[i].code == code) {
                SkDebugf(" %s", kExceptions[i].name);
            }
        }
        SkDebugf("\n");

        // We need to run SymInitialize before doing any of the stack walking below.
        HANDLE hProcess = GetCurrentProcess();
        SymInitialize(hProcess, 0, true);

        STACKFRAME64 frame;
        sk_bzero(&frame, sizeof(frame));
        // Start frame off from the frame that triggered the exception.
        CONTEXT* c = e->ContextRecord;
        frame.AddrPC.Mode      = AddrModeFlat;
        frame.AddrStack.Mode   = AddrModeFlat;
        frame.AddrFrame.Mode   = AddrModeFlat;
    #if defined(_X86_)
        frame.AddrPC.Offset    = c->Eip;
        frame.AddrStack.Offset = c->Esp;
        frame.AddrFrame.Offset = c->Ebp;
        const DWORD machineType = IMAGE_FILE_MACHINE_I386;
    #elif defined(_AMD64_)
        frame.AddrPC.Offset    = c->Rip;
        frame.AddrStack.Offset = c->Rsp;
        frame.AddrFrame.Offset = c->Rbp;
        const DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
    #elif defined(_M_ARM64)
        frame.AddrPC.Offset    = c->Pc;
        frame.AddrStack.Offset = c->Sp;
        frame.AddrFrame.Offset = c->Fp;
        const DWORD machineType = IMAGE_FILE_MACHINE_ARM64;
    #endif

    #if !defined(SK_WINUWP)
        while (StackWalk64(machineType,
                           GetCurrentProcess(),
                           GetCurrentThread(),
                           &frame,
                           c,
                           nullptr,
                           SymFunctionTableAccess64,
                           SymGetModuleBase64,
                           nullptr)) {
            // Buffer to store symbol name in.
            static const int kMaxNameLength = 1024;
            uint8_t buffer[sizeof(IMAGEHLP_SYMBOL64) + kMaxNameLength];
            sk_bzero(buffer, sizeof(buffer));

            // We have to place IMAGEHLP_SYMBOL64 at the front, and fill in
            // how much space it can use.
            IMAGEHLP_SYMBOL64* symbol = reinterpret_cast<IMAGEHLP_SYMBOL64*>(&buffer);
            symbol->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
            symbol->MaxNameLength = kMaxNameLength - 1;

            // Translate the current PC into a symbol and byte offset from the symbol.
            DWORD64 offset;
            SymGetSymFromAddr64(hProcess, frame.AddrPC.Offset, &offset, symbol);

            SkDebugf("%s +%llx\n", symbol->Name, offset);
        }
    #endif //SK_WINUWP

        // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
        _exit(1);

        // The compiler wants us to return something.  This is what we'd do
        // if we didn't _exit().
        return EXCEPTION_EXECUTE_HANDLER;
    }

    void SetupCrashHandler() {
        SetUnhandledExceptionFilter(handler);
    }

#else

    void SetupCrashHandler() { }

#endif
