Vidalia 0.3.1
crashreporter/main.cpp
Go to the documentation of this file.
1/*
2** This file is part of Vidalia, and is subject to the license terms in the
3** LICENSE file, found in the top level directory of this distribution. If you
4** did not receive the LICENSE file with this file, you may obtain it from the
5** Vidalia source package distributed by the Vidalia Project at
6** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7** including this file, may be copied, modified, propagated, or distributed
8** except according to the terms described in the LICENSE file.
9*/
10
11/*
12** \file main.cpp
13** \brief Application that is run after Vidalia crashes and asks the
14** user if they would like to submit the crash report.
15*/
16
17#include "CrashReportDialog.h"
18
19#include <QApplication>
20#include <QFileInfo>
21#include <QMessageBox>
22#include <QTextStream>
23#include <QTextCodec>
24
25/** Read the crash dump annotations file given by <b>fileName</b> and parse
26 * each line into a Key=Value pair. Returns a QHash containing the keys
27 * mapped to their values on success. If a file or parse error occurs, this
28 * returns a default-constructed QHash and sets <b>errorMessage</b> to a
29 * string describing the error encountered.
30 */
31QHash<QString,QString>
32read_annotations_file(const QString &fileName, QString &errorMessage)
33{
34 QHash<QString, QString> annotations;
35
36 /* Open the annotations file for reading text */
37 QFile infile(fileName);
38 if (! infile.open(QIODevice::ReadOnly | QIODevice::Text)) {
39 errorMessage = infile.errorString();
40 return QHash<QString,QString>();
41 }
42
43 /* The annotations file should be UTF-8 encoded */
44 QTextStream reader(&infile);
45 reader.setCodec(QTextCodec::codecForName("utf-8"));
46 while (! reader.atEnd()) {
47 QString line = reader.readLine().trimmed();
48 if (line.isEmpty())
49 continue;
50
51 int idx = line.indexOf("=");
52 if (idx > 0 && idx < line.length()-1) {
53 QString key = line.mid(0, idx).trimmed();
54 QString val = line.mid(idx + 1).trimmed();
55 annotations.insert(key, val);
56 }
57 }
58 return annotations;
59}
60
61int
62main(int argc, char *argv[])
63{
64 QApplication app(argc, argv);
65 CrashReportDialog crashDialog;
66 QFileInfo minidumpFile, extraInfoFile;
67 QString minidumpFilePath, extraInfoFilePath, errorMessage;
68 QHash<QString,QString> annotations;
69
70 if (argc < 2) {
71 errorMessage = "No minidump file specified.";
72 goto err;
73 }
74
75 /* Ensure that the specified minidump file exists and is readable */
76 minidumpFile = QFileInfo(argv[1]);
77 minidumpFilePath = minidumpFile.absoluteFilePath();
78 if (! minidumpFile.exists() || ! minidumpFile.size()) {
79 errorMessage = QString("The specified minidump file does not exist: %1")
80 .arg(minidumpFilePath);
81 goto err;
82 }
83 if (! minidumpFile.isReadable()) {
84 errorMessage = QString("The specified minidump file is not readable: %1")
85 .arg(minidumpFilePath);
86 goto err;
87 }
88
89 /* Ensure that the specified minidump has an associated extra crash
90 * information file that exists and is readable. */
91 extraInfoFile = QFileInfo(minidumpFilePath + ".info");
92 extraInfoFilePath = extraInfoFile.absoluteFilePath();
93 if (! extraInfoFile.exists() || ! extraInfoFile.size()) {
94 errorMessage = QString("The specified minidump does not have a "
95 "corresponding crash annotations file: %1")
96 .arg(extraInfoFilePath);
97 goto err;
98 }
99 if (! extraInfoFile.isReadable()) {
100 errorMessage = QString("The specified crash information file is not "
101 "readable: %1").arg(extraInfoFilePath);
102 goto err;
103 }
104
105 /* Read and parse the crash annotations file */
106 annotations = read_annotations_file(extraInfoFilePath, errorMessage);
107 if (annotations.isEmpty()) {
108 errorMessage = QString("Unable to read crash annotations file '%1': %2")
109 .arg(extraInfoFilePath)
110 .arg(errorMessage);
111 goto err;
112 }
113
114 /* Display the crash reporting dialog */
115 crashDialog.setCrashAnnotations(annotations);
116 crashDialog.setMinidumpFiles(minidumpFilePath, extraInfoFilePath);
117 crashDialog.show();
118 return app.exec();
119
120err:
121 /* We encountered an error trying to load the minidump or extra crash
122 * information file. So, display an error and then bail, since now there's
123 * nothing for us to send. */
124 QMessageBox dlg;
125 dlg.setWindowIcon(QIcon(":/images/32x32/tools-report-bug.png"));
126 dlg.setWindowTitle("Crash Reporter Error");
127
128 dlg.setIconPixmap(QPixmap(":/images/64x64/tools-report-bug.png"));
129 dlg.setStandardButtons(QMessageBox::Ok);
130
131 dlg.setText("<b>Vidalia encountered an error and needed to close</b>");
132 dlg.setInformativeText(
133 "<p>Vidalia attempted to automatically create an error report to "
134 "help diagnose the problem, but was unable to do so. Please report "
135 "this problem, along with what you were doing before Vidalia crashed, "
136 "to the developers at:</p><p>"
137 "<a href=\"https://trac.torproject.org/projects/tor/newticket\">"
138 "https://trac.torproject.org/projects/tor/newticket</a></p> "
139 "<p>Click \"Show Details\" below for information about the problem "
140 "encountered.");
141
142 dlg.setDetailedText(errorMessage);
143 return dlg.exec();
144}
void setCrashAnnotations(const QHash< QString, QString > &annotations)
void setMinidumpFiles(const QString &minidump, const QString &annotations)
int main(int argc, char *argv[])
QHash< QString, QString > read_annotations_file(const QString &fileName, QString &errorMessage)
bool err(QString *str, const QString &errmsg)
Definition: stringutil.cpp:37