[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r3856: Read the minidump and parse/verify the crash annotations fil (vidalia/branches/breakpad/src/crashreporter)



Author: edmanm
Date: 2009-06-15 15:42:52 -0400 (Mon, 15 Jun 2009)
New Revision: 3856

Modified:
   vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.cpp
   vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.h
   vidalia/branches/breakpad/src/crashreporter/main.cpp
Log:

Read the minidump and parse/verify the crash annotations file when the
crash reporter starts up, and throw up an error message if either of
those fail. Pass the minidump contents and parsed key-value pairs from
the annotations file to the CrashReportDialog.


Modified: vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.cpp
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.cpp	2009-06-15 09:00:11 UTC (rev 3855)
+++ vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.cpp	2009-06-15 19:42:52 UTC (rev 3856)
@@ -21,7 +21,9 @@
 #include <QPushButton>
 
 
-CrashReportDialog::CrashReportDialog(QWidget *parent)
+CrashReportDialog::CrashReportDialog(const QByteArray &minidump,
+                                     const QHash<QString,QString> &annotations,
+                                     QWidget *parent)
   : QDialog(parent)
 {
   ui.setupUi(this);

Modified: vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.h
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.h	2009-06-15 09:00:11 UTC (rev 3855)
+++ vidalia/branches/breakpad/src/crashreporter/CrashReportDialog.h	2009-06-15 19:42:52 UTC (rev 3856)
@@ -18,7 +18,12 @@
 
 #include "ui_CrashReportDialog.h"
 
+#include <QHash>
 
+class QString;
+class QByteArray;
+
+
 class CrashReportDialog : public QDialog
 {
   Q_OBJECT
@@ -26,7 +31,9 @@
 public:
   /** Default constructor.
    */
-  CrashReportDialog(QWidget *parent = 0);
+  CrashReportDialog(const QByteArray &minidump,
+                    const QHash<QString,QString> &annotations,
+                    QWidget *parent = 0);
 
 private:
   /** Qt Designer created object. */

Modified: vidalia/branches/breakpad/src/crashreporter/main.cpp
===================================================================
--- vidalia/branches/breakpad/src/crashreporter/main.cpp	2009-06-15 09:00:11 UTC (rev 3855)
+++ vidalia/branches/breakpad/src/crashreporter/main.cpp	2009-06-15 19:42:52 UTC (rev 3856)
@@ -20,14 +20,81 @@
 #include <QApplication>
 #include <QFileInfo>
 #include <QMessageBox>
+#include <QTextStream>
+#include <QTextCodec>
 
 
+/** Open the minidump file  given by <b>fileName</b> and read its entire
+ * contents into a QByteArray. Returns the contents of the minidump file
+ * on success. If an error occurs, this returns a default-constructed
+ * QByteArray and sets <b>errorMessage</b> to a string describing the error
+ * ecountered.
+ */
+QByteArray
+read_minidump_file(const QString &fileName, QString &errorMessage)
+{
+  QByteArray md;
+  QFile mdFile(fileName);
+
+  if (! mdFile.open(QIODevice::ReadOnly)) {
+    errorMessage = mdFile.errorString();
+    return QByteArray();
+  }
+  while (! mdFile.atEnd()) {
+    md.append(mdFile.readAll());
+    if (mdFile.error() != QFile::NoError) {
+      errorMessage = mdFile.errorString();
+      return QByteArray();
+    }
+  }
+  mdFile.close();
+  return md;
+}
+
+/** Read the crash dump annotations file given by <b>fileName</b> and parse
+ * each line into a Key=Value pair. Returns a QHash containing the keys
+ * mapped to their values on success. If a file or parse error occurs, this
+ * returns a default-constructed QHash and sets <b>errorMessage</b> to a
+ * string describing the error encountered.
+ */
+QHash<QString,QString>
+read_annotations_file(const QString &fileName, QString &errorMessage)
+{
+  QHash<QString, QString> annotations;
+
+  /* Open the annotations file for reading text */
+  QFile infile(fileName);
+  if (! infile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+    errorMessage = infile.errorString();
+    return QHash<QString,QString>();
+  }
+
+  /* The annotations file should be UTF-8 encoded */
+  QTextStream reader(&infile);
+  reader.setCodec(QTextCodec::codecForName("utf-8"));
+  while (! infile.atEnd()) {
+    QString line = reader.readLine().trimmed();
+    if (line.isEmpty())
+      continue;
+
+    int idx = line.indexOf("=");
+    if (idx > 0 && idx < line.length()-1) {
+      QString key = line.mid(0, idx).trimmed();
+      QString val = line.mid(idx + 1).trimmed();
+      annotations.insert(key, val); 
+    }
+  }
+  return annotations;
+}
+
 int
 main(int argc, char *argv[])
 {
   QApplication app(argc, argv);
   QFileInfo minidumpFile, extraInfoFile;
-  QString errorMessage;
+  QString minidumpFileName, extraInfoFileName, errorMessage;
+  QHash<QString,QString> annotations;
+  QByteArray minidump;
 
   if (argc < 2) {
     errorMessage = "No minidump file specified.";
@@ -35,40 +102,59 @@
   }
 
   /* Ensure that the specified minidump file exists and is readable */
-  minidumpFile = QFileInfo(argv[1]);
+  minidumpFile     = QFileInfo(argv[1]);
+  minidumpFileName = minidumpFile.absoluteFilePath();
   if (! minidumpFile.exists() || ! minidumpFile.size()) {
     errorMessage = QString("The specified minidump file does not exist: %1")
-                                       .arg(minidumpFile.absoluteFilePath());
+                                                      .arg(minidumpFileName);
     goto err;
   }
   if (! minidumpFile.isReadable()) {
     errorMessage = QString("The specified minidump file is not readable: %1")
-                                        .arg(minidumpFile.absoluteFilePath());
+                                                       .arg(minidumpFileName);
     goto err;
   }
 
   /* Ensure that the specified minidump has an associated extra crash
    * information file that exists and is readable. */
-  extraInfoFile = QFileInfo(minidumpFile.absoluteFilePath() + ".info");
+  extraInfoFile     = QFileInfo(minidumpFileName + ".info");
+  extraInfoFileName = extraInfoFile.absoluteFilePath();
   if (! extraInfoFile.exists() || ! extraInfoFile.size()) {
     errorMessage = QString("The specified minidump does not have a "
-                           "corresponding crash information file: %1");
+                           "corresponding crash annotations file: %1")
+                                               .arg(extraInfoFileName);
     goto err;
   }
   if (! extraInfoFile.isReadable()) {
     errorMessage = QString("The specified crash information file is not "
-                           "readable: %1").arg(extraInfoFile.absoluteFilePath());
+                           "readable: %1").arg(extraInfoFileName);
     goto err;
   }
 
+  /* Read the minidump file's contents */
+  minidump = read_minidump_file(minidumpFileName, errorMessage);
+  if (minidump.isNull()) {
+    errorMessage = QString("Unable to read minidump file '%1': %2")
+                                             .arg(minidumpFileName)
+                                             .arg(errorMessage);
+    goto err;
+  }
+  /* Read and parse the crash annotations file */
+  annotations = read_annotations_file(extraInfoFileName, errorMessage);
+  if (annotations.isEmpty()) {
+    errorMessage = QString("Unable to read crash annotations file '%1': %2")
+                                                     .arg(extraInfoFileName)
+                                                     .arg(errorMessage);
+    goto err;
+  }
+
   /* Display the crash reporting dialog */
   {
-    CrashReportDialog dlg;
+    CrashReportDialog dlg(minidump, annotations);
     dlg.show();
+    return app.exec();
   }
 
-  return app.exec();
-
 err:
   /* We encountered an error trying to load the minidump or extra crash
    * information file. So, display an error and then bail, since now there's