Fix incorrect crash report hash calculation

Allow saving of an offline crash report for later upload if crash reporting server is unavailable
pull/2/head
Timothy Pearson 11 years ago
parent 39808986b1
commit de1901f3ab

@ -29,16 +29,18 @@
#include <tqlabel.h> #include <tqlabel.h>
#include <tqhbox.h> #include <tqhbox.h>
#include "netwm.h"
#include <tdelocale.h> #include <tdelocale.h>
#include <tdeglobal.h> #include <tdeglobal.h>
#include <kstandarddirs.h> #include <kstandarddirs.h>
#include <kbugreport.h> #include <kbugreport.h>
#include <tdefiledialog.h>
#include <tdemessagebox.h> #include <tdemessagebox.h>
#include <kprocess.h> #include <kprocess.h>
#include <tdeapplication.h> #include <tdeapplication.h>
#include <dcopclient.h> #include <dcopclient.h>
#include <tdetempfile.h>
#include "netwm.h"
#include "backtrace.h" #include "backtrace.h"
#include "drbugreport.h" #include "drbugreport.h"
@ -192,6 +194,7 @@ void Toplevel :: slotNewDebuggingApp(const TQString& launchName)
void Toplevel :: slotUser3() void Toplevel :: slotUser3()
{ {
enableButton(User3, false);
TQApplication::setOverrideCursor ( tqwaitCursor ); TQApplication::setOverrideCursor ( tqwaitCursor );
// generate the backtrace // generate the backtrace
@ -239,6 +242,8 @@ void Toplevel::slotSendReportBacktraceSomeError()
delete m_bugdescription; delete m_bugdescription;
m_bugdescription = 0; m_bugdescription = 0;
enableButton(User3, true);
} }
void Toplevel::slotSendReportBacktraceDone(const TQString &str) void Toplevel::slotSendReportBacktraceDone(const TQString &str)
@ -258,6 +263,7 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
if (i == KMessageBox::Cancel) { if (i == KMessageBox::Cancel) {
TQApplication::restoreOverrideCursor(); TQApplication::restoreOverrideCursor();
enableButton(User3, true);
return; return;
} }
@ -277,6 +283,30 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
} }
} }
// Get automatic system information
TQString autoSystemInformation;
KBugReport* kbugreport = new KBugReport(0, true, m_krashconf->aboutData());
autoSystemInformation += "Application: ";
autoSystemInformation += m_krashconf->appName();
autoSystemInformation += "\n";
autoSystemInformation += "Signal: ";
autoSystemInformation += TQString("%1").arg(m_krashconf->signalNumber());
autoSystemInformation += "\n";
autoSystemInformation += "Compiler: ";
autoSystemInformation += kbugreport->compilerVersion();
autoSystemInformation += "\n";
autoSystemInformation += "Kernel: ";
autoSystemInformation += kbugreport->operatingSystem();
autoSystemInformation += "\n";
autoSystemInformation += "TDE Version: ";
autoSystemInformation += kbugreport->tdeVersion();
autoSystemInformation += "\n";
autoSystemInformation += "Timestamp: ";
autoSystemInformation += TQString("%1").arg(TQDateTime::currentDateTime().toTime_t());
autoSystemInformation += "\n";
delete kbugreport;
kbugreport = 0;
// Generate automatic crash description // Generate automatic crash description
TQString autoCrashDescription = m_krashconf->errorDescriptionText(); TQString autoCrashDescription = m_krashconf->errorDescriptionText();
m_krashconf->expandString(autoCrashDescription, false); m_krashconf->expandString(autoCrashDescription, false);
@ -285,6 +315,8 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
TQString backtraceSubmission = str; TQString backtraceSubmission = str;
backtraceSubmission.append("\n==== (tdebugreport) automatic crash description ====\n"); backtraceSubmission.append("\n==== (tdebugreport) automatic crash description ====\n");
backtraceSubmission.append(TQString("%1\n").arg(autoCrashDescription)); backtraceSubmission.append(TQString("%1\n").arg(autoCrashDescription));
backtraceSubmission.append("\n==== (tdebugreport) automatic system description ====\n");
backtraceSubmission.append(TQString("%1\n").arg(autoSystemInformation));
if (m_bugdescription->emailAddress().contains("@") && m_bugdescription->emailAddress().contains(".")) { if (m_bugdescription->emailAddress().contains("@") && m_bugdescription->emailAddress().contains(".")) {
backtraceSubmission.append("\n==== (tdebugreport) reporting Email address ====\n"); backtraceSubmission.append("\n==== (tdebugreport) reporting Email address ====\n");
backtraceSubmission.append(TQString("%1\n").arg(m_bugdescription->emailAddress())); backtraceSubmission.append(TQString("%1\n").arg(m_bugdescription->emailAddress()));
@ -302,13 +334,13 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
backtraceSubmission.append("\n==== (tdebugreport) proof of work ====\n"); backtraceSubmission.append("\n==== (tdebugreport) proof of work ====\n");
int proofOfWorkPos = backtraceSubmission.length(); int proofOfWorkPos = backtraceSubmission.length();
backtraceSubmission.append(TQUuid::createUuid().toString()); backtraceSubmission.append(TQUuid::createUuid().toString());
TQCString backtraceSubmissionData(backtraceSubmission.ascii()); m_backtraceSubmissionData = TQCString(backtraceSubmission.ascii());
while ((hash[0] != 0) || ((hash[1] & 0xfc) != 0)) { // First 14 bits of the SHA1 hash must be zero while ((hash[0] != 0) || ((hash[1] & 0xfc) != 0)) { // First 14 bits of the SHA1 hash must be zero
TQCString proofOfWork(TQUuid::createUuid().toString().ascii()); TQCString proofOfWork(TQUuid::createUuid().toString().ascii());
memcpy(backtraceSubmissionData.data() + proofOfWorkPos, proofOfWork.data(), proofOfWork.size()); memcpy(m_backtraceSubmissionData.data() + proofOfWorkPos, proofOfWork.data(), proofOfWork.size());
sha.reset(); sha.reset();
sha.process(backtraceSubmissionData, backtraceSubmissionData.length()); sha.process(m_backtraceSubmissionData.data(), m_backtraceSubmissionData.size());
memcpy(hash.data(), sha.hash(), hash.size()); memcpy(hash.data(), sha.hash(), hash.size());
} }
@ -324,6 +356,7 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
if (i == KMessageBox::Cancel) { if (i == KMessageBox::Cancel) {
delete m_bugdescription; delete m_bugdescription;
m_bugdescription = 0; m_bugdescription = 0;
enableButton(User3, true);
return; return;
} }
@ -331,20 +364,20 @@ void Toplevel::slotSendReportBacktraceDone(const TQString &str)
if (i == KMessageBox::Yes) { if (i == KMessageBox::Yes) {
BugDescription fullReport(0, true, NULL); BugDescription fullReport(0, true, NULL);
fullReport.fullReportViewMode(true); fullReport.fullReportViewMode(true);
fullReport.setText(TQString(backtraceSubmissionData.data())); fullReport.setText(TQString(m_backtraceSubmissionData.data()));
fullReport.showMaximized(); fullReport.showMaximized();
fullReport.exec(); fullReport.exec();
} }
} }
postCrashDataToServer(backtraceSubmissionData); postCrashDataToServer(m_backtraceSubmissionData);
delete m_bugdescription; delete m_bugdescription;
m_bugdescription = 0; m_bugdescription = 0;
} }
int Toplevel::postCrashDataToServer(TQByteArray data) { int Toplevel::postCrashDataToServer(TQByteArray data) {
serverResponse = ""; m_serverResponse = "";
TQCString formDataBoundary = "-----------------------------------DrKonqiCrashReporterBoundary"; TQCString formDataBoundary = "-----------------------------------DrKonqiCrashReporterBoundary";
TQCString postData; TQCString postData;
@ -378,21 +411,21 @@ int Toplevel::postCrashDataToServer(TQByteArray data) {
void Toplevel::postCrashDataToServerData(TDEIO::Job *, const TQByteArray &ba) void Toplevel::postCrashDataToServerData(TDEIO::Job *, const TQByteArray &ba)
{ {
uint offset = 0; uint offset = 0;
if (serverResponse.count() > 0) { if (m_serverResponse.count() > 0) {
offset = serverResponse.count() - 1; offset = m_serverResponse.count() - 1;
} }
uint size = ba.count(); uint size = ba.count();
serverResponse.resize(offset + size + 1); m_serverResponse.resize(offset + size + 1);
memcpy(serverResponse.data() + offset, ba.data(), size); memcpy(m_serverResponse.data() + offset, ba.data(), size);
*(serverResponse.data() + offset + size) = 0; *(m_serverResponse.data() + offset + size) = 0;
} }
void Toplevel::postCrashDataToServerResult(TDEIO::Job *job) void Toplevel::postCrashDataToServerResult(TDEIO::Job *job)
{ {
int err = job->error(); int err = job->error();
if (err == 0) { if (err == 0) {
TQString responseString(serverResponse); TQString responseString(m_serverResponse);
if (responseString.startsWith("ACK\n")) { if (responseString.startsWith("ACK\n")) {
responseString = responseString.mid(4); responseString = responseString.mid(4);
KMessageBox::information KMessageBox::information
@ -403,17 +436,75 @@ void Toplevel::postCrashDataToServerResult(TDEIO::Job *job)
} }
else { else {
responseString = responseString.mid(4); responseString = responseString.mid(4);
KMessageBox::error // KMessageBox::error
// (0,
// i18n("<p>Your crash report failed to upload!</p><p>Please check your network settings and try again.</p><p>The server responded:<br>%1</p>").arg(responseString),
// i18n("Upload failure"));
int i = KMessageBox::warningYesNoCancel
(0,
i18n("<p>Your crash report failed to upload!</p><p>Please check your network settings and try again.</p><p>The server responded:<br>%1</p>").arg(responseString),
i18n("Upload failure"),i18n("Save Report"),i18n("Retry Upload"));
if (i == KMessageBox::No) {
postCrashDataToServer(m_backtraceSubmissionData);
}
if (i == KMessageBox::Yes) {
saveOfflineCrashReport(m_backtraceSubmissionData);
}
}
}
else {
int i = KMessageBox::warningYesNoCancel
(0, (0,
i18n("<p>Your crash report failed to upload!</p><p>Please check your network settings and try again.</p><p>The server responded:<br>%1</p>").arg(responseString), i18n("<p>Your crash report failed to upload!</p><p>Please check your network settings and try again.</p>"),
i18n("Upload failure")); i18n("Upload failure"),i18n("Save Report"),i18n("Retry Upload"));
if (i == KMessageBox::No) {
postCrashDataToServer(m_backtraceSubmissionData);
} }
if (i == KMessageBox::Yes) {
saveOfflineCrashReport(m_backtraceSubmissionData);
}
}
}
int Toplevel::saveOfflineCrashReport(TQByteArray data)
{
TQString defname = m_krashconf->execName() + TQString::fromLatin1( ".tdecrash" );
if( defname.contains( '/' ))
defname = defname.mid( defname.findRev( '/' ) + 1 );
TQString filename = KFileDialog::getSaveFileName(defname, TQString::null, this, i18n("Select Filename"));
if (filename.isEmpty()) {
enableButton(User3, true);
return 1;
} }
else { else {
KMessageBox::error TQFile f(filename);
(0,
i18n("<p>Your crash report failed to upload!</p><p>Please check your network settings and try again.</p>"), if (f.exists()) {
i18n("Upload failure")); if (KMessageBox::Cancel ==
KMessageBox::warningContinueCancel( 0,
i18n( "A file named \"%1\" already exists. "
"Are you sure you want to overwrite it?" ).arg( filename ),
i18n( "Overwrite File?" ),
i18n( "&Overwrite" ) ))
return 2;
}
if (f.open(IO_WriteOnly)) {
f.writeBlock(data.data(), data.count());
f.close();
enableButton(User3, true);
return 0;
}
else {
KMessageBox::sorry(this, i18n("Cannot open file %1 for writing").arg(filename));
enableButton(User3, true);
return 3;
}
} }
} }

@ -52,6 +52,7 @@ private:
// helper methods // helper methods
TQString generateText() const; TQString generateText() const;
int postCrashDataToServer(TQByteArray data); int postCrashDataToServer(TQByteArray data);
int saveOfflineCrashReport(TQByteArray data);
protected slots: protected slots:
void slotUser1(); void slotUser1();
@ -74,7 +75,8 @@ private:
KrashConfig *m_krashconf; KrashConfig *m_krashconf;
DrKBugReport *m_bugreport; DrKBugReport *m_bugreport;
BugDescription* m_bugdescription; BugDescription* m_bugdescription;
TQCString serverResponse; TQCString m_serverResponse;
TQCString m_backtraceSubmissionData;
}; };
#endif #endif

Loading…
Cancel
Save