-
Armin Felder authoredArmin Felder authored
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
}