Commit 454044b0d947b3a845eacb44574850a9e1dd3473

add breakpad support - probably doesn't build on windows right now, will fix shortly
hooq.pro
(7 / 2)
  
1include(common.pri)
2
13TEMPLATE = subdirs
24SUBDIRS += \
35 hooq \
99 injectedHooq \
1010 uilib \
1111
12include(common.pri)
13
1412# State dependencies to fix make -j
1513
1614hooq.depends += \
1717
1818hooqcli.depends += \
1919 hooqInjector \
20
21CONFIG(debug, debug|release) {
22 SUBDIRS += google-breakpad
23 hooq.depends += google-breakpad
24}
  
1/*
2 Hooq: Qt4 UI recording, playback, and testing toolkit.
3 Copyright (C) 2010 Mendeley Limited <copyright@mendeley.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*/
19///@author Robert Knight <robert.knight@mendeley.com>
20#include "BreakpadCrashHandler.h"
21
22#if defined(Q_OS_LINUX)
23 #include "google-breakpad/src/client/linux/handler/exception_handler.h"
24#elif defined(Q_OS_MAC)
25 #include "google-breakpad/src/client/mac/handler/exception_handler.h"
26#elif defined(Q_OS_WIN)
27 #include "google-breakpad/src/client/windows/handler/exception_handler.h"
28#endif
29
30#include <QDateTime>
31#include <QDir>
32#include <QFile>
33
34#include <QtDebug>
35
36BreakpadCrashHandler::BreakpadCrashHandler(const QString& outputDirectory)
37: m_exceptionHandler(0)
38, m_outputDir(outputDirectory)
39{
40 // create minidump output directory if it does not already exist
41 QDir(outputDirectory).mkpath(".");
42
43#if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
44 m_exceptionHandler = new google_breakpad::ExceptionHandler(
45 outputDirectory.toStdString(), /* minidump output directory */
46 0, /* filter */
47 0, /* minidump callback */
48 0, /* callback_context */
49 true /* install_handler */
50 );
51#elif defined(Q_OS_WIN)
52 m_exceptionHandler = new google_breakpad::ExceptionHandler(
53 outputDirectory.toStdWString(), /* minidump output directory */
54 0, /* filter */
55 0, /* minidump callback */
56 0, /* calback_context */
57 google_breakpad::ExceptionHandler::HANDLER_ALL /* handler_types */
58 );
59#endif
60}
61
62BreakpadCrashHandler::~BreakpadCrashHandler()
63{
64 delete m_exceptionHandler;
65}
66
67void BreakpadCrashHandler::removeOldMiniDumps(const QString& outputDirectory)
68{
69 QStringList minidumps = findMiniDumps(outputDirectory);
70 for (int i = 1; i < minidumps.count(); i++)
71 {
72 if (!QFile::remove(minidumps.at(i)))
73 {
74 qWarning() << "Unable to remove old minidump" << minidumps.at(i);
75 }
76 else
77 {
78 qDebug() << "removing old minidump" << minidumps.at(i);
79 }
80 }
81}
82
83QString BreakpadCrashHandler::mostRecentMiniDump(const QString& outputDirectoryPath)
84{
85 QStringList minidumps = findMiniDumps(outputDirectoryPath);
86 if (!minidumps.isEmpty())
87 {
88 qDebug() << "newest minidump" << minidumps.first();
89 return minidumps.first();
90 }
91 else
92 {
93 return QString();
94 }
95}
96
97QStringList BreakpadCrashHandler::findMiniDumps(const QString& outputDirectoryPath)
98{
99 QStringList minidumpPaths;
100 QDir outputDir(outputDirectoryPath);
101 Q_FOREACH(const QFileInfo& fileInfo, outputDir.entryInfoList(QStringList() << "*.dmp",QDir::NoFilter,QDir::Time))
102 {
103 qDebug() << "checking minidump file" << fileInfo.absoluteFilePath() << fileInfo.lastModified();
104 if (isValidMiniDump(fileInfo.absoluteFilePath()))
105 {
106 minidumpPaths.append(fileInfo.absoluteFilePath());
107 }
108 }
109 return minidumpPaths;
110}
111
112bool BreakpadCrashHandler::isValidMiniDump(const QString& filePath)
113{
114 QFile dumpFile(filePath);
115 if (dumpFile.open(QIODevice::ReadOnly))
116 {
117 QByteArray mimeMagic = dumpFile.read(4);
118 if (mimeMagic == "MDMP")
119 {
120 return true;
121 }
122 else
123 {
124 return false;
125 }
126 }
127 else
128 {
129 return false;
130 }
131}
  
1#pragma once
2/*
3 Hooq: Qt4 UI recording, playback, and testing toolkit.
4 Copyright (C) 2010 Mendeley Limited <copyright@mendeley.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20///@author Robert Knight <robert.knight@mendeley.com>
21
22#include <QString>
23
24namespace google_breakpad
25{
26 class ExceptionHandler;
27}
28
29/** Crash handler which installs platform-specific hooks to catch
30 * application crashes and create 'minidump' files containing
31 * a description of the program state.
32 *
33 * See http://code.google.com/p/google-breakpad/ for information on
34 * interpreting the minidump files which are created.
35 *
36 * To use BreakpadCrashHandler, construct an instance of it early in
37 * your application lifecycle (eg. in main()) which is destroyed just
38 * before a normal application exit.
39 */
40class BreakpadCrashHandler
41{
42 public:
43 /** Construct a crash handler and install hooks to catch
44 * application crashes. Upon a crash, a minidump file
45 * will be created in @p outputDirectory with the name
46 * <random UUID>.dmp
47 */
48 BreakpadCrashHandler(const QString& outputDirectory);
49 ~BreakpadCrashHandler();
50
51 /** Returns the absolute file path of the most recent valid
52 * minidump file in @p outputDirectory
53 */
54 static QString mostRecentMiniDump(const QString& outputDirectory);
55
56 /** Removes all valid minidump files in @p outputDirectory,
57 * except the most recent one.
58 */
59 static void removeOldMiniDumps(const QString& outputDirectory);
60
61
62 private:
63 static bool isValidMiniDump(const QString& filePath);
64 // return a list of all valid minidump files in 'outputDirectory'
65 // sorted by last modified time (most recent first)
66 static QStringList findMiniDumps(const QString& outputDirectory);
67
68 google_breakpad::ExceptionHandler* m_exceptionHandler;
69 QString m_outputDir;
70};
  
8686 XmlToQtScript_StringVariablesPostProcessor.cpp \
8787 main.cpp \
8888
89CONFIG(debug, debug|release) {
90 INCLUDEPATH += ..
91 HEADERS += BreakpadCrashHandler.h
92 SOURCES += BreakpadCrashHandler.cpp
93 DEFINES += WITH_BREAKPAD
94}
95
8996unix {
9097 include("../install.pri")
9198 target.path = /${DESTDIR}$$BINDIR
9299 INSTALLS += target
100 CONFIG(debug, debug|release) {
101 LIBS += -L../google-breakpad -lbreakpad
102 }
93103}
94104
95105win32 {
  
2121
2222#include <QApplication>
2323
24#ifdef WITH_BREAKPAD
25#include "BreakpadCrashHandler.h"
26#include <QDesktopServices>
27#endif
28
2429int main(int argc, char** argv)
2530{
2631 QApplication app(argc, argv);
3434 app.setApplicationVersion("0.1");
3535 app.setOrganizationDomain("hooq.org");
3636 app.setOrganizationName("Hooq Developers");
37
38#ifdef WITH_BREAKPAD
39 BreakpadCrashHandler handler(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation) + "/hooq-crashes");
40#endif
3741
3842 MainWindow window;
3943 window.show();