Skip to content

Commit 3ec217f

Browse files
committed
breakdown WIP (include stackwalker)
1 parent 3e5e5d4 commit 3ec217f

File tree

5 files changed

+1335
-72
lines changed

5 files changed

+1335
-72
lines changed

CMakeLists.txt

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ add_executable(
8383
${BREAKDOWN}/breakdown.cpp
8484
${BREAKDOWN}/breakdown.ui
8585
)
86-
add_executable(
87-
stackwalker
88-
${STACKWALKER}/http_symbol_supplier.cc
89-
${STACKWALKER}/stackwalker.cc
90-
)
86+
#add_executable(
87+
# stackwalker
88+
# ${STACKWALKER}/http_symbol_supplier.cc
89+
# ${STACKWALKER}/stackwalker.cc
90+
#)
9191

9292
target_link_libraries(
9393
breakdown
@@ -101,11 +101,11 @@ target_link_libraries(
101101
${JSON_LIBRARIES}
102102
)
103103

104-
target_link_libraries(
105-
stackwalker
106-
${BREAKPAD_BIN}/src/libbreakpad.a
107-
${BREAKPAD_BIN}/src/third_party/libdisasm/libdisasm.a
108-
${CURL_LIBRARIES}
109-
${ZIP_LIBRARIES}
110-
${JSON_LIBRARIES}
111-
)
104+
#target_link_libraries(
105+
# stackwalker
106+
# ${BREAKPAD_BIN}/src/libbreakpad.a
107+
# ${BREAKPAD_BIN}/src/third_party/libdisasm/libdisasm.a
108+
# ${CURL_LIBRARIES}
109+
# ${ZIP_LIBRARIES}
110+
# ${JSON_LIBRARIES}
111+
#)

breakdown/CMakeLists.txt

Lines changed: 0 additions & 51 deletions
This file was deleted.

breakdown/breakdown.cpp

Lines changed: 125 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@
3030
#include <QDesktopServices>
3131
#include <QMessageBox>
3232
#include <QSettings>
33+
#include <QMimeDatabase>
34+
#include <QMimeType>
35+
#include <QDebug>
36+
37+
#include "stackwalker.h"
3338

3439
BreakDown::BreakDown(QWidget *parent) :
3540
QMainWindow(parent),
@@ -142,8 +147,13 @@ void BreakDown::openJsonFile(const QString &file)
142147
if (!jsonFile.open(QIODevice::ReadOnly|QIODevice::Text)) { return; }
143148
QString rawJson = jsonFile.readAll();
144149
jsonFile.close();
150+
if (!rawJson.isEmpty()) { openJsonString(rawJson); }
151+
}
145152

146-
QJsonDocument doc(QJsonDocument::fromJson(rawJson.toUtf8()));
153+
void BreakDown::openJsonString(const QString json, const QString customID)
154+
{
155+
if (json.isEmpty()) { return; }
156+
QJsonDocument doc(QJsonDocument::fromJson(json.toUtf8()));
147157
if (doc.isEmpty() || doc.isNull()) { return; }
148158
QJsonObject obj = doc.object();
149159

@@ -157,6 +167,7 @@ void BreakDown::openJsonFile(const QString &file)
157167
QJsonObject system_info_item = system_info.toObject();
158168

159169
QString uuid = obj.value(QString("uuid")).toString();
170+
if (uuid.isEmpty() && !customID.isEmpty()) { uuid = customID; }
160171
QString timestamp = obj.value(QString("submitted_timestamp")).toString();
161172
QString comment = obj.value(QString("Comments")).toString();
162173
QString git_commit = obj.value(QString("git_commit")).toString();
@@ -309,18 +320,124 @@ void BreakDown::openJsonFile(const QString &file)
309320
}
310321
}
311322

323+
void BreakDown::openDumpFile(const QString &file)
324+
{
325+
vector<string> server_path;
326+
vector<string> symbol_paths;
327+
328+
// TODO: settings (also remember cache and tmp!!!)
329+
server_path.push_back("https://stackwalker.000webhostapp.com/symbols");
330+
331+
Minidump minidump(file.toStdString());
332+
minidump.Read();
333+
334+
Json::Value root;
335+
scoped_ptr<SymbolSupplier> symbol_supplier;
336+
HTTPSymbolSupplier* http_symbol_supplier = nullptr;
337+
if (!server_path.empty()) {
338+
http_symbol_supplier = new HTTPSymbolSupplier(server_path,
339+
QDir::tempPath().toStdString(),
340+
symbol_paths,
341+
QDir::tempPath().toStdString());
342+
symbol_supplier.reset(http_symbol_supplier);
343+
} else if (!symbol_paths.empty()) {
344+
symbol_supplier.reset(new SimpleSymbolSupplier(symbol_paths));
345+
}
346+
347+
BasicSourceLineResolver resolver;
348+
StackFrameSymbolizerForward symbolizer(symbol_supplier.get(), &resolver);
349+
MinidumpProcessor minidump_processor(&symbolizer, true);
350+
ProcessState process_state;
351+
ProcessResult result = minidump_processor.Process(&minidump, &process_state);
352+
353+
if (result != google_breakpad::PROCESS_OK) {
354+
string failed = ResultString(result);
355+
QMessageBox::warning(this,
356+
tr("Failed to process minidump"),
357+
QString::fromStdString(failed));
358+
return;
359+
}
360+
361+
Json::Value raw_root(Json::objectValue);
362+
363+
root["status"] = ResultString(result);
364+
root["sensitive"] = Json::Value(Json::objectValue);
365+
if (result == google_breakpad::PROCESS_OK) {
366+
ConvertProcessStateToJSON(process_state,
367+
symbolizer,
368+
http_symbol_supplier,
369+
root,
370+
raw_root);
371+
} else {
372+
QMessageBox::warning(this,
373+
tr("Failed to process minidump"),
374+
QString::fromStdString(ResultString(result)));
375+
}
376+
ConvertMemoryInfoToJSON(minidump, raw_root, root);
377+
378+
// Get the PID.
379+
MinidumpMiscInfo* misc_info = minidump.GetMiscInfo();
380+
if (misc_info && misc_info->misc_info() &&
381+
(misc_info->misc_info()->flags1 & MD_MISCINFO_FLAGS1_PROCESS_ID))
382+
{
383+
root["pid"] = misc_info->misc_info()->process_id;
384+
}
385+
386+
// See if this is a Linux dump with /proc/cpuinfo in it
387+
uint32_t cpuinfo_length = 0;
388+
if (process_state.system_info()->os == "Linux" &&
389+
minidump.SeekToStreamType(MD_LINUX_CPU_INFO, &cpuinfo_length))
390+
{
391+
string contents;
392+
contents.resize(cpuinfo_length);
393+
if (minidump.ReadBytes(const_cast<char*>(contents.data()), cpuinfo_length)) {
394+
ConvertCPUInfoToJSON(contents, root);
395+
}
396+
}
397+
398+
// See if this is a Linux dump with /etc/lsb-release in it
399+
uint32_t length = 0;
400+
if (process_state.system_info()->os == "Linux" &&
401+
minidump.SeekToStreamType(MD_LINUX_LSB_RELEASE, &length))
402+
{
403+
string contents;
404+
contents.resize(length);
405+
if (minidump.ReadBytes(const_cast<char*>(contents.data()), length)) {
406+
ConvertLSBReleaseToJSON(contents, root);
407+
}
408+
}
409+
410+
scoped_ptr<Json::Writer> writer;
411+
writer.reset(new Json::StyledWriter());
412+
string json = writer->write(root);
413+
414+
if (!json.empty()) {
415+
QFileInfo info(file);
416+
openJsonString(QString::fromStdString(json), info.baseName());
417+
}
418+
}
419+
312420
void BreakDown::on_actionQuit_triggered()
313421
{
314422
qApp->quit();
315423
}
316424

317425
void BreakDown::on_actionOpen_triggered()
318426
{
319-
QString jsonFile = QFileDialog::getOpenFileName(this,
320-
tr("Open Stackwalker JSON or DMP"),
321-
QDir::homePath());
322-
if (jsonFile.isEmpty()) { return; }
323-
openJsonFile(jsonFile);
427+
QString file = QFileDialog::getOpenFileName(this,
428+
tr("Open Stackwalker JSON or Breakpad DMP"),
429+
QDir::homePath(),
430+
"*.json *.dmp");
431+
if (file.isEmpty()) { return; }
432+
433+
QMimeDatabase db;
434+
QMimeType type = db.mimeTypeForFile(file);
435+
436+
if (type.name() == "application/json") {
437+
openJsonFile(file);
438+
} else {
439+
openDumpFile(file);
440+
}
324441
}
325442

326443
void BreakDown::on_reportInfoCrashTree_itemDoubleClicked(QTreeWidgetItem *item, int column)
@@ -335,6 +452,6 @@ void BreakDown::on_actionAbout_triggered()
335452
QMessageBox::about(this,
336453
QString("%1 Breakdown").arg(tr("About")),
337454
QString("<h3>Breakdown</h3>"
338-
"<p>Parse crash reports from Stackwalker, designed for use with Natron.<p>"
339-
"<p>Copyright &copy; 2019 <a href=\"https://github.com/rodlie\">Ole-André Rodlie</a>.</p>"));
455+
"<p>Parse crash reports from Breakpad.<p>"
456+
"<p>Copyright &copy;2019 <a href=\"https://github.com/rodlie\">Ole-André Rodlie</a>.</p>"));
340457
}

breakdown/breakdown.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ private slots:
4343
void setLineEditCursorPosition();
4444
void clearReport();
4545
void openJsonFile(const QString &file);
46+
void openJsonString(const QString json, const QString customID = QString());
47+
void openDumpFile(const QString &file);
4648
void on_actionQuit_triggered();
4749
void on_actionOpen_triggered();
4850
void on_reportInfoCrashTree_itemDoubleClicked(QTreeWidgetItem *item, int column);

0 commit comments

Comments
 (0)