void SaveSettings() { /* * NOTE! This code needs to stay in sync with the preference setting * code in in nsExceptionHandler.cpp. */ StringTable settings; ReadStringsFromFile(gSettingsPath + "/" + kIniFile, settings, true); if (!gEmailFieldHint) settings["Email"] = gtk_entry_get_text(GTK_ENTRY(gEmailEntry)); else settings.erase("Email"); settings["EmailMe"] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gEmailMeCheck)) ? "1" : "0"; if (gIncludeURLCheck != 0) settings["IncludeURL"] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck)) ? "1" : "0"; settings["SubmitReport"] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gSubmitReportCheck)) ? "1" : "0"; WriteStringsToFile(gSettingsPath + "/" + kIniFile, "Crash Reporter", settings, true); }
static void UpdateURL() { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gIncludeURLCheck))) { gQueryParameters["URL"] = gURLParameter; } else { gQueryParameters.erase("URL"); } }
int main(int argc, char** argv) { gArgc = argc; gArgv = argv; if (!ReadConfig()) { UIError("Couldn't read configuration."); return 0; } if (!UIInit()) return 0; if (argc > 1) { gReporterDumpFile = argv[1]; } if (gReporterDumpFile.empty()) { // no dump file specified, run the default UI UIShowDefaultUI(); } else { // Start by running minidump analyzer to gather stack traces. string reporterDumpFile = gReporterDumpFile; vector<string> args = { reporterDumpFile }; UIRunProgram(GetProgramPath(UI_MINIDUMP_ANALYZER_FILENAME), args, /* wait */ true); // go ahead with the crash reporter gExtraFile = GetAdditionalFilename(gReporterDumpFile, kExtraDataExtension); if (gExtraFile.empty()) { UIError(gStrings[ST_ERROR_BADARGUMENTS]); return 0; } if (!UIFileExists(gExtraFile)) { UIError(gStrings[ST_ERROR_EXTRAFILEEXISTS]); return 0; } gMemoryFile = GetAdditionalFilename(gReporterDumpFile, kMemoryReportExtension); if (!UIFileExists(gMemoryFile)) { gMemoryFile.erase(); } StringTable queryParameters; if (!ReadStringsFromFile(gExtraFile, queryParameters, true)) { UIError(gStrings[ST_ERROR_EXTRAFILEREAD]); return 0; } if (queryParameters.find("ProductName") == queryParameters.end()) { UIError(gStrings[ST_ERROR_NOPRODUCTNAME]); return 0; } // There is enough information in the extra file to rewrite strings // to be product specific RewriteStrings(queryParameters); if (queryParameters.find("ServerURL") == queryParameters.end()) { UIError(gStrings[ST_ERROR_NOSERVERURL]); return 0; } // Hopefully the settings path exists in the environment. Try that before // asking the platform-specific code to guess. gSettingsPath = UIGetEnv("MOZ_CRASHREPORTER_DATA_DIRECTORY"); if (gSettingsPath.empty()) { string product = queryParameters["ProductName"]; string vendor = queryParameters["Vendor"]; if (!UIGetSettingsPath(vendor, product, gSettingsPath)) { gSettingsPath.clear(); } } if (gSettingsPath.empty() || !UIEnsurePathExists(gSettingsPath)) { UIError(gStrings[ST_ERROR_NOSETTINGSPATH]); return 0; } OpenLogFile(); gEventsPath = UIGetEnv("MOZ_CRASHREPORTER_EVENTS_DIRECTORY"); gPingPath = UIGetEnv("MOZ_CRASHREPORTER_PING_DIRECTORY"); // Assemble and send the crash ping string hash; string pingUuid; hash = ComputeDumpHash(); if (!hash.empty()) { AppendToEventFile("MinidumpSha256Hash", hash); } if (SendCrashPing(queryParameters, hash, pingUuid, gPingPath)) { AppendToEventFile("CrashPingUUID", pingUuid); } // Update the crash event with stacks if they are present auto stackTracesItr = queryParameters.find("StackTraces"); if (stackTracesItr != queryParameters.end()) { AppendToEventFile(stackTracesItr->first, stackTracesItr->second); } if (!UIFileExists(gReporterDumpFile)) { UIError(gStrings[ST_ERROR_DUMPFILEEXISTS]); return 0; } string pendingDir = gSettingsPath + UI_DIR_SEPARATOR + "pending"; if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile, gMemoryFile)) { return 0; } string sendURL = queryParameters["ServerURL"]; // we don't need to actually send this queryParameters.erase("ServerURL"); queryParameters["Throttleable"] = "1"; // re-set XUL_APP_FILE for xulrunner wrapped apps const char *appfile = getenv("MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE"); if (appfile && *appfile) { const char prefix[] = "XUL_APP_FILE="; char *env = (char*) malloc(strlen(appfile) + strlen(prefix) + 1); if (!env) { UIError("Out of memory"); return 0; } strcpy(env, prefix); strcat(env, appfile); putenv(env); free(env); } vector<string> restartArgs; ostringstream paramName; int i = 0; paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++; const char *param = getenv(paramName.str().c_str()); while (param && *param) { restartArgs.push_back(param); paramName.str(""); paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++; param = getenv(paramName.str().c_str()); } // 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; } StringTable files; files["upload_file_minidump"] = gReporterDumpFile; if (!gMemoryFile.empty()) { files["memory_report"] = gMemoryFile; } if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs)) DeleteDump(); } UIShutdown(); return 0; }
int main(int argc, char** argv) { gArgc = argc; gArgv = argv; if (!ReadConfig()) { UIError("Couldn't read configuration."); return 0; } if (!UIInit()) return 0; if (argc > 1) { gReporterDumpFile = argv[1]; } if (gReporterDumpFile.empty()) { // no dump file specified, run the default UI UIShowDefaultUI(); } else { gExtraFile = GetAdditionalFilename(gReporterDumpFile, kExtraDataExtension); if (gExtraFile.empty()) { UIError(gStrings[ST_ERROR_BADARGUMENTS]); return 0; } if (!UIFileExists(gExtraFile)) { UIError(gStrings[ST_ERROR_EXTRAFILEEXISTS]); return 0; } gMemoryFile = GetAdditionalFilename(gReporterDumpFile, kMemoryReportExtension); if (!UIFileExists(gMemoryFile)) { gMemoryFile.erase(); } StringTable queryParameters; if (!ReadStringsFromFile(gExtraFile, queryParameters, true)) { UIError(gStrings[ST_ERROR_EXTRAFILEREAD]); return 0; } if (queryParameters.find("ProductName") == queryParameters.end()) { UIError(gStrings[ST_ERROR_NOPRODUCTNAME]); return 0; } // There is enough information in the extra file to rewrite strings // to be product specific RewriteStrings(queryParameters); if (queryParameters.find("ServerURL") == queryParameters.end()) { UIError(gStrings[ST_ERROR_NOSERVERURL]); return 0; } // Hopefully the settings path exists in the environment. Try that before // asking the platform-specific code to guess. #ifdef XP_WIN32 static const wchar_t kDataDirKey[] = L"MOZ_CRASHREPORTER_DATA_DIRECTORY"; const wchar_t *settingsPath = _wgetenv(kDataDirKey); if (settingsPath && *settingsPath) { gSettingsPath = WideToUTF8(settingsPath); } #else static const char kDataDirKey[] = "MOZ_CRASHREPORTER_DATA_DIRECTORY"; const char *settingsPath = getenv(kDataDirKey); if (settingsPath && *settingsPath) { gSettingsPath = settingsPath; } #endif else { string product = queryParameters["ProductName"]; string vendor = queryParameters["Vendor"]; if (!UIGetSettingsPath(vendor, product, gSettingsPath)) { gSettingsPath.clear(); } } if (gSettingsPath.empty() || !UIEnsurePathExists(gSettingsPath)) { UIError(gStrings[ST_ERROR_NOSETTINGSPATH]); return 0; } OpenLogFile(); #ifdef XP_WIN32 static const wchar_t kEventsDirKey[] = L"MOZ_CRASHREPORTER_EVENTS_DIRECTORY"; const wchar_t *eventsPath = _wgetenv(kEventsDirKey); if (eventsPath && *eventsPath) { gEventsPath = WideToUTF8(eventsPath); } #else static const char kEventsDirKey[] = "MOZ_CRASHREPORTER_EVENTS_DIRECTORY"; const char *eventsPath = getenv(kEventsDirKey); if (eventsPath && *eventsPath) { gEventsPath = eventsPath; } #endif else { gEventsPath.clear(); } if (!UIFileExists(gReporterDumpFile)) { UIError(gStrings[ST_ERROR_DUMPFILEEXISTS]); return 0; } string pendingDir = gSettingsPath + UI_DIR_SEPARATOR + "pending"; if (!MoveCrashData(pendingDir, gReporterDumpFile, gExtraFile, gMemoryFile)) { return 0; } string sendURL = queryParameters["ServerURL"]; // we don't need to actually send this queryParameters.erase("ServerURL"); queryParameters["Throttleable"] = "1"; // re-set XUL_APP_FILE for xulrunner wrapped apps const char *appfile = getenv("MOZ_CRASHREPORTER_RESTART_XUL_APP_FILE"); if (appfile && *appfile) { const char prefix[] = "XUL_APP_FILE="; char *env = (char*) malloc(strlen(appfile) + strlen(prefix) + 1); if (!env) { UIError("Out of memory"); return 0; } strcpy(env, prefix); strcat(env, appfile); putenv(env); free(env); } vector<string> restartArgs; ostringstream paramName; int i = 0; paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++; const char *param = getenv(paramName.str().c_str()); while (param && *param) { restartArgs.push_back(param); paramName.str(""); paramName << "MOZ_CRASHREPORTER_RESTART_ARG_" << i++; param = getenv(paramName.str().c_str()); }; // 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; } StringTable files; files["upload_file_minidump"] = gReporterDumpFile; if (!gMemoryFile.empty()) { files["memory_report"] = gMemoryFile; } if (!UIShowCrashUI(files, queryParameters, sendURL, restartArgs)) DeleteDump(); } UIShutdown(); return 0; }