Bug 1004623 - UpdateCrashEventsDir() is called before XPCOM is started, which means crash events are not being recorded until/unless the user uses an out-of-process plugin. r=ted

--HG--
extra : rebase_source : da13e7c52556c4747914ae502847beb6cc653c46
This commit is contained in:
Benjamin Smedberg 2014-05-06 15:48:40 -04:00
parent 4609853952
commit fe4c35f171
3 changed files with 78 additions and 40 deletions

View File

@ -1352,7 +1352,7 @@ EnsureDirectoryExists(nsIFile* dir)
nsresult rv = dir->Create(nsIFile::DIRECTORY_TYPE, 0700);
if (NS_WARN_IF(NS_FAILED(rv) && rv != NS_ERROR_FILE_ALREADY_EXISTS)) {
return rv;
return rv;
}
return NS_OK;
@ -2081,45 +2081,20 @@ nsresult SetSubmitReports(bool aSubmitReports)
return NS_OK;
}
void
UpdateCrashEventsDir()
static void
SetCrashEventsDir(nsIFile* aDir)
{
nsCOMPtr<nsIFile> eventsDir;
nsCOMPtr<nsIFile> eventsDir = aDir;
// We prefer the following locations in order:
//
// 1. If environment variable is present, use it. We don't expect
// the environment variable except for tests and other atypical setups.
// 2. Inside the profile directory.
// 3. Inside the user application data directory (no profile available).
// 4. A temporary directory (setup likely is invalid / application is buggy).
const char *env = PR_GetEnv("CRASHES_EVENTS_DIR");
if (env) {
eventsDir = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (!eventsDir) {
return;
}
eventsDir->InitWithNativePath(nsDependentCString(env));
if (env && *env) {
NS_NewNativeLocalFile(nsDependentCString(env),
false, getter_AddRefs(eventsDir));
EnsureDirectoryExists(eventsDir);
} else {
nsresult rv = NS_GetSpecialDirectory("ProfD", getter_AddRefs(eventsDir));
if (NS_SUCCEEDED(rv)) {
eventsDir->Append(NS_LITERAL_STRING("crashes"));
EnsureDirectoryExists(eventsDir);
eventsDir->Append(NS_LITERAL_STRING("events"));
EnsureDirectoryExists(eventsDir);
} else {
rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(eventsDir));
if (NS_SUCCEEDED(rv)) {
eventsDir->Append(NS_LITERAL_STRING("Crash Reports"));
EnsureDirectoryExists(eventsDir);
eventsDir->Append(NS_LITERAL_STRING("events"));
EnsureDirectoryExists(eventsDir);
} else {
NS_WARNING("Couldn't get the user appdata directory. Crash events may not be produced.");
return;
}
}
}
if (eventsDirectory) {
NS_Free(eventsDirectory);
}
#ifdef XP_WIN
@ -2133,6 +2108,56 @@ UpdateCrashEventsDir()
#endif
}
void
SetProfileDirectory(nsIFile* aDir)
{
nsCOMPtr<nsIFile> dir;
aDir->Clone(getter_AddRefs(dir));
dir->Append(NS_LITERAL_STRING("crashes"));
EnsureDirectoryExists(dir);
dir->Append(NS_LITERAL_STRING("events"));
EnsureDirectoryExists(dir);
SetCrashEventsDir(dir);
}
void
SetUserAppDataDirectory(nsIFile* aDir)
{
nsCOMPtr<nsIFile> dir;
aDir->Clone(getter_AddRefs(dir));
dir->Append(NS_LITERAL_STRING("Crash Reports"));
EnsureDirectoryExists(dir);
dir->Append(NS_LITERAL_STRING("events"));
EnsureDirectoryExists(dir);
SetCrashEventsDir(dir);
}
void
UpdateCrashEventsDir()
{
const char *env = PR_GetEnv("CRASHES_EVENTS_DIR");
if (env && *env) {
SetCrashEventsDir(nullptr);
}
nsCOMPtr<nsIFile> eventsDir;
nsresult rv = NS_GetSpecialDirectory("ProfD", getter_AddRefs(eventsDir));
if (NS_SUCCEEDED(rv)) {
SetProfileDirectory(eventsDir);
return;
}
rv = NS_GetSpecialDirectory("UAppData", getter_AddRefs(eventsDir));
if (NS_SUCCEEDED(rv)) {
SetUserAppDataDirectory(eventsDir);
return;
}
NS_WARNING("Couldn't get the user appdata directory. Crash events may not be produced.");
}
bool GetCrashEventsDir(nsAString& aPath)
{
if (!eventsDirectory) {

View File

@ -36,10 +36,19 @@ nsresult UnsetExceptionHandler();
/**
* Tell the crash reporter to recalculate where crash events files should go.
* SetCrashEventsDir is used before XPCOM is initialized from the startup
* code.
*
* This should be called during crash reporter initialization and when a
* profile is activated or deactivated.
* UpdateCrashEventsDir uses the directory service to re-set the
* crash event directory based on the current profile.
*
* 1. If environment variable is present, use it. We don't expect
* the environment variable except for tests and other atypical setups.
* 2. <profile>/crashes/events
* 3. <UAppData>/Crash Reports/events
*/
void SetUserAppDataDirectory(nsIFile* aDir);
void SetProfileDirectory(nsIFile* aDir);
void UpdateCrashEventsDir();
/**

View File

@ -3021,7 +3021,11 @@ XREMain::XRE_mainInit(bool* aExitFlag)
if ((mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER) &&
NS_SUCCEEDED(
CrashReporter::SetExceptionHandler(mAppData->xreDirectory))) {
CrashReporter::UpdateCrashEventsDir();
nsCOMPtr<nsIFile> file;
rv = mDirProvider.GetUserAppDataDirectory(getter_AddRefs(file));
if (NS_SUCCEEDED(rv)) {
CrashReporter::SetUserAppDataDirectory(file);
}
if (mAppData->crashReporterURL)
CrashReporter::SetServerURL(nsDependentCString(mAppData->crashReporterURL));
@ -3676,7 +3680,7 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
if (mAppData->flags & NS_XRE_ENABLE_CRASH_REPORTER)
MakeOrSetMinidumpPath(mProfD);
CrashReporter::UpdateCrashEventsDir();
CrashReporter::SetProfileDirectory(mProfD);
#endif
nsAutoCString version;