123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * Copyright (C) 2009 Aleksey Palazhchenko
- * Copyright (C) 2014 Sergey Shambir
- * Copyright (C) 2016 Alexander Makarov
- *
- * This file is a part of Breakpad-qt library.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- */
- #include <QDir>
- #include <QProcess>
- #include <QCoreApplication>
- #include <QMessageBox>
- #include "QBreakpadHandler.h"
- #include "QBreakpadHttpUploader.h"
- #define QBREAKPAD_VERSION 0x000400
- #if defined(Q_OS_MAC)
- #include "client/mac/handler/exception_handler.h"
- #elif defined(Q_OS_LINUX)
- #include "client/linux/handler/exception_handler.h"
- #elif defined(Q_OS_WIN32)
- #include "client/windows/handler/exception_handler.h"
- #endif
- #if defined(Q_OS_WIN32)
- bool DumpCallback(const wchar_t* dump_dir,
- const wchar_t* minidump_id,
- void* context,
- EXCEPTION_POINTERS* exinfo,
- MDRawAssertionInfo* assertion,
- bool succeeded)
- #elif defined(Q_OS_MAC)
- bool DumpCallback(const char *dump_dir,
- const char *minidump_id,
- void *context, bool succeeded)
- #else
- bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor,
- void* context,
- bool succeeded)
- #endif
- {
- #ifdef Q_OS_LINUX
- Q_UNUSED(descriptor);
- #endif
- Q_UNUSED(context);
- #if defined(Q_OS_WIN32)
- Q_UNUSED(assertion);
- Q_UNUSED(exinfo);
- #endif
- /*
- NO STACK USE, NO HEAP USE THERE !!!
- Creating QString's, using qDebug, etc. - everything is crash-unfriendly.
- */
- #if defined(Q_OS_WIN32)
- QString path = QString::fromWCharArray(dump_dir) + QLatin1String("/") + QString::fromWCharArray(minidump_id);
- qDebug("%s, dump path: %s\n", succeeded ? "Succeed to write minidump" : "Failed to write minidump", qPrintable(path));
- #elif defined(Q_OS_MAC)
- QString path = QString::fromUtf8(dump_dir) + QLatin1String("/") + QString::fromUtf8(minidump_id);
- qDebug("%s, dump path: %s\n", succeeded ? "Succeed to write minidump" : "Failed to write minidump", qPrintable(path));
- #else
- qDebug("%s, dump path: %s\n", succeeded ? "Succeed to write minidump" : "Failed to write minidump", descriptor.path());
- #endif
- return succeeded;
- }
- class QBreakpadHandlerPrivate
- {
- public:
- google_breakpad::ExceptionHandler* pExptHandler;
- QString dumpPath;
- QUrl uploadUrl;
- };
- //------------------------------------------------------------------------------
- QString QBreakpadHandler::version()
- {
- return QString("%1.%2.%3").arg(
- QString::number((QBREAKPAD_VERSION >> 16) & 0xff),
- QString::number((QBREAKPAD_VERSION >> 8) & 0xff),
- QString::number(QBREAKPAD_VERSION & 0xff));
- }
- QBreakpadHandler::QBreakpadHandler() :
- d(new QBreakpadHandlerPrivate())
- {
- }
- QBreakpadHandler::~QBreakpadHandler()
- {
- delete d;
- }
- void QBreakpadHandler::setDumpPath(const QString& path)
- {
- QString absPath = path;
- if(!QDir::isAbsolutePath(absPath)) {
- absPath = QDir::cleanPath(qApp->applicationDirPath() + "/" + path);
- }
- Q_ASSERT(QDir::isAbsolutePath(absPath));
- QDir().mkpath(absPath);
- if (!QDir().exists(absPath)) {
- qDebug("Failed to set dump path which not exists: %s", qPrintable(absPath));
- return;
- }
- d->dumpPath = absPath;
- // NOTE: ExceptionHandler initialization
- #if defined(Q_OS_WIN32)
- d->pExptHandler = new google_breakpad::ExceptionHandler(absPath.toStdWString(), /*FilterCallback*/ 0,
- DumpCallback, /*context*/ 0,
- google_breakpad::ExceptionHandler::HANDLER_ALL);
- #elif defined(Q_OS_MAC)
- d->pExptHandler = new google_breakpad::ExceptionHandler(absPath.toStdString(),
- /*FilterCallback*/ 0,
- DumpCallback, /*context*/ 0, true, NULL);
- #else
- d->pExptHandler = new google_breakpad::ExceptionHandler(google_breakpad::MinidumpDescriptor(absPath.toStdString()),
- /*FilterCallback*/ 0,
- DumpCallback,
- /*context*/ 0,
- true,
- -1);
- #endif
- }
- QString QBreakpadHandler::uploadUrl() const
- {
- return d->uploadUrl.toString();
- }
- QStringList QBreakpadHandler::dumpFileList() const
- {
- if(!d->dumpPath.isNull() && !d->dumpPath.isEmpty()) {
- QDir dumpDir(d->dumpPath);
- dumpDir.setNameFilters(QStringList()<<"*.dmp");
- return dumpDir.entryList();
- }
- return QStringList();
- }
- void QBreakpadHandler::setUploadUrl(const QUrl &url)
- {
- if(!url.isValid() || url.isEmpty())
- return;
- d->uploadUrl = url;
- }
- void QBreakpadHandler::sendDumps()
- {
- if(!d->dumpPath.isNull() && !d->dumpPath.isEmpty()) {
- QDir dumpDir(d->dumpPath);
- dumpDir.setNameFilters(QStringList()<<"*.dmp");
- QStringList dumpFiles = dumpDir.entryList();
- foreach(QString itDmpFileName, dumpFiles) {
- qDebug() << "Sending " << QString(itDmpFileName);
- QBreakpadHttpUploader *sender = new QBreakpadHttpUploader(d->uploadUrl);
- sender->uploadDump(d->dumpPath + "/" + itDmpFileName);
- }
- }
- }
|