diff --git a/Telegram/SourceFiles/logs.cpp b/Telegram/SourceFiles/logs.cpp index a3cb642ea7..641c7fd576 100644 --- a/Telegram/SourceFiles/logs.cpp +++ b/Telegram/SourceFiles/logs.cpp @@ -19,7 +19,7 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org */ #include "stdafx.h" -#include +#include #include "pspecific.h" // see https://blog.inventic.eu/2012/08/qt-and-google-breakpad/ @@ -606,6 +606,19 @@ namespace SignalHandlers { return stream; } + const dump &operator<<(const dump &stream, const wchar_t *str) { + if (!CrashDumpFile) return stream; + + for (int i = 0, l = wcslen(str); i < l; ++i) { + if (str[i] >= 0 && str[i] < 128) { + _writeChar(char(str[i])); + } else { + _writeChar('?'); + } + } + return stream; + } + template const dump &_writeNumber(const dump &stream, Type number) { if (!CrashDumpFile) return stream; @@ -667,7 +680,9 @@ namespace SignalHandlers { typedef std::map AnnotationsMap; AnnotationsMap ProcessAnnotations; -// see https://github.com/benbjohnson/bandicoot + const char *BreakpadDumpPath = 0; + const wchar_t *BreakpadDumpPathW = 0; + #if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64 struct sigaction SIG_def[32]; @@ -710,10 +725,16 @@ namespace SignalHandlers { dump() << "Caught signal " << signum << " (" << name << ") in thread " << uint64(thread) << "\n"; } else if (signum == -1) { dump() << "Google Breakpad caught a crash, minidump written in thread " << uint64(thread) << "\n"; + if (BreakpadDumpPath) { + dump() << "Minidump: " << BreakpadDumpPath << "\n"; + } else if (BreakpadDumpPathW) { + dump() << "Minidump: " << BreakpadDumpPathW << "\n"; + } } else { dump() << "Caught signal " << signum << " in thread " << uint64(thread) << "\n"; } + // see https://github.com/benbjohnson/bandicoot #if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64 ucontext_t *uc = (ucontext_t*)ucontext; @@ -801,7 +822,18 @@ namespace SignalHandlers { bool DumpCallback(const google_breakpad::MinidumpDescriptor &md, void *context, bool success) #endif { +#ifdef Q_OS_WIN + BreakpadDumpPathW = _minidump_id; + Handler(-1); +#else + +#ifdef Q_OS_MAC + BreakpadDumpPath = _minidump_id; +#else + BreakpadDumpPath = md.path(); +#endif Handler(-1, 0, 0); +#endif return success; } #endif diff --git a/Telegram/SourceFiles/logs.h b/Telegram/SourceFiles/logs.h index 9deebadb1c..e8e2c99984 100644 --- a/Telegram/SourceFiles/logs.h +++ b/Telegram/SourceFiles/logs.h @@ -92,6 +92,7 @@ namespace SignalHandlers { ~dump(); }; const dump &operator<<(const dump &stream, const char *str); + const dump &operator<<(const dump &stream, const wchar_t *str); const dump &operator<<(const dump &stream, int num); const dump &operator<<(const dump &stream, unsigned int num); const dump &operator<<(const dump &stream, unsigned long num); diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index f23b0a5a33..6525b79dde 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -2018,32 +2018,49 @@ LastCrashedWindow::LastCrashedWindow() { if (_sendingState != SendingNoReport) { - QString maxDump, maxDumpFull; - QDateTime maxDumpModified, workingModified = QFileInfo(cWorkingDir() + qsl("tdata/working")).lastModified(); - qint64 maxDumpSize = 0; + qint64 dumpsize = 0; QString dumpspath = cWorkingDir() + qsl("tdata/dumps"); #if defined Q_OS_MAC && !defined MAC_USE_BREAKPAD dumpspath += qsl("/completed"); #endif - QFileInfoList list = QDir(dumpspath).entryInfoList(); - for (int32 i = 0, l = list.size(); i < l; ++i) { - QString name = list.at(i).fileName(); - if (name.endsWith(qstr(".dmp"))) { - QDateTime modified = list.at(i).lastModified(); - if (maxDump.isEmpty() || qAbs(workingModified.secsTo(modified)) < qAbs(workingModified.secsTo(maxDumpModified))) { - maxDump = name; - maxDumpModified = modified; - maxDumpFull = list.at(i).absoluteFilePath(); - maxDumpSize = list.at(i).size(); - } + QString possibleDump = getReportField(qstr("minidump"), qstr("Minidump:")); + if (!possibleDump.isEmpty()) { + if (!possibleDump.startsWith('/')) { + possibleDump = dumpspath + '/' + possibleDump; + } + if (!possibleDump.endsWith('.dmp')) { + possibleDump += qsl(".dmp"); + } + QFileInfo possibleInfo(possibleDump); + if (possibleInfo.exists()) { + _minidumpName = possibleInfo.fileName(); + _minidumpFull = possibleInfo.absoluteFilePath(); + dumpsize = possibleInfo.size(); } } - if (!maxDump.isEmpty() && qAbs(workingModified.secsTo(maxDumpModified)) < 10) { - _minidumpName = maxDump; - _minidumpFull = maxDumpFull; - } + if (_minidumpFull.isEmpty()) { + QString maxDump, maxDumpFull; + QDateTime maxDumpModified, workingModified = QFileInfo(cWorkingDir() + qsl("tdata/working")).lastModified(); + QFileInfoList list = QDir(dumpspath).entryInfoList(); + for (int32 i = 0, l = list.size(); i < l; ++i) { + QString name = list.at(i).fileName(); + if (name.endsWith(qstr(".dmp"))) { + QDateTime modified = list.at(i).lastModified(); + if (maxDump.isEmpty() || qAbs(workingModified.secsTo(modified)) < qAbs(workingModified.secsTo(maxDumpModified))) { + maxDump = name; + maxDumpModified = modified; + maxDumpFull = list.at(i).absoluteFilePath(); + dumpsize = list.at(i).size(); + } + } + } + if (!maxDump.isEmpty() && qAbs(workingModified.secsTo(maxDumpModified)) < 10) { + _minidumpName = maxDump; + _minidumpFull = maxDumpFull; + } + } - _minidump.setText(qsl("+ %1 (%2 KB)").arg(_minidumpName).arg(maxDumpSize / 1024)); + _minidump.setText(qsl("+ %1 (%2 KB)").arg(_minidumpName).arg(dumpsize / 1024)); } _networkSettings.setText(qsl("NETWORK SETTINGS"));