Skip to content
Snippets Groups Projects
segfaulthandler.cpp 3.94 KiB
/********************************************************************************************
 *                                                                                          *
 * Copyright (C) 2017 Armin Felder, Dennis Beier                                            *
 * This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>.     *
 *                                                                                          *
 * RocketChatMobileEngine is free software: you can redistribute it and/or modify           *
 * it under the terms of the GNU General Public License as published by                     *
 * the Free Software Foundation, either version 3 of the License, or                        *
 * (at your option) any later version.                                                      *
 *                                                                                          *
 * RocketChatMobileEngine is distributed in the hope that it will be useful,                *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                           *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            *
 * GNU General Public License for more details.                                             *
 *                                                                                          *
 * You should have received a copy of the GNU General Public License                        *
 * along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>.           *
 *                                                                                          *
 ********************************************************************************************/


#include "segfaulthandler.h"
#include <QDebug>
#include <QThread>

#if defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) || defined(Q_OS_LINUX) ||defined(Q_OS_IOS)
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#endif
#ifdef Q_OS_ANDROID
#include <QAndroidJniEnvironment>
#include <QAndroidJniObject>
#endif

#include "persistancelayer.h"

QHash<Qt::HANDLE, QString> SegfaultHandler::mFailurePoints;
QHash<Qt::HANDLE, struct sigaction> SegfaultHandler::mActs;


SegfaultHandler::SegfaultHandler( QObject *parent ) : QObject( parent )
{
    init();
}

SegfaultHandler::SegfaultHandler( QString pText )
{
    mFailurePoint = pText;
    SegfaultHandler::mFailurePoints[QThread::currentThreadId()] = pText;
    init();
}
SegfaultHandler::~SegfaultHandler()
{
    SegfaultHandler::mFailurePoints.remove( QThread::currentThreadId() );
}

void SegfaultHandler::segfaultHandlerMethod( int pSigno )
{
    Q_UNUSED( pSigno );
    QString errorString = "SIGSEGV in thread!";
    QString failurePoint = SegfaultHandler::mFailurePoints[QThread::currentThreadId()];

    if ( failurePoint.length() ) {
        qCritical() << " at: " << failurePoint;
        errorString += " : " + failurePoint;
    }

    qCritical() << errorString;
    PersistanceLayer *storage = PersistanceLayer::instance();
    storage->transaction();
    storage->setSetting( "ERROR", errorString );
    storage->commit();
#if defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) || defined(Q_OS_LINUX) ||defined(Q_OS_IOS)
    qDebug() << "currThread:" << QThread::currentThreadId();

    struct sigaction *act = &( SegfaultHandler::mActs[QThread::currentThreadId()] );
    qDebug() << act->sa_handler;
    act->sa_handler = SIG_DFL;
    sigaction( SIGSEGV, act, NULL );
    raise( SIGSEGV );
#endif
}

void SegfaultHandler::init()
{
#if defined(Q_OS_ANDROID) || defined(Q_OS_MACOS) || defined(Q_OS_LINUX) ||defined(Q_OS_IOS)
    struct sigaction act;
    act.sa_handler = SegfaultHandler::segfaultHandlerMethod;
    sigemptyset( &act.sa_mask );
    act.sa_flags = 0;

    qDebug() << "currThread:" << QThread::currentThreadId();
    SegfaultHandler::mActs[QThread::currentThreadId()] = act;

    sigaction( SIGSEGV, &( SegfaultHandler::mActs[QThread::currentThreadId()] ), NULL );
#endif
}