<commit_before>/**
 * Copyright (c) 2017 <NAME>
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/core/util/crash.h"

#include "saiga/core/util/assert.h"

#include <iostream>


#if defined(_WIN32)
#    include <signal.h>
#    include <stdio.h>
#    include <stdlib.h>
#    include <tchar.h>
#    include <windows.h>
// dbghelp must be included after windows.h
#    include <DbgHelp.h>
#endif


#if defined(__unix__)
#    include <execinfo.h>
#    include <signal.h>
#    include <stdio.h>
#    include <stdlib.h>
#    include <string.h>
#    include <ucontext.h>
#    include <unistd.h>
#endif
#include "internal/noGraphicsAPI.h"
namespace Saiga
{
std::function<void()> customCrashHandler;

void addCustomSegfaultHandler(std::function<void()> fnc)
{
    customCrashHandler = fnc;
}

#if defined(__unix__)
// Source: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes

/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext
{
    unsigned long uc_flags;
    struct ucontext* uc_link;
    stack_t uc_stack;
    struct sigcontext uc_mcontext;
    sigset_t uc_sigmask;
} sig_ucontext_t;


void printCurrentStack()
{
    void* array[50];
    char** messages;
    int size, i;

    size = backtrace(array, 50);

    /* overwrite sigaction with caller's address */
    //    array[1] = caller_address;

    messages = backtrace_symbols(array, size);

    /* skip first stack frame (points here) */
    for (i = 0; i < size && messages != NULL; ++i)
    {
        std::cout << "[bt]: (" << i << ") " << messages[i] << std::endl;
    }

    free(messages);
}

void crit_err_hdlr(int sig_num, siginfo_t* info, void* ucontext)
{
    void* caller_address;
    sig_ucontext_t* uc;

    uc = (sig_ucontext_t*)ucontext;

    /* Get the address at the time the signal was raised */
#    if defined(__i386__)                         // gcc specific
    caller_address = (void*)uc->uc_mcontext.eip;  // EIP: x86 specific
#    elif defined(__x86_64__)                     // gcc specific
    caller_address = (void*)uc->uc_mcontext.rip;  // RIP: x86_64 specific
#    elif defined(__arm__)
    caller_address = (void*)uc->uc_mcontext.arm_pc;
#    else
#        error Unsupported architecture. // TODO: Add support for other arch.
#    endif

    std::cout << "signal " << sig_num << " (" << strsignal(sig_num) << ")"
              << ", address is " << info->si_addr << " from " << (void*)caller_address << std::endl;


    printCurrentStack();

    if (customCrashHandler) customCrashHandler();<commit_msg>crash<commit_after>/**
 * Copyright (c) 2017 <NAME>
 * Licensed under the MIT License.
 * See LICENSE file for more information.
 */

#include "saiga/core/util/crash.h"

#include "saiga/core/util/assert.h"

#include <iostream>


#if defined(_WIN32)
#    include <signal.h>
#    include <stdio.h>
#    include <stdlib.h>
#    include <tchar.h>
#    include <windows.h>
// dbghelp must be included after windows.h
#    include <DbgHelp.h>
#endif


#if defined(__unix__)
#    include <execinfo.h>
#    include <signal.h>
#    include <stdio.h>
#    include <stdlib.h>
#    include <string.h>
#    include <ucontext.h>
#    include <unistd.h>
#endif
#include "internal/noGraphicsAPI.h"
namespace Saiga
{
std::function<void()> customCrashHandler;

void addCustomSegfaultHandler(std::function<void()> fnc)
{
    customCrashHandler = fnc;
}

#if defined(__unix__)
// Source: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes

/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext
{
    unsigned long uc_flags;
    struct ucontext* uc_link;
    stack_t uc_stack;
    struct sigcontext uc_mcontext;
    sigset_t uc_sigmask;
} sig_ucontext_t;


void printCurrentStack()
{
    void* array[50];
    char** messages;
    int size, i;

    size = backtrace(array, 50);

    /* overwrite sigaction with caller's address */
    //    array[1] = caller_address;

    messages = backtrace_symbols(array, size);

    /* skip first stack frame (points here) */
    for (i = 0; i < size && messages != NULL; ++i)
    {
        std::cout << "[bt]: (" << i << ") " << messages[i] << std::endl;
    }

    free(messages);
}

void crit_err_hdlr(int sig_num, siginfo_t* info, void* ucontext)
{
    void* caller_address;
    sig_ucontext_t* uc;

    uc = (sig_ucontext_t*)ucontext;

    /* Get the address at the time the signal was raised */
#    if defined(__i386__)                         // gcc specific
    caller_address = (void*)uc->uc_mcontext.eip;  // EIP: x86 specific
#    elif defined(__x86_64__)                     // gcc specific
    caller_address = (void*)uc->uc_mcontext.rip;  // RIP: x86_64 specific
#    elif defined(__arm__)
    caller_address = (void*)uc->uc_mcontext.arm_pc;
#    else
    caller_address = nullptr;
    (void)uc;
#    endif

    std::cout << "signal " << sig_num << " (" << strsignal(sig_num) << ")"
              << ", address is " << info->si_addr << " from " << (void*)caller_address << std::endl;


    printCurrentStack();

    if (customCrashHandler) customCrashHandler();
{'fraction_non_alphanumeric': 0.1417337936325278, 'fraction_numerical': 0.011507479861910242, 'mean_word_length': 3.027027027027027, 'pattern_counts': {'":': 0, '<': 99, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7563322', 'n_tokens_mistral': 1872, 'n_tokens_neox': 1766, 'n_words': 417}