Exemplo n.º 1
0
void OnException(int signo)
{
    if (signo == SIGCHLD)
        return;


#define WRITE_STRING_LEN(STR, LEN) \
    do { \
        write(STDERR_FILENO, (STR), (LEN)); \
        if (fd) \
            write(fd, (STR), (LEN)); \
    } while(0)

#define WRITE_STRING(STR) \
    WRITE_STRING_LEN(STR, (sizeof(STR) - sizeof(STR[0])))

#define WRITE_BUFFER(BUFFER) \
    WRITE_STRING_LEN((BUFFER).buffer, (BUFFER).offset)

    MinimalBuffer buffer;

    int fd = 0;

    if (crashlog && (signo == SIGSEGV || signo == SIGABRT || signo == SIGKILL))
        fd = open(crashlog, O_WRONLY | O_CREAT | O_TRUNC, 0644);

    /* print signal info */
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, signo, 10);
    WRITE_STRING("=========================\n");
    WRITE_STRING("FCITX " VERSION " -- Get Signal No.: ");
    WRITE_BUFFER(buffer);
    WRITE_STRING("\n");

    /* print time info */
    time_t t = time(NULL);
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, t, 10);
    WRITE_STRING("Date: try \"date -d @");
    WRITE_BUFFER(buffer);
    WRITE_STRING("\" if you are using GNU date ***\n");

    /* print process info */
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, getpid(), 10);
    WRITE_STRING("ProcessID: ");
    WRITE_BUFFER(buffer);
    WRITE_STRING("\n");

#if defined(ENABLE_BACKTRACE)
#define BACKTRACE_SIZE 32
    void *array[BACKTRACE_SIZE] = {NULL, };

    int size = backtrace(array, BACKTRACE_SIZE);
    backtrace_symbols_fd(array, size, STDERR_FILENO);
    if (fd)
        backtrace_symbols_fd(array, size, fd);
#endif

    if (fd)
        close(fd);

    switch (signo) {
    case SIGKILL:
        break;
    case SIGABRT:
    case SIGSEGV:
    case SIGBUS:
    case SIGILL:
    case SIGFPE:
        exit(1);
        break;

    default:
        {
            if (!instance || !instance->initialized) {
                exit(1);
                break;
            }

            uint8_t sig = 0;
            if (signo < 0xff)
                sig = (uint8_t)(signo & 0xff);
            write(selfpipe[1], &sig, 1);
            signal(signo, OnException);
        }
        break;
    }
}
Exemplo n.º 2
0
void OnException(int signo)
{
    if (signo == SIGCHLD)
        return;

    MinimalBuffer buffer;
    int fd = -1;

    if (crashlog && (signo == SIGSEGV || signo == SIGABRT))
        fd = open(crashlog, O_WRONLY | O_CREAT | O_TRUNC, 0644);

    /* print signal info */
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, signo, 10);
    _write_string(fd, "=========================\n");
    _write_string(fd, "FCITX " VERSION " -- Get Signal No.: ");
    _write_buffer(fd, &buffer);
    _write_string(fd, "\n");

    /* print time info */
    time_t t = time(NULL);
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, t, 10);
    _write_string(fd, "Date: try \"date -d @");
    _write_buffer(fd, &buffer);
    _write_string(fd, "\" if you are using GNU date ***\n");

    /* print process info */
    BufferReset(&buffer);
    BufferAppendUInt64(&buffer, getpid(), 10);
    _write_string(fd, "ProcessID: ");
    _write_buffer(fd, &buffer);
    _write_string(fd, "\n");

#if defined(ENABLE_BACKTRACE)
#define BACKTRACE_SIZE 32
    void *array[BACKTRACE_SIZE] = { NULL, };

    int size = backtrace(array, BACKTRACE_SIZE);
    backtrace_symbols_fd(array, size, STDERR_FILENO);
    if (fd >= 0)
        backtrace_symbols_fd(array, size, fd);
#endif

    if (fd >= 0)
        close(fd);

    switch (signo) {
    case SIGABRT:
    case SIGSEGV:
    case SIGBUS:
    case SIGILL:
    case SIGFPE:
        exit(1);
        break;
    default:
        {
            if (!instance || !instance->initialized) {
                exit(1);
                break;
            }

            uint8_t sig = 0;
            if (signo < 0xff)
                sig = (uint8_t)(signo & 0xff);
            write(selfpipe[1], &sig, 1);
            signal(signo, OnException);
        }
        break;
    }
}