Bug 379290 - Add env var to auto submit crashes r=gsvelto
MozReview-Commit-ID: HguIy4GKMb0
--- a/toolkit/crashreporter/client/crashreporter.cpp
+++ b/toolkit/crashreporter/client/crashreporter.cpp
@@ -39,29 +39,34 @@ using std::auto_ptr;
namespace CrashReporter {
StringTable gStrings;
string gSettingsPath;
string gEventsPath;
string gPingPath;
int gArgc;
char** gArgv;
+bool gAutoSubmit;
enum SubmissionResult {Succeeded, Failed};
static auto_ptr<ofstream> gLogStream(nullptr);
static string gReporterDumpFile;
static string gExtraFile;
static string gMemoryFile;
static const char kExtraDataExtension[] = ".extra";
static const char kMemoryReportExtension[] = ".memory.json.gz";
void UIError(const string& message)
{
+ if (gAutoSubmit) {
+ return;
+ }
+
string errorMessage;
if (!gStrings[ST_CRASHREPORTERERROR].empty()) {
char buf[2048];
UI_SNPRINTF(buf, 2048,
gStrings[ST_CRASHREPORTERERROR].c_str(),
message.c_str());
errorMessage = buf;
} else {
@@ -642,36 +647,44 @@ GetProgramPath(const string& exename)
int main(int argc, char** argv)
{
bool minidumpAllThreads = false;
gArgc = argc;
gArgv = argv;
+ string autoSubmitEnv = UIGetEnv("MOZ_CRASHREPORTER_AUTO_SUBMIT");
+ if (!autoSubmitEnv.empty()) {
+ gAutoSubmit = true;
+ }
+
if (!ReadConfig()) {
UIError("Couldn't read configuration.");
return 0;
}
- if (!UIInit())
+ if (!UIInit()) {
return 0;
+ }
if (argc == 3) {
if (!strcmp(argv[1], "--full")) {
minidumpAllThreads = true;
}
gReporterDumpFile = argv[2];
} else if (argc == 2) {
gReporterDumpFile = argv[1];
}
if (gReporterDumpFile.empty()) {
// no dump file specified, run the default UI
- UIShowDefaultUI();
+ if (!gAutoSubmit) {
+ UIShowDefaultUI();
+ }
} else {
// Start by running minidump analyzer to gather stack traces.
string reporterDumpFile = gReporterDumpFile;
vector<string> args = { reporterDumpFile };
if (minidumpAllThreads) {
args.insert(args.begin(), "--full");
}
UIRunProgram(GetProgramPath(UI_MINIDUMP_ANALYZER_FILENAME),
@@ -805,23 +818,23 @@ int main(int argc, char** argv)
// allow override of the server url via environment variable
//XXX: remove this in the far future when our robot
// masters force everyone to use XULRunner
char* urlEnv = getenv("MOZ_CRASHREPORTER_URL");
if (urlEnv && *urlEnv) {
sendURL = urlEnv;
}
- // see if this version has been end-of-lifed
- if (queryParameters.find("Version") != queryParameters.end() &&
- CheckEndOfLifed(queryParameters["Version"])) {
- UIError(gStrings[ST_ERROR_ENDOFLIFE]);
- DeleteDump();
- return 0;
- }
+ // see if this version has been end-of-lifed
+ if (queryParameters.find("Version") != queryParameters.end() &&
+ CheckEndOfLifed(queryParameters["Version"])) {
+ UIError(gStrings[ST_ERROR_ENDOFLIFE]);
+ DeleteDump();
+ return 0;
+ }
StringTable files;
files["upload_file_minidump"] = gReporterDumpFile;
if (!gMemoryFile.empty()) {
files["memory_report"] = gMemoryFile;
}
if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs))
--- a/toolkit/crashreporter/client/crashreporter.h
+++ b/toolkit/crashreporter/client/crashreporter.h
@@ -88,16 +88,17 @@ typedef std::map<std::string, std::strin
//=============================================================================
namespace CrashReporter {
extern StringTable gStrings;
extern std::string gSettingsPath;
extern std::string gEventsPath;
extern int gArgc;
extern char** gArgv;
+ extern bool gAutoSubmit;
void UIError(const std::string& message);
// The UI finished sending the report
void SendCompleted(bool success, const std::string& serverResponse);
bool ReadStrings(std::istream& in,
StringTable& strings,
--- a/toolkit/crashreporter/client/crashreporter_gtk_common.cpp
+++ b/toolkit/crashreporter/client/crashreporter_gtk_common.cpp
@@ -54,16 +54,17 @@ string gCACertificateFile;
string gSendURL;
string gURLParameter;
vector<string> gRestartArgs;
GThread* gSendThreadID;
// From crashreporter_linux.cpp
void SaveSettings();
void SendReport();
+void DisableGUIAndSendReport();
void TryInitGnome();
void UpdateSubmit();
static bool RestartApplication()
{
char** argv = reinterpret_cast<char**>(
malloc(sizeof(char*) * (gRestartArgs.size() + 1)));
@@ -88,17 +89,19 @@ static bool RestartApplication()
free(argv);
return true;
}
// Quit the app, used as a timeout callback
static gboolean CloseApp(gpointer data)
{
- gtk_main_quit();
+ if (!gAutoSubmit) {
+ gtk_main_quit();
+ }
g_thread_join(gSendThreadID);
return FALSE;
}
static gboolean ReportCompleted(gpointer success)
{
gtk_widget_hide(gThrobber);
string str = success ? gStrings[ST_REPORTSUBMITSUCCESS]
@@ -206,20 +209,23 @@ gpointer SendThread(gpointer args)
if (success) {
LogMessage("Crash report submitted successfully");
}
else {
LogMessage("Crash report submission failed: " + error);
}
SendCompleted(success, response);
- // Apparently glib is threadsafe, and will schedule this
- // on the main thread, see:
- // http://library.gnome.org/devel/gtk-faq/stable/x499.html
- g_idle_add(ReportCompleted, (gpointer)success);
+
+ if (!gAutoSubmit) {
+ // Apparently glib is threadsafe, and will schedule this
+ // on the main thread, see:
+ // http://library.gnome.org/devel/gtk-faq/stable/x499.html
+ g_idle_add(ReportCompleted, (gpointer)success);
+ }
return nullptr;
}
gboolean WindowDeleted(GtkWidget* window,
GdkEvent* event,
gpointer userData)
{
@@ -238,17 +244,17 @@ gboolean check_escape(GtkWidget* window,
}
return FALSE;
}
static void MaybeSubmitReport()
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck))) {
gDidTrySend = true;
- SendReport();
+ DisableGUIAndSendReport();
} else {
gtk_main_quit();
}
}
void CloseClicked(GtkButton* button,
gpointer userData)
{
--- a/toolkit/crashreporter/client/crashreporter_linux.cpp
+++ b/toolkit/crashreporter/client/crashreporter_linux.cpp
@@ -92,38 +92,42 @@ void SaveSettings()
? "1" : "0";
WriteStringsToFile(gSettingsPath + "/" + kIniFile,
"Crash Reporter", settings, true);
}
void SendReport()
{
+#ifdef MOZ_ENABLE_GCONF
+ LoadProxyinfo();
+#endif
+
+ // spawn a thread to do the sending
+ gSendThreadID = g_thread_create(SendThread, nullptr, TRUE, nullptr);
+}
+
+void DisableGUIAndSendReport()
+{
// disable all our gui controls, show the throbber + change the progress text
gtk_widget_set_sensitive(gSubmitReportCheck, FALSE);
gtk_widget_set_sensitive(gViewReportButton, FALSE);
gtk_widget_set_sensitive(gCommentText, FALSE);
if (gIncludeURLCheck)
gtk_widget_set_sensitive(gIncludeURLCheck, FALSE);
gtk_widget_set_sensitive(gEmailMeCheck, FALSE);
gtk_widget_set_sensitive(gEmailEntry, FALSE);
gtk_widget_set_sensitive(gCloseButton, FALSE);
if (gRestartButton)
gtk_widget_set_sensitive(gRestartButton, FALSE);
gtk_widget_show_all(gThrobber);
gtk_label_set_text(GTK_LABEL(gProgressLabel),
gStrings[ST_REPORTDURINGSUBMIT].c_str());
-#ifdef MOZ_ENABLE_GCONF
- LoadProxyinfo();
-#endif
-
- // and spawn a thread to do the sending
- GError* err;
- gSendThreadID = g_thread_create(SendThread, nullptr, TRUE, &err);
+ SendReport();
}
static void ShowReportInfo(GtkTextView* viewReportTextView)
{
GtkTextBuffer* buffer =
gtk_text_view_get_buffer(viewReportTextView);
GtkTextIter start, end;
@@ -386,16 +390,22 @@ bool UIShowCrashUI(const StringTable& fi
{
gFiles = files;
gQueryParameters = queryParameters;
gSendURL = sendURL;
gRestartArgs = restartArgs;
if (gQueryParameters.find("URL") != gQueryParameters.end())
gURLParameter = gQueryParameters["URL"];
+ if (gAutoSubmit) {
+ SendReport();
+ CloseApp(nullptr);
+ return true;
+ }
+
gWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(gWindow),
gStrings[ST_CRASHREPORTERTITLE].c_str());
gtk_window_set_resizable(GTK_WINDOW(gWindow), FALSE);
gtk_window_set_position(GTK_WINDOW(gWindow), GTK_WIN_POS_CENTER);
gtk_container_set_border_width(GTK_CONTAINER(gWindow), 12);
g_signal_connect(gWindow, "delete-event", G_CALLBACK(WindowDeleted), 0);
g_signal_connect(gWindow, "key_press_event", G_CALLBACK(check_escape), nullptr);
--- a/toolkit/crashreporter/client/crashreporter_osx.mm
+++ b/toolkit/crashreporter/client/crashreporter_osx.mm
@@ -106,16 +106,22 @@ static bool RestartApplication()
-(void)showCrashUI:(const StringTable&)files
queryParameters:(const StringTable&)queryParameters
sendURL:(const string&)sendURL
{
gFiles = files;
gQueryParameters = queryParameters;
gSendURL = sendURL;
+ if (gAutoSubmit) {
+ gDidTrySend = true;
+ [self sendReport];
+ return;
+ }
+
[mWindow setTitle:Str(ST_CRASHREPORTERTITLE)];
[mHeaderLabel setStringValue:Str(ST_CRASHREPORTERHEADER)];
NSRect viewReportFrame = [mViewReportButton frame];
[mViewReportButton setTitle:Str(ST_VIEWREPORT)];
[mViewReportButton sizeToFit];
if (gRTLlayout) {
// sizeToFit will keep the left side fixed, so realign
@@ -532,22 +538,27 @@ static bool RestartApplication()
[mEmailText setEnabled:NO];
}
}
-(void)sendReport
{
if (![self setupPost]) {
LogMessage("Crash report submission failed: could not set up POST data");
- [self setStringFitVertically:mProgressText
+
+ if (gAutoSubmit) {
+ [NSApp terminate:self];
+ }
+
+ [self setStringFitVertically:mProgressText
string:Str(ST_SUBMITFAILED)
resizeWindow:YES];
- // quit after 5 seconds
- [self performSelector:@selector(closeMeDown:) withObject:nil
- afterDelay:5.0];
+ // quit after 5 seconds
+ [self performSelector:@selector(closeMeDown:) withObject:nil
+ afterDelay:5.0];
}
[NSThread detachNewThreadSelector:@selector(uploadThread:)
toTarget:self
withObject:mPost];
}
-(bool)setupPost
@@ -622,16 +633,20 @@ static bool RestartApplication()
}
NSString* r = [[NSString alloc] initWithData: data encoding: encoding];
reply = [r UTF8String];
[r release];
}
SendCompleted(success, reply);
+ if (gAutoSubmit) {
+ [NSApp terminate:self];
+ }
+
[mProgressIndicator stopAnimation:self];
if (success) {
[self setStringFitVertically:mProgressText
string:Str(ST_REPORTSUBMITSUCCESS)
resizeWindow:YES];
} else {
[self setStringFitVertically:mProgressText
string:Str(ST_SUBMITFAILED)
@@ -761,18 +776,22 @@ bool UIInit()
{
gMainPool = [[NSAutoreleasePool alloc] init];
[NSApplication sharedApplication];
if (gStrings.find("isRTL") != gStrings.end() &&
gStrings["isRTL"] == "yes")
gRTLlayout = true;
- [NSBundle loadNibNamed:(gRTLlayout ? @"MainMenuRTL" : @"MainMenu")
- owner:NSApp];
+ if (gAutoSubmit) {
+ gUI = [[CrashReporterUI alloc] init];
+ } else {
+ [NSBundle loadNibNamed:(gRTLlayout ? @"MainMenuRTL" : @"MainMenu")
+ owner:NSApp];
+ }
return true;
}
void UIShutdown()
{
[gMainPool release];
}
--- a/toolkit/crashreporter/client/crashreporter_win.cpp
+++ b/toolkit/crashreporter/client/crashreporter_win.cpp
@@ -409,17 +409,24 @@ static DWORD WINAPI SendThreadProc(LPVOI
else {
// get an error string and print it to the log
//XXX: would be nice to get the HTTP status code here, filed:
// http://code.google.com/p/google-breakpad/issues/detail?id=220
LogMessage(FormatLastError());
}
}
- PostMessage(td->hDlg, WM_UPLOADCOMPLETE, finishedOk ? 1 : 0, 0);
+ if (gAutoSubmit) {
+ // Ordinarily this is done on the main thread in CrashReporterDialogProc,
+ // for auto submit we don't run that and it should be safe to finish up
+ // here as is done on other platforms.
+ SendCompleted(finishedOk, WideToUTF8(gSendData.serverResponse));
+ } else {
+ PostMessage(td->hDlg, WM_UPLOADCOMPLETE, finishedOk ? 1 : 0, 0);
+ }
return 0;
}
static void EndCrashReporterDialog(HWND hwndDlg, int code)
{
// Save the current values to the registry
wchar_t email[MAX_EMAIL_LENGTH];
@@ -1352,16 +1359,26 @@ bool UIShowCrashUI(const StringTable& fi
gURLParameter = gQueryParameters[L"URL"];
gRestartArgs = restartArgs;
if (gStrings.find("isRTL") != gStrings.end() &&
gStrings["isRTL"] == "yes")
gRTLlayout = true;
+ if (gAutoSubmit) {
+ gSendData.queryParameters = gQueryParameters;
+
+ gThreadHandle = CreateThread(nullptr, 0, SendThreadProc, &gSendData, 0,
+ nullptr);
+ WaitForSingleObject(gThreadHandle, INFINITE);
+ // SendCompleted was called from SendThreadProc
+ return true;
+ }
+
return 1 == DialogBoxParamMaybeRTL(IDD_SENDDIALOG, nullptr,
(DLGPROC)CrashReporterDialogProc, 0);
}
void UIError_impl(const string& message)
{
wstring title = Str(ST_CRASHREPORTERTITLE);
if (title.empty())