Bug 1759175 pt9 - Remove old crash reporter localization r=gsvelto,geckoview-reviewers,m_kato

This removes the old localization files, updates installer package manifests, and replaces code that
accessed the files with fluent accesses for the new localization info.

This also replaces some code in nsExceptionHandler to get/set the crash reporter `submit reports`
setting.

Differential Revision: https://phabricator.services.mozilla.com/D199914
This commit is contained in:
Alex Franchuk 2024-03-20 14:59:46 +00:00
parent 5bfaf67d7f
commit 2439b67822
10 changed files with 56 additions and 346 deletions

View File

@ -388,14 +388,10 @@ bin/libfreebl_64int_3.so
@BINPATH@/crashreporter.app/
#else
@BINPATH@/crashreporter@BIN_SUFFIX@
@RESPATH@/crashreporter.ini
#ifdef XP_UNIX
@RESPATH@/Throbber-small.gif
#elif defined(XP_WIN)
#if defined(XP_WIN)
@BINPATH@/@DLL_PREFIX@mozwer@DLL_SUFFIX@
#endif
#endif
@RESPATH@/browser/crashreporter-override.ini
#ifdef MOZ_CRASHREPORTER_INJECTOR
@BINPATH@/breakpadinjector.dll
#endif

View File

@ -1,9 +0,0 @@
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This file is in the UTF-8 encoding
[Strings]
# LOCALIZATION NOTE (CrashReporterProductErrorText2): The %s is replaced with a string containing detailed information.
CrashReporterProductErrorText2=Firefox had a problem and crashed. Well try to restore your tabs and windows when it restarts.\n\nUnfortunately the crash reporter is unable to submit a crash report.\n\nDetails: %s
CrashReporterDescriptionText2=Firefox had a problem and crashed. Well try to restore your tabs and windows when it restarts.\n\nTo help us diagnose and fix the problem, you can send us a crash report.

View File

@ -9,9 +9,6 @@ JAR_MANIFESTS += ["jar.mn"]
# If DIST_SUBDIR ever gets unset in browser this path might be wrong due to PREF_DIR changing.
LOCALIZED_PP_FILES.defaults.preferences += ["en-US/firefox-l10n.js"]
if CONFIG["MOZ_CRASHREPORTER"]:
LOCALIZED_FILES += ["en-US/crashreporter/crashreporter-override.ini"]
if CONFIG["MOZ_UPDATER"]:
LOCALIZED_GENERATED_FILES += ["updater.ini"]
updater = LOCALIZED_GENERATED_FILES["updater.ini"]

View File

@ -192,14 +192,6 @@
@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
#endif
; [Crash Reporter]
; CrashService is not used on Android but the ini files are required for L10N
; strings, see bug 1191351.
#ifdef MOZ_CRASHREPORTER
@BINPATH@/crashreporter.ini
@BINPATH@/crashreporter-override.ini
#endif
[mobile]
@BINPATH@/chrome/geckoview@JAREXT@
@BINPATH@/chrome/geckoview.manifest

View File

@ -2,8 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
import { FileUtils } from "resource://gre/modules/FileUtils.sys.mjs";
const SUCCESS = "success";
const FAILED = "failed";
const SUBMITTING = "submitting";
@ -13,81 +11,6 @@ const UUID_REGEX =
const SUBMISSION_REGEX =
/^bp-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
// TODO: this is still synchronous; need an async INI parser to make it async
function parseINIStrings(path) {
let file = new FileUtils.File(path);
let factory = Cc["@mozilla.org/xpcom/ini-parser-factory;1"].getService(
Ci.nsIINIParserFactory
);
let parser = factory.createINIParser(file);
let obj = {};
for (let key of parser.getKeys("Strings")) {
obj[key] = parser.getString("Strings", key);
}
return obj;
}
// Since we're basically re-implementing (with async) part of the crashreporter
// client here, we'll just steal the strings we need from crashreporter.ini
async function getL10nStrings() {
let path = PathUtils.join(
Services.dirsvc.get("GreD", Ci.nsIFile).path,
"crashreporter.ini"
);
let pathExists = await IOUtils.exists(path);
if (!pathExists) {
// we if we're on a mac
let parentDir = PathUtils.parent(path);
path = PathUtils.join(
parentDir,
"MacOS",
"crashreporter.app",
"Contents",
"Resources",
"crashreporter.ini"
);
let pathExists = await IOUtils.exists(path);
if (!pathExists) {
// This happens on Android where everything is in an APK.
// Android users can't see the contents of the submitted files
// anyway, so just hardcode some fallback strings.
return {
crashid: "Crash ID: %s",
reporturl: "You can view details of this crash at %s",
};
}
}
let crstrings = parseINIStrings(path);
let strings = {
crashid: crstrings.CrashID,
reporturl: crstrings.CrashDetailsURL,
};
path = PathUtils.join(
Services.dirsvc.get("XCurProcD", Ci.nsIFile).path,
"crashreporter-override.ini"
);
pathExists = await IOUtils.exists(path);
if (pathExists) {
crstrings = parseINIStrings(path);
if ("CrashID" in crstrings) {
strings.crashid = crstrings.CrashID;
}
if ("CrashDetailsURL" in crstrings) {
strings.reporturl = crstrings.CrashDetailsURL;
}
}
return strings;
}
function getDir(name) {
let uAppDataPath = Services.dirsvc.get("UAppData", Ci.nsIFile).path;
return PathUtils.join(uAppDataPath, "Crash Reports", name);
@ -109,11 +32,17 @@ function getPendingMinidump(id) {
}
async function writeSubmittedReportAsync(crashID, viewURL) {
let strings = await getL10nStrings();
let data = strings.crashid.replace("%s", crashID);
// Since we're basically re-implementing (with async) part of the
// crashreporter client here, we'll use the strings we need from the
// crashreporter fluent file.
const l10n = new Localization(["crashreporter/crashreporter.ftl"]);
let data = await l10n.formatValue("crashreporter-crash-identifier", {
id: crashID,
});
if (viewURL) {
data += "\n" + strings.reporturl.replace("%s", viewURL);
data +=
"\n" +
(await l10n.formatValue("crashreporter-crash-details", { url: viewURL }));
}
await writeFileAsync("submitted", `${crashID}.txt`, data);

View File

@ -120,9 +120,12 @@ if CONFIG["MOZ_CRASHREPORTER"]:
DEFINES["MOZ_PHC"] = True
LOCAL_INCLUDES += [
"/toolkit/components/jsoncpp/include",
"google-breakpad/src",
]
USE_LIBS += ["jsoncpp"]
PYTHON_UNITTEST_MANIFESTS += [
"tools/python.toml",
]

View File

@ -7,6 +7,7 @@
#include "nsExceptionHandler.h"
#include "nsExceptionHandlerUtils.h"
#include "json/json.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsComponentManagerUtils.h"
#include "nsDirectoryServiceDefs.h"
@ -95,6 +96,9 @@
using mozilla::InjectCrashRunnable;
#endif
#include <fstream>
#include <optional>
#include <stdlib.h>
#include <time.h>
#include <prenv.h>
@ -195,7 +199,7 @@ static const XP_CHAR dumpFileExtension[] = XP_TEXT(".dmp");
static const XP_CHAR extraFileExtension[] = XP_TEXT(".extra");
static const XP_CHAR memoryReportExtension[] = XP_TEXT(".memory.json.gz");
static xpstring* defaultMemoryReportPath = nullptr;
static std::optional<xpstring> defaultMemoryReportPath = {};
static const char kCrashMainID[] = "crash.main.3\n";
@ -433,26 +437,26 @@ static void CreateFileFromPath(const xpstring& path, nsIFile** file) {
NS_NewLocalFile(nsDependentString(path.c_str()), false, file);
}
static xpstring* CreatePathFromFile(nsIFile* file) {
static std::optional<xpstring> CreatePathFromFile(nsIFile* file) {
nsAutoString path;
nsresult rv = file->GetPath(path);
if (NS_FAILED(rv)) {
return nullptr;
return {};
}
return new xpstring(static_cast<wchar_t*>(path.get()), path.Length());
return xpstring(static_cast<wchar_t*>(path.get()), path.Length());
}
#else
static void CreateFileFromPath(const xpstring& path, nsIFile** file) {
NS_NewNativeLocalFile(nsDependentCString(path.c_str()), false, file);
}
MAYBE_UNUSED static xpstring* CreatePathFromFile(nsIFile* file) {
MAYBE_UNUSED static std::optional<xpstring> CreatePathFromFile(nsIFile* file) {
nsAutoCString path;
nsresult rv = file->GetNativePath(path);
if (NS_FAILED(rv)) {
return nullptr;
return {};
}
return new xpstring(path.get(), path.Length());
return xpstring(path.get(), path.Length());
}
#endif
@ -2252,7 +2256,7 @@ static nsresult SetupCrashReporterDirectory(nsIFile* aAppDataDirectory,
NS_ENSURE_SUCCESS(rv, rv);
EnsureDirectoryExists(directory);
xpstring* directoryPath = CreatePathFromFile(directory);
std::optional<xpstring> directoryPath = CreatePathFromFile(directory);
if (!directoryPath) {
return NS_ERROR_FAILURE;
@ -2264,8 +2268,6 @@ static nsresult SetupCrashReporterDirectory(nsIFile* aAppDataDirectory,
setenv(aEnvVarName, directoryPath->c_str(), /* overwrite */ 1);
#endif
delete directoryPath;
if (aDirectory) {
directory.forget(aDirectory);
}
@ -2760,178 +2762,55 @@ nsresult AppendObjCExceptionInfoToAppNotes(void* inException) {
*/
static nsresult PrefSubmitReports(bool* aSubmitReports, bool writePref) {
nsresult rv;
#if defined(XP_WIN)
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_UNIX)
/*
* NOTE! This needs to stay in sync with the preference checking code
* in toolkit/crashreporter/client/crashreporter_win.cpp
* NOTE! This needs to stay in sync with the code in
* toolkit/crashreporter/client/app/src/{logic,settings}.rs
*/
nsCOMPtr<nsIXULAppInfo> appinfo =
do_GetService("@mozilla.org/xre/app-info;1", &rv);
nsCOMPtr<nsIFile> reporterSettings;
rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(reporterSettings));
NS_ENSURE_SUCCESS(rv, rv);
reporterSettings->AppendNative("Crash Reports"_ns);
reporterSettings->AppendNative("crashreporter_settings.json"_ns);
nsAutoCString appVendor, appName;
rv = appinfo->GetVendor(appVendor);
NS_ENSURE_SUCCESS(rv, rv);
rv = appinfo->GetName(appName);
NS_ENSURE_SUCCESS(rv, rv);
std::optional<xpstring> file_path = CreatePathFromFile(reporterSettings);
nsCOMPtr<nsIWindowsRegKey> regKey(
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString regPath;
regPath.AppendLiteral("Software\\");
// We need to ensure the registry keys are created so we can properly
// write values to it
// Create appVendor key
if (!appVendor.IsEmpty()) {
regPath.Append(appVendor);
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_SET_VALUE);
regPath.Append('\\');
if (!file_path) {
return NS_ERROR_FAILURE;
}
// Create appName key
regPath.Append(appName);
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_SET_VALUE);
regPath.Append('\\');
// Create Crash Reporter key
regPath.AppendLiteral("Crash Reporter");
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_SET_VALUE);
// If we're saving the pref value, just write it to ROOT_KEY_CURRENT_USER
// and we're done.
if (writePref) {
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_SET_VALUE);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t value = *aSubmitReports ? 1 : 0;
rv = regKey->WriteIntValue(u"SubmitCrashReport"_ns, value);
regKey->Close();
return rv;
}
// We're reading the pref value, so we need to first look under
// ROOT_KEY_LOCAL_MACHINE to see if it's set there, and then fall back to
// ROOT_KEY_CURRENT_USER. If it's not set in either place, the pref defaults
// to "true".
uint32_t value;
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_SUCCEEDED(rv)) {
rv = regKey->ReadIntValue(u"SubmitCrashReport"_ns, &value);
regKey->Close();
if (NS_SUCCEEDED(rv)) {
*aSubmitReports = !!value;
return NS_OK;
}
}
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_ConvertUTF8toUTF16(regPath),
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_FAILED(rv)) {
*aSubmitReports = true;
return NS_OK;
}
rv = regKey->ReadIntValue(u"SubmitCrashReport"_ns, &value);
// default to true on failure
if (NS_FAILED(rv)) {
value = 1;
rv = NS_OK;
}
regKey->Close();
*aSubmitReports = !!value;
return NS_OK;
#elif defined(XP_MACOSX)
rv = NS_OK;
if (writePref) {
CFPropertyListRef cfValue =
(CFPropertyListRef)(*aSubmitReports ? kCFBooleanTrue : kCFBooleanFalse);
::CFPreferencesSetAppValue(CFSTR("submitReport"), cfValue,
reporterClientAppID);
if (!::CFPreferencesAppSynchronize(reporterClientAppID))
rv = NS_ERROR_FAILURE;
} else {
*aSubmitReports = true;
Boolean keyExistsAndHasValidFormat = false;
Boolean prefValue = ::CFPreferencesGetAppBooleanValue(
CFSTR("submitReport"), reporterClientAppID,
&keyExistsAndHasValidFormat);
if (keyExistsAndHasValidFormat) *aSubmitReports = !!prefValue;
}
return rv;
#elif defined(XP_UNIX)
/*
* NOTE! This needs to stay in sync with the preference checking code
* in toolkit/crashreporter/client/crashreporter_linux.cpp
*/
nsCOMPtr<nsIFile> reporterINI;
rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(reporterINI));
NS_ENSURE_SUCCESS(rv, rv);
reporterINI->AppendNative("Crash Reports"_ns);
reporterINI->AppendNative("crashreporter.ini"_ns);
Json::Value root;
bool exists;
rv = reporterINI->Exists(&exists);
rv = reporterSettings->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists) {
if (!writePref) {
// If reading the pref, default to true if .ini doesn't exist.
// If reading the pref, default to true if the settings file doesn't
// exist.
*aSubmitReports = true;
return NS_OK;
}
// Create the file so the INI processor can write to it.
rv = reporterINI->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
// Create the file so the JSON processor can write to it.
rv = reporterSettings->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
NS_ENSURE_SUCCESS(rv, rv);
} else {
// Read the root value
std::ifstream file(*file_path);
file >> root;
}
nsCOMPtr<nsIINIParserFactory> iniFactory =
do_GetService("@mozilla.org/xpcom/ini-parser-factory;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIINIParser> iniParser;
rv = iniFactory->CreateINIParser(reporterINI, getter_AddRefs(iniParser));
NS_ENSURE_SUCCESS(rv, rv);
// If we're writing the pref, just set and we're done.
if (writePref) {
nsCOMPtr<nsIINIParserWriter> iniWriter = do_QueryInterface(iniParser);
NS_ENSURE_TRUE(iniWriter, NS_ERROR_FAILURE);
rv = iniWriter->SetString("Crash Reporter"_ns, "SubmitReport"_ns,
*aSubmitReports ? "1"_ns : "0"_ns);
NS_ENSURE_SUCCESS(rv, rv);
rv = iniWriter->WriteFile(reporterINI);
return rv;
root["submit_report"] = *aSubmitReports;
std::ofstream file(*file_path);
file << root;
} else if (root["submit_report"].isBool()) {
*aSubmitReports = root["submit_report"].asBool();
} else {
// Default to "true" if the pref can't be found.
*aSubmitReports = true;
}
nsAutoCString submitReportValue;
rv = iniParser->GetString("Crash Reporter"_ns, "SubmitReport"_ns,
submitReportValue);
// Default to "true" if the pref can't be found.
if (NS_FAILED(rv))
*aSubmitReports = true;
else if (submitReportValue.EqualsASCII("0"))
*aSubmitReports = false;
else
*aSubmitReports = true;
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
@ -2973,19 +2852,17 @@ static void SetCrashEventsDir(nsIFile* aDir) {
EnsureDirectoryExists(eventsDir);
}
xpstring* path = CreatePathFromFile(eventsDir);
std::optional<xpstring> path = CreatePathFromFile(eventsDir);
if (!path) {
return; // There's no clean failure from this
}
eventsDirectory = xpstring(*path);
eventsDirectory = *path;
#ifdef XP_WIN
SetEnvironmentVariableW(eventsDirectoryEnv, path->c_str());
#else
setenv(eventsDirectoryEnv, path->c_str(), /* overwrite */ 1);
#endif
delete path;
}
void SetProfileDirectory(nsIFile* aDir) {

View File

@ -1,58 +0,0 @@
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, You can obtain one at http://mozilla.org/MPL/2.0/.
# This file is in the UTF-8 encoding
[Strings]
# LOCALIZATION NOTE (isRTL):
# Leave this entry empty unless your language requires right-to-left layout,
# for example like Arabic, Hebrew, Persian. If your language needs RTL, please
# use the untranslated English word "yes" as value
isRTL=
CrashReporterTitle=Crash Reporter
# LOCALIZATION NOTE (CrashReporterVendorTitle): %s is replaced with the vendor name. (i.e. "Mozilla")
CrashReporterVendorTitle=%s Crash Reporter
# LOCALIZATION NOTE (CrashReporterErrorText): %s is replaced with another string containing detailed information.
CrashReporterErrorText=The application had a problem and crashed.\n\nUnfortunately, the crash reporter is unable to submit a report for this crash.\n\nDetails: %s
# LOCALIZATION NOTE (CrashReporterProductErrorText2): The first %s is replaced with the product name (i.e. "Firefox"), the second is replaced with another string containing detailed information. These two substitutions can not be reordered!
CrashReporterProductErrorText2=%s had a problem and crashed.\n\nUnfortunately, the crash reporter is unable to submit a crash report.\n\nDetails: %s
CrashReporterSorry=We're Sorry
# LOCALIZATION NOTE (CrashReporterDescriptionText2): The %s is replaced with the product name.
CrashReporterDescriptionText2=%s had a problem and crashed.\n\nTo help us diagnose and fix the problem, you can send us a crash report.
CrashReporterDefault=This application is run after a crash to report the problem to the application vendor. It should not be run directly.
Details=Details…
ViewReportTitle=Report Contents
CommentGrayText=Add a comment (comments are publicly visible)
ExtraReportInfo=This report also contains technical information about the state of the application when it crashed.
# LOCALIZATION NOTE (CheckSendReport): The %s is replaced with the vendor name.
CheckSendReport=Tell %s about this crash so they can fix it
CheckIncludeURL=Include the address of the page I was on
ReportPreSubmit2=Your crash report will be submitted before you quit or restart.
ReportDuringSubmit2=Submitting your report…
ReportSubmitSuccess=Report submitted successfully!
ReportSubmitFailed=There was a problem submitting your report.
ReportResubmit=Resending reports that previously failed to send…
# LOCALIZATION NOTE (Quit2): The %s is replaced with the product name.
Quit2=Quit %s
# LOCALIZATION NOTE (Restart): The %s is replaced with the product name.
Restart=Restart %s
Ok=OK
Close=Close
# LOCALIZATION NOTE (CrashID): The %s is replaced with the Crash ID from the server, which is a string like abc12345-6789-0abc-def1-23456abcdef1
CrashID=Crash ID: %s
# LOCALIZATION NOTE (CrashDetailsURL): The %s is replaced with a URL that the user can visit to view the crash details.
CrashDetailsURL=You can view details of this crash at %s
ErrorBadArguments=The application passed an invalid argument.
ErrorExtraFileExists=The application didn't leave an application data file.
ErrorExtraFileRead=Couldn't read the application data file.
ErrorExtraFileMove=Couldn't move application data file.
ErrorDumpFileExists=The application did not leave a crash dump file.
ErrorDumpFileMove=Couldn't move crash dump.
ErrorNoProductName=The application did not identify itself.
ErrorNoServerURL=The application did not specify a crash reporting server.
ErrorNoSettingsPath=Couldn't find the crash reporter's settings.
ErrorCreateDumpDir=Couldn't create pending dump directory.
# LOCALIZATION NOTE (ErrorEndOfLife): The %s is replaced with the product name.
ErrorEndOfLife=The version of %s you are using is no longer supported. Crash reports are no longer being accepted for this version. Please consider upgrading to a supported version.

View File

@ -119,14 +119,6 @@ ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
ifneq (en,$(LPROJ_ROOT))
mv '$(STAGEDIST)'/en.lproj '$(STAGEDIST)'/$(LPROJ_ROOT).lproj
endif
ifdef MOZ_CRASHREPORTER
# On Mac OS X, the crashreporter.ini file needs to be moved from under the
# application bundle's Resources directory where all other l10n files are
# located to the crash reporter bundle's Resources directory.
mv '$(STAGEDIST)'/crashreporter.app/Contents/Resources/crashreporter.ini \
'$(STAGEDIST)'/../MacOS/crashreporter.app/Contents/Resources/crashreporter.ini
$(RM) -rf '$(STAGEDIST)'/crashreporter.app
endif
endif
ifeq (WINNT,$(OS_ARCH))
$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen l10ngen/helper.exe

View File

@ -20,15 +20,6 @@ FINAL_TARGET_FILES.res += [
"!multilocale.txt",
]
if CONFIG["MOZ_CRASHREPORTER"]:
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
# TODO: fixing bug 1223748 should let us remove this special case
LOCALIZED_FILES["crashreporter.app"].Contents.Resources += [
"en-US/crashreporter/crashreporter.ini"
]
else:
LOCALIZED_FILES += ["en-US/crashreporter/crashreporter.ini"]
LOCALIZED_GENERATED_FILES += ["update.locale"]
update_locale = LOCALIZED_GENERATED_FILES["update.locale"]
update_locale.script = "generate_update_locale.py"