mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
bug 761909 - crash reporter plumbing for gonk. r=bsmedberg
This commit is contained in:
parent
5bbf7af69a
commit
e865ee4b36
@ -17,7 +17,7 @@ namespace dom {
|
||||
void
|
||||
CrashReporterParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
#if defined(__ANDROID__) && defined(MOZ_CRASHREPORTER)
|
||||
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::RemoveLibraryMappingsForChild(ProcessId(OtherProcess()));
|
||||
#endif
|
||||
}
|
||||
@ -25,7 +25,7 @@ CrashReporterParent::ActorDestroy(ActorDestroyReason why)
|
||||
bool
|
||||
CrashReporterParent::RecvAddLibraryMappings(const InfallibleTArray<Mapping>& mappings)
|
||||
{
|
||||
#if defined(__ANDROID__) && defined(MOZ_CRASHREPORTER)
|
||||
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
||||
for (PRUint32 i = 0; i < mappings.Length(); i++) {
|
||||
const Mapping& m = mappings[i];
|
||||
CrashReporter::AddLibraryMappingForChild(ProcessId(OtherProcess()),
|
||||
|
@ -155,9 +155,12 @@ static google_breakpad::ExceptionHandler* gExceptionHandler = nsnull;
|
||||
static XP_CHAR* pendingDirectory;
|
||||
static XP_CHAR* crashReporterPath;
|
||||
|
||||
// if this is false, we don't launch the crash reporter
|
||||
// If this is false, we don't launch the crash reporter
|
||||
static bool doReport = true;
|
||||
|
||||
// If this is true, we don't have a crash reporter
|
||||
static bool headlessClient = false;
|
||||
|
||||
// if this is true, we pass the exception on to the OS crash reporter
|
||||
static bool showOSCrashReporter = false;
|
||||
|
||||
@ -166,6 +169,15 @@ static time_t lastCrashTime = 0;
|
||||
// The pathname of a file to store the crash time in
|
||||
static XP_CHAR lastCrashTimeFilename[XP_PATH_MAX] = {0};
|
||||
|
||||
// A marker file to hold the path to the last dump written, which
|
||||
// will be checked on startup.
|
||||
static XP_CHAR crashMarkerFilename[XP_PATH_MAX] = {0};
|
||||
|
||||
// Whether we've already looked for the marker file.
|
||||
static bool lastRunCrashID_checked = false;
|
||||
// The minidump ID contained in the marker file.
|
||||
static nsString* lastRunCrashID = nsnull;
|
||||
|
||||
// these are just here for readability
|
||||
static const char kCrashTimeParameter[] = "CrashTime=";
|
||||
static const int kCrashTimeParameterLen = sizeof(kCrashTimeParameter)-1;
|
||||
@ -314,7 +326,7 @@ static cpu_type_t pref_cpu_types[2] = {
|
||||
static posix_spawnattr_t spawnattr;
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// Android builds use a custom library loader,
|
||||
// so the embedding will provide a list of shared
|
||||
// libraries that are mapped into anonymous mappings.
|
||||
@ -416,6 +428,29 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
p = Concat(p, minidump_id, &size);
|
||||
Concat(p, extraFileExtension, &size);
|
||||
|
||||
if (headlessClient) {
|
||||
// Leave a marker indicating that there was a crash.
|
||||
#if defined(XP_WIN32)
|
||||
HANDLE hFile = CreateFile(crashMarkerFilename, GENERIC_WRITE, 0,
|
||||
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if(hFile != INVALID_HANDLE_VALUE) {
|
||||
DWORD nBytes;
|
||||
WriteFile(hFile, minidumpPath, 2*wcslen(minidumpPath), &nBytes, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
#elif defined(XP_UNIX)
|
||||
int fd = sys_open(crashMarkerFilename,
|
||||
O_WRONLY | O_CREAT | O_TRUNC,
|
||||
0600);
|
||||
if (fd != -1) {
|
||||
ssize_t ignored = sys_write(fd, minidumpPath, my_strlen(minidumpPath));
|
||||
(void)ignored;
|
||||
sys_close(fd);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char oomAllocationSizeBuffer[32];
|
||||
int oomAllocationSizeBufferLen = 0;
|
||||
if (gOOMAllocationSize) {
|
||||
@ -471,14 +506,6 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
}
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
XP_CHAR cmdLine[CMDLINE_SIZE];
|
||||
size = CMDLINE_SIZE;
|
||||
p = Concat(cmdLine, L"\"", &size);
|
||||
p = Concat(p, crashReporterPath, &size);
|
||||
p = Concat(p, L"\" \"", &size);
|
||||
p = Concat(p, minidumpPath, &size);
|
||||
Concat(p, L"\"", &size);
|
||||
|
||||
if (!crashReporterAPIData->IsEmpty()) {
|
||||
// write out API data
|
||||
HANDLE hFile = CreateFile(extraDataPath, GENERIC_WRITE, 0,
|
||||
@ -539,6 +566,14 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
XP_CHAR cmdLine[CMDLINE_SIZE];
|
||||
size = CMDLINE_SIZE;
|
||||
p = Concat(cmdLine, L"\"", &size);
|
||||
p = Concat(p, crashReporterPath, &size);
|
||||
p = Concat(p, L"\" \"", &size);
|
||||
p = Concat(p, minidumpPath, &size);
|
||||
Concat(p, L"\"", &size);
|
||||
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
@ -617,7 +652,7 @@ bool MinidumpCallback(const XP_CHAR* dump_path,
|
||||
if (pid == -1)
|
||||
return false;
|
||||
else if (pid == 0) {
|
||||
#if !defined(__ANDROID__)
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
// need to clobber this, as libcurl might load NSS,
|
||||
// and we want it to load the system NSS.
|
||||
unsetenv("LD_LIBRARY_PATH");
|
||||
@ -688,8 +723,6 @@ namespace {
|
||||
nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
bool force/*=false*/)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (gExceptionHandler)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
@ -697,9 +730,14 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
if (envvar && *envvar && !force)
|
||||
return NS_OK;
|
||||
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
doReport = false;
|
||||
headlessClient = true;
|
||||
#else
|
||||
// this environment variable prevents us from launching
|
||||
// the crash reporter client
|
||||
doReport = ShouldReport();
|
||||
#endif
|
||||
|
||||
// allocate our strings
|
||||
crashReporterAPIData = new nsCString();
|
||||
@ -719,37 +757,37 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
notesField = new nsCString();
|
||||
NS_ENSURE_TRUE(notesField, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// locate crashreporter executable
|
||||
nsCOMPtr<nsIFile> exePath;
|
||||
rv = aXREDirectory->Clone(getter_AddRefs(exePath));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!headlessClient) {
|
||||
// locate crashreporter executable
|
||||
nsCOMPtr<nsIFile> exePath;
|
||||
nsresult rv = aXREDirectory->Clone(getter_AddRefs(exePath));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
exePath->Append(NS_LITERAL_STRING("crashreporter.app"));
|
||||
exePath->Append(NS_LITERAL_STRING("Contents"));
|
||||
exePath->Append(NS_LITERAL_STRING("MacOS"));
|
||||
exePath->Append(NS_LITERAL_STRING("crashreporter.app"));
|
||||
exePath->Append(NS_LITERAL_STRING("Contents"));
|
||||
exePath->Append(NS_LITERAL_STRING("MacOS"));
|
||||
#endif
|
||||
|
||||
exePath->AppendNative(NS_LITERAL_CSTRING(CRASH_REPORTER_FILENAME));
|
||||
exePath->AppendNative(NS_LITERAL_CSTRING(CRASH_REPORTER_FILENAME));
|
||||
|
||||
#ifdef XP_WIN32
|
||||
nsString crashReporterPath_temp;
|
||||
nsString crashReporterPath_temp;
|
||||
|
||||
exePath->GetPath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewUnicode(crashReporterPath_temp);
|
||||
exePath->GetPath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewUnicode(crashReporterPath_temp);
|
||||
#elif !defined(__ANDROID__)
|
||||
nsCString crashReporterPath_temp;
|
||||
nsCString crashReporterPath_temp;
|
||||
|
||||
exePath->GetNativePath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewCString(crashReporterPath_temp);
|
||||
exePath->GetNativePath(crashReporterPath_temp);
|
||||
crashReporterPath = ToNewCString(crashReporterPath_temp);
|
||||
#else
|
||||
// On Android, we launch using the application package name
|
||||
// instead of a filename, so use ANDROID_PACKAGE_NAME to do that here.
|
||||
//TODO: don't hardcode org.mozilla here, so other vendors can
|
||||
// ship XUL apps with different package names on Android?
|
||||
nsCString package(ANDROID_PACKAGE_NAME "/.CrashReporter");
|
||||
crashReporterPath = ToNewCString(package);
|
||||
// On Android, we launch using the application package name
|
||||
// instead of a filename, so use ANDROID_PACKAGE_NAME to do that here.
|
||||
nsCString package(ANDROID_PACKAGE_NAME "/.CrashReporter");
|
||||
crashReporterPath = ToNewCString(package);
|
||||
#endif
|
||||
}
|
||||
|
||||
// get temp path to use for minidump path
|
||||
#if defined(XP_WIN32)
|
||||
@ -778,12 +816,11 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
tempPath = path;
|
||||
|
||||
#elif defined(__ANDROID__)
|
||||
// GeckoAppShell sets this in the environment
|
||||
// GeckoAppShell or Gonk's init.rc sets this in the environment
|
||||
const char *tempenv = PR_GetEnv("TMPDIR");
|
||||
if (!tempenv)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCString tempPath(tempenv);
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
// we assume it's always /tmp on unix systems
|
||||
nsCString tempPath = NS_LITERAL_CSTRING("/tmp/");
|
||||
@ -897,7 +934,7 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
||||
showOSCrashReporter = prefValue;
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
for (unsigned int i = 0; i < library_mappings.size(); i++) {
|
||||
u_int8_t guid[sizeof(MDGUID)];
|
||||
FileIDToGUID(library_mappings[i].debug_id.c_str(), guid);
|
||||
@ -1122,6 +1159,34 @@ nsresult SetupExtraData(nsIFile* aAppDataDirectory,
|
||||
strncpy(lastCrashTimeFilename, filename.get(), filename.Length());
|
||||
#endif
|
||||
|
||||
if (headlessClient) {
|
||||
nsCOMPtr<nsIFile> markerFile;
|
||||
rv = dataDirectory->Clone(getter_AddRefs(markerFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = markerFile->AppendNative(NS_LITERAL_CSTRING("LastCrashFilename"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
memset(crashMarkerFilename, 0, sizeof(crashMarkerFilename));
|
||||
|
||||
#if defined(XP_WIN32)
|
||||
nsAutoString markerFilename;
|
||||
rv = markerFile->GetPath(markerFilename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (markerFilename.Length() < XP_PATH_MAX)
|
||||
wcsncpy(crashMarkerFilename, markerFilename.get(),
|
||||
markerFilename.Length());
|
||||
#else
|
||||
nsCAutoString markerFilename;
|
||||
rv = markerFile->GetNativePath(markerFilename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (markerFilename.Length() < XP_PATH_MAX)
|
||||
strncpy(crashMarkerFilename, markerFilename.get(),
|
||||
markerFilename.Length());
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1153,6 +1218,9 @@ nsresult UnsetExceptionHandler()
|
||||
delete notesField;
|
||||
notesField = nsnull;
|
||||
|
||||
delete lastRunCrashID;
|
||||
lastRunCrashID = nsnull;
|
||||
|
||||
if (pendingDirectory) {
|
||||
NS_Free(pendingDirectory);
|
||||
pendingDirectory = nsnull;
|
||||
@ -1513,26 +1581,26 @@ static nsresult PrefSubmitReports(bool* aSubmitReports, bool writePref)
|
||||
// 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.AppendLiteral("\\");
|
||||
}
|
||||
|
||||
// Create appName key
|
||||
regPath.Append(appName);
|
||||
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
NS_ConvertUTF8toUTF16(regPath),
|
||||
nsIWindowsRegKey::ACCESS_SET_VALUE);
|
||||
regPath.AppendLiteral("\\");
|
||||
|
||||
// Create Crash Reporter key
|
||||
regPath.AppendLiteral("Crash Reporter");
|
||||
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
NS_ConvertUTF8toUTF16(regPath),
|
||||
// Create appVendor key
|
||||
if(!appVendor.IsEmpty()) {
|
||||
regPath.Append(appVendor);
|
||||
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
NS_ConvertUTF8toUTF16(regPath),
|
||||
nsIWindowsRegKey::ACCESS_SET_VALUE);
|
||||
regPath.AppendLiteral("\\");
|
||||
}
|
||||
|
||||
// Create appName key
|
||||
regPath.Append(appName);
|
||||
regKey->Create(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
|
||||
NS_ConvertUTF8toUTF16(regPath),
|
||||
nsIWindowsRegKey::ACCESS_SET_VALUE);
|
||||
regPath.AppendLiteral("\\");
|
||||
|
||||
// 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
|
||||
@ -1695,6 +1763,33 @@ nsresult SetSubmitReports(bool aSubmitReports)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
FindPendingDir()
|
||||
{
|
||||
if (pendingDirectory)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIFile> pendingDir;
|
||||
nsresult rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(pendingDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't get the user appdata directory, crash dumps will go in an unusual location");
|
||||
}
|
||||
else {
|
||||
pendingDir->Append(NS_LITERAL_STRING("Crash Reports"));
|
||||
pendingDir->Append(NS_LITERAL_STRING("pending"));
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsString path;
|
||||
pendingDir->GetPath(path);
|
||||
pendingDirectory = ToNewUnicode(path);
|
||||
#else
|
||||
nsCString path;
|
||||
pendingDir->GetNativePath(path);
|
||||
pendingDirectory = ToNewCString(path);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// The "pending" dir is Crash Reports/pending, from which minidumps
|
||||
// can be submitted. Because this method may be called off the main thread,
|
||||
// we store the pending directory as a path.
|
||||
@ -1944,7 +2039,7 @@ OnChildProcessDumpRequested(void* aContext,
|
||||
#endif
|
||||
getter_AddRefs(minidump));
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// Do dump generation here since the CrashGenerationServer doesn't
|
||||
// have access to the library mappings.
|
||||
MappingMap::const_iterator iter =
|
||||
@ -2045,7 +2140,7 @@ OOPInit()
|
||||
|
||||
const std::string dumpPath = gExceptionHandler->dump_path();
|
||||
bool generateDumps = true;
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// On Android, the callback will do dump generation, since it needs
|
||||
// to pass the library mappings.
|
||||
generateDumps = false;
|
||||
@ -2081,25 +2176,7 @@ OOPInit()
|
||||
|
||||
dumpMapLock = new Mutex("CrashReporter::dumpMapLock");
|
||||
|
||||
nsCOMPtr<nsIFile> pendingDir;
|
||||
nsresult rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(pendingDir));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Couldn't get the user appdata directory, crash dumps will go in an unusual location");
|
||||
}
|
||||
else {
|
||||
pendingDir->Append(NS_LITERAL_STRING("Crash Reports"));
|
||||
pendingDir->Append(NS_LITERAL_STRING("pending"));
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsString path;
|
||||
pendingDir->GetPath(path);
|
||||
pendingDirectory = ToNewUnicode(path);
|
||||
#else
|
||||
nsCString path;
|
||||
pendingDir->GetNativePath(path);
|
||||
pendingDirectory = ToNewCString(path);
|
||||
#endif
|
||||
}
|
||||
FindPendingDir();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2207,6 +2284,77 @@ UnregisterInjectorCallback(DWORD processID)
|
||||
|
||||
#endif // MOZ_CRASHREPORTER_INJECTOR
|
||||
|
||||
bool
|
||||
CheckForLastRunCrash()
|
||||
{
|
||||
if (lastRunCrashID)
|
||||
return true;
|
||||
|
||||
// The exception handler callback leaves the filename of the
|
||||
// last minidump in a known file.
|
||||
nsCOMPtr<nsIFile> lastCrashFile;
|
||||
CreateFileFromPath(crashMarkerFilename,
|
||||
getter_AddRefs(lastCrashFile));
|
||||
|
||||
bool exists;
|
||||
if (NS_FAILED(lastCrashFile->Exists(&exists)) || !exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCAutoString lastMinidump_contents;
|
||||
if (NS_FAILED(GetFileContents(lastCrashFile, lastMinidump_contents))) {
|
||||
return false;
|
||||
}
|
||||
lastCrashFile->Remove(false);
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Ugly but effective.
|
||||
nsDependentString lastMinidump(
|
||||
reinterpret_cast<const PRUnichar*>(lastMinidump_contents.get()));
|
||||
#else
|
||||
nsCAutoString lastMinidump = lastMinidump_contents;
|
||||
#endif
|
||||
nsCOMPtr<nsIFile> lastMinidumpFile;
|
||||
CreateFileFromPath(lastMinidump.get(),
|
||||
getter_AddRefs(lastMinidumpFile));
|
||||
|
||||
if (NS_FAILED(lastMinidumpFile->Exists(&exists)) || !exists) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> lastExtraFile;
|
||||
if (!GetExtraFileForMinidump(lastMinidumpFile,
|
||||
getter_AddRefs(lastExtraFile))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FindPendingDir();
|
||||
|
||||
// Move {dump,extra} to pending folder
|
||||
if (!MoveToPending(lastMinidumpFile, lastExtraFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lastRunCrashID = new nsString();
|
||||
return GetIDFromMinidump(lastMinidumpFile, *lastRunCrashID);
|
||||
}
|
||||
|
||||
bool
|
||||
GetLastRunCrashID(nsAString& id)
|
||||
{
|
||||
if (!lastRunCrashID_checked) {
|
||||
CheckForLastRunCrash();
|
||||
lastRunCrashID_checked = true;
|
||||
}
|
||||
|
||||
if (!lastRunCrashID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
id = *lastRunCrashID;
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
// Child-side API
|
||||
bool
|
||||
@ -2479,7 +2627,7 @@ UnsetRemoteExceptionHandler()
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
void AddLibraryMapping(const char* library_name,
|
||||
const char* file_id,
|
||||
uintptr_t start_address,
|
||||
|
@ -43,6 +43,7 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data);
|
||||
nsresult SetRestartArgs(int argc, char** argv);
|
||||
nsresult SetupExtraData(nsIFile* aAppDataDirectory,
|
||||
const nsACString& aBuildID);
|
||||
bool GetLastRunCrashID(nsAString& id);
|
||||
|
||||
// Registers an additional memory region to be included in the minidump
|
||||
nsresult RegisterAppMemory(void* ptr, size_t length);
|
||||
@ -164,7 +165,7 @@ bool SetRemoteExceptionHandler();
|
||||
|
||||
bool UnsetRemoteExceptionHandler();
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#if defined(MOZ_WIDGET_ANDROID)
|
||||
// Android builds use a custom library loader, so /proc/<pid>/maps
|
||||
// will just show anonymous mappings for all the non-system
|
||||
// shared libraries. This API is to work around that by providing
|
||||
|
@ -821,6 +821,17 @@ nsXULAppInfo::GetReplacedLockTime(PRInt64 *aReplacedLockTime)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::GetLastRunCrashID(nsAString &aLastRunCrashID)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
CrashReporter::GetLastRunCrashID(aLastRunCrashID);
|
||||
return NS_OK;
|
||||
#else
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Matches the enum in WinNT.h for the Vista SDK but renamed so that we can
|
||||
// safely build with the Vista SDK and without it.
|
||||
|
@ -89,4 +89,10 @@ interface nsIXULRuntime : nsISupports
|
||||
* closed cleanly. This is set to 0 if there was no existing profile lock.
|
||||
*/
|
||||
readonly attribute PRInt64 replacedLockTime;
|
||||
|
||||
/**
|
||||
* Local ID of the minidump generated when the process crashed
|
||||
* on the previous run. Can be passed directly to CrashSubmit.submit.
|
||||
*/
|
||||
readonly attribute DOMString lastRunCrashID;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user