This commit is contained in:
John Preston 2016-01-31 21:01:05 +03:00
commit dd26de7dd2
6 changed files with 129 additions and 28 deletions

View File

@ -126,8 +126,7 @@ void AboutBox::dragEnterEvent(QDragEnterEvent *e) {
void AboutBox::dropEvent(QDropEvent *e) {
if (!_getCrashReportFile(e->mimeData()).isEmpty()) {
e->acceptProposedAction();
psExecTelegram(_getCrashReportFile(e->mimeData()));
App::quit();
psShowCrash(_getCrashReportFile(e->mimeData()));
}
}
@ -142,4 +141,4 @@ QString telegramFaqLink() {
}
}
return result;
}
}

View File

@ -708,41 +708,47 @@ namespace SignalHandlers {
#if defined Q_OS_MAC || defined Q_OS_LINUX32 || defined Q_OS_LINUX64
ucontext_t *uc = (ucontext_t*)ucontext;
void *addresses[128] = { 0 };
void *caller = 0;
#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6)
/* OSX < 10.6 */
#if defined(__x86_64__)
caller = (void*)uap->uc_mcontext->__ss.__rip;
caller = (void*)uc->uc_mcontext->__ss.__rip;
#elif defined(__i386__)
caller = (void*)uap->uc_mcontext->__ss.__eip;
caller = (void*)uc->uc_mcontext->__ss.__eip;
#else
caller = (void*)uap->uc_mcontext->__ss.__srr0;
caller = (void*)uc->uc_mcontext->__ss.__srr0;
#endif
#elif defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)
/* OSX >= 10.6 */
#if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__)
caller = (void*)uc->uc_mcontext->__ss.__rip;
#else
caller = (void*)uap->uc_mcontext->__ss.__eip;
caller = (void*)uc->uc_mcontext->__ss.__eip;
#endif
#elif defined(__linux__)
/* Linux */
#if defined(__i386__)
caller = (void*)uap->uc_mcontext.gregs[14]; /* Linux 32 */
caller = (void*)uc->uc_mcontext.gregs[14]; /* Linux 32 */
#elif defined(__X86_64__) || defined(__x86_64__)
caller = (void*)uap->uc_mcontext.gregs[16]; /* Linux 64 */
caller = (void*)uc->uc_mcontext.gregs[16]; /* Linux 64 */
#elif defined(__ia64__) /* Linux IA64 */
caller = (void*)uap->uc_mcontext.sc_ip;
caller = (void*)uc->uc_mcontext.sc_ip;
#endif
#endif
void *addresses[132] = { 0 };
size_t size = backtrace(addresses, 128);
/* overwrite sigaction with caller's address */
if (caller) addresses[1] = caller;
if (caller) {
for (int i = size; i > 1; --i) {
addresses[i + 3] = addresses[i];
}
addresses[2] = (void*)0x1;
addresses[3] = caller;
addresses[4] = (void*)0x1;
}
#ifdef Q_OS_MAC
dump() << "\nBase image addresses:\n";

View File

@ -979,6 +979,8 @@ void psWriteDump() {
}
QString demanglestr(const QString &mangled) {
if (mangled.isEmpty()) return mangled;
QByteArray cmd = ("c++filt -n " + mangled).toUtf8();
FILE *f = popen(cmd.constData(), "r");
if (!f) return "BAD_SYMBOL_" + mangled;
@ -994,6 +996,51 @@ QString demanglestr(const QString &mangled) {
return result.trimmed();
}
QStringList addr2linestr(uint64 *addresses, int count) {
QStringList result;
if (!count) return result;
result.reserve(count);
QString cmdstr = "addr2line -e " + escapeShell(cExeDir() + cExeName());
for (int i = 0; i < count; ++i) {
if (addresses[i]) {
cmdstr += qsl(" 0x%1").arg(addresses[i], 0, 16);
}
}
QByteArray cmd = cmdstr.toUtf8();
FILE *f = popen(cmd.constData(), "r");
QStringList addr2lineResult;
if (f) {
char buffer[4096] = {0};
while (!feof(f)) {
if (fgets(buffer, 4096, f) != NULL) {
addr2lineResult.push_back(QString::fromUtf8(buffer));
}
}
pclose(f);
}
for (int i = 0, j = 0; i < count; ++i) {
if (addresses[i]) {
if (j < addr2lineResult.size() && !addr2lineResult.at(j).isEmpty() && !addr2lineResult.at(j).startsWith(qstr("0x"))) {
QString res = addr2lineResult.at(j).trimmed();
if (int index = res.indexOf(qstr("/Telegram/"))) {
if (index > 0) {
res = res.mid(index + qstr("/Telegram/").size());
}
}
result.push_back(res);
} else {
result.push_back(QString());
}
++j;
} else {
result.push_back(QString());
}
}
return result;
}
QString _showCrashDump(const QByteArray &crashdump, QString dumpfile) {
QString initial = QString::fromUtf8(crashdump), result;
QStringList lines = initial.split('\n');
@ -1001,6 +1048,7 @@ QString _showCrashDump(const QByteArray &crashdump, QString dumpfile) {
int32 i = 0, l = lines.size();
while (i < l) {
uint64 addresses[1024] = { 0 };
for (; i < l; ++i) {
result.append(lines.at(i)).append('\n');
QString line = lines.at(i).trimmed();
@ -1010,21 +1058,59 @@ QString _showCrashDump(const QByteArray &crashdump, QString dumpfile) {
}
}
for (int32 start = i; i < l; ++i) {
int32 start = i;
for (; i < l; ++i) {
QString line = lines.at(i).trimmed();
if (line.isEmpty()) break;
QRegularExpressionMatch m1 = QRegularExpression(qsl("^(.+)\\(([^+]+)\\+([^\\)]+)\\)\\[(.+)\\]$")).match(line);
QRegularExpressionMatch m2 = QRegularExpression(qsl("^(.+)\\[(.+)\\]$")).match(line);
QString addrstr = m1.hasMatch() ? m1.captured(4) : (m2.hasMatch() ? m2.captured(2) : QString());
if (!addrstr.isEmpty()) {
uint64 addr = addrstr.startsWith(qstr("0x")) ? addrstr.mid(2).toULongLong(0, 16) : addrstr.toULongLong();
if (addr > 1) {
addresses[i - start] = addr;
}
}
}
QStringList addr2line = addr2linestr(addresses, i - start);
for (i = start; i < l; ++i) {
QString line = lines.at(i).trimmed();
if (line.isEmpty()) break;
result.append(qsl("%1. ").arg(i + 1 - start));
result.append(qsl("\n%1. ").arg(i - start));
if (line.startsWith(qstr("ERROR: "))) {
result.append(line).append('\n');
continue;
}
QRegularExpressionMatch m = QRegularExpression(qsl("^(.+)\\(([^+]+)\\+([^\\)]+)\\)(.+)$")).match(line);
if (!m.hasMatch()) {
if (line == qstr("[0x1]")) {
result.append(qsl("(0x1 separator)\n"));
continue;
}
QRegularExpressionMatch m1 = QRegularExpression(qsl("^(.+)\\(([^+]*)\\+([^\\)]+)\\)(.+)$")).match(line);
QRegularExpressionMatch m2 = QRegularExpression(qsl("^(.+)\\[(.+)\\]$")).match(line);
if (!m1.hasMatch() && !m2.hasMatch()) {
result.append(qstr("BAD LINE: ")).append(line).append('\n');
continue;
}
result.append(demanglestr(m.captured(2))).append(qsl(" + ")).append(m.captured(3)).append(qsl(" (")).append(m.captured(1)).append(qsl(") ")).append(m.captured(4)).append('\n');
if (m1.hasMatch()) {
result.append(demanglestr(m1.captured(2))).append(qsl(" + ")).append(m1.captured(3)).append(qsl(" [")).append(m1.captured(1)).append(qsl("] "));
if (!addr2line.at(i - start).isEmpty() && addr2line.at(i - start) != qsl("??:0")) {
result.append(qsl(" (")).append(addr2line.at(i - start)).append(qsl(")\n"));
} else {
result.append(m1.captured(4)).append(qsl(" (demangled)")).append('\n');
}
} else {
result.append('[').append(m2.captured(1)).append(']');
if (!addr2line.at(i - start).isEmpty() && addr2line.at(i - start) != qsl("??:0")) {
result.append(qsl(" (")).append(addr2line.at(i - start)).append(qsl(")\n"));
} else {
result.append(' ').append(m2.captured(2)).append('\n');
}
}
}
}
return result;
@ -1041,13 +1127,18 @@ int psShowCrash(const QString &crashdump) {
text = qsl("ERROR: could not read crash dump file '%1'").arg(QFileInfo(crashdump).absoluteFilePath());
}
QByteArray args[] = { "" };
int a_argc = 1;
char *a_argv[1] = { args[0].data() };
QApplication app(a_argc, a_argv);
if (Sandbox::started()) {
ShowCrashReportWindow *wnd = new ShowCrashReportWindow(text);
return 0;
}
ShowCrashReportWindow wnd(text);
return app.exec();
QByteArray args[] = { "" };
int a_argc = 1;
char *a_argv[1] = { args[0].data() };
QApplication app(a_argc, a_argv);
ShowCrashReportWindow *wnd = new ShowCrashReportWindow(text);
return app.exec();
}
bool _removeDirectory(const QString &path) { // from http://stackoverflow.com/questions/2256945/removing-a-non-empty-directory-programmatically-in-c-or-c

View File

@ -2113,7 +2113,7 @@ void LastCrashedWindow::onViewReport() {
}
void LastCrashedWindow::onSaveReport() {
QString to = QFileDialog::getSaveFileName(0, qsl("Telegram Crash Report"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + qsl("/report"), qsl("Telegram crash report (*.telegramcrash)"));
QString to = QFileDialog::getSaveFileName(0, qsl("Telegram Crash Report"), QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + qsl("/report.telegramcrash"), qsl("Telegram crash report (*.telegramcrash)"));
if (!to.isEmpty()) {
QFile file(to);
if (file.open(QIODevice::WriteOnly)) {
@ -2874,3 +2874,7 @@ ShowCrashReportWindow::ShowCrashReportWindow(const QString &text)
void ShowCrashReportWindow::resizeEvent(QResizeEvent *e) {
_log.setGeometry(rect().marginsRemoved(QMargins(basicSize(), basicSize(), basicSize(), basicSize())));
}
void ShowCrashReportWindow::closeEvent(QCloseEvent *e) {
deleteLater();
}

View File

@ -547,6 +547,7 @@ public:
protected:
void resizeEvent(QResizeEvent *e);
void closeEvent(QCloseEvent *e);
private:

View File

@ -281,12 +281,12 @@ QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-result -Wno-unused-parameter -Wno-unused-v
CONFIG(release, debug|release) {
QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_CXXFLAGS_RELEASE += -Ofast -flto -fno-strict-aliasing
QMAKE_CXXFLAGS_RELEASE += -Ofast -flto -fno-strict-aliasing -g
QMAKE_LFLAGS_RELEASE -= -O1
QMAKE_LFLAGS_RELEASE += -Ofast -flto -rdynamic
QMAKE_LFLAGS_RELEASE += -Ofast -flto -rdynamic -g
}
CONFIG(debug, debug|release) {
QMAKE_LFLAGS_DEBUG += -rdynamic
QMAKE_LFLAGS_DEBUG += -rdynamic -g
}
INCLUDEPATH += ./../../Libraries/QtStatic/qtbase/include/QtGui/5.5.1/QtGui\