diff options
author | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-06 15:53:52 +0200 |
---|---|---|
committer | janekptacijarabaci <janekptacijarabaci@seznam.cz> | 2018-07-06 15:53:52 +0200 |
commit | 941e54654eabed0a3568f7fefe424a45aa02eddb (patch) | |
tree | 49aa02b174c428962d99142d8061267bfcd79e69 /xpcom | |
parent | ad9ee72dcd7981bc47b3844a224d69fadfdfd8ef (diff) | |
parent | 0daa12376295d5d796256a116eb2a348a3a9273f (diff) | |
download | UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.gz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.lz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.tar.xz UXP-941e54654eabed0a3568f7fefe424a45aa02eddb.zip |
Merge branch 'master' of https://github.com/MoonchildProductions/UXP into _testBranch_test_1
Diffstat (limited to 'xpcom')
39 files changed, 480 insertions, 1230 deletions
diff --git a/xpcom/base/nsIMemoryReporter.idl b/xpcom/base/nsIMemoryReporter.idl index 9617877df..babfa646f 100644 --- a/xpcom/base/nsIMemoryReporter.idl +++ b/xpcom/base/nsIMemoryReporter.idl @@ -405,13 +405,6 @@ interface nsIMemoryReporterManager : nsISupports [infallible] readonly attribute boolean hasMozMallocUsableSize; /* - * These attributes indicate DMD's status. "Enabled" means enabled at - * build-time. - */ - [infallible] readonly attribute boolean isDMDEnabled; - [infallible] readonly attribute boolean isDMDRunning; - - /* * Run a series of GC/CC's in an attempt to minimize the application's memory * usage. When we're finished, we invoke the given runnable if it's not * null. @@ -519,23 +512,9 @@ nsresult RegisterNonJSSizeOfTab(NonJSSizeOfTabFn aSizeOfTabFn); } -#if defined(MOZ_DMD) -#if !defined(MOZ_MEMORY) -#error "MOZ_DMD requires MOZ_MEMORY" -#endif - -#include "DMD.h" - -#define MOZ_REPORT(ptr) mozilla::dmd::Report(ptr) -#define MOZ_REPORT_ON_ALLOC(ptr) mozilla::dmd::ReportOnAlloc(ptr) - -#else - #define MOZ_REPORT(ptr) #define MOZ_REPORT_ON_ALLOC(ptr) -#endif // defined(MOZ_DMD) - // Functions generated via this macro should be used by all traversal-based // memory reporters. Such functions return |moz_malloc_size_of(ptr)|; this // will always be zero on some obscure platforms. diff --git a/xpcom/base/nsMemoryInfoDumper.cpp b/xpcom/base/nsMemoryInfoDumper.cpp index 06453b126..afb18382d 100644 --- a/xpcom/base/nsMemoryInfoDumper.cpp +++ b/xpcom/base/nsMemoryInfoDumper.cpp @@ -766,65 +766,3 @@ nsMemoryInfoDumper::DumpMemoryInfoToTempDir(const nsAString& aIdentifier, aAnonymize, aMinimizeMemoryUsage, identifier); } -#ifdef MOZ_DMD -dmd::DMDFuncs::Singleton dmd::DMDFuncs::sSingleton; - -nsresult -nsMemoryInfoDumper::OpenDMDFile(const nsAString& aIdentifier, int aPid, - FILE** aOutFile) -{ - if (!dmd::IsRunning()) { - *aOutFile = nullptr; - return NS_OK; - } - - // Create a filename like dmd-<identifier>-<pid>.json.gz, which will be used - // if DMD is enabled. - nsCString dmdFilename; - MakeFilename("dmd", aIdentifier, aPid, "json.gz", dmdFilename); - - // Open a new DMD file named |dmdFilename| in NS_OS_TEMP_DIR for writing, - // and dump DMD output to it. This must occur after the memory reporters - // have been run (above), but before the memory-reports file has been - // renamed (so scripts can detect the DMD file, if present). - - nsresult rv; - nsCOMPtr<nsIFile> dmdFile; - rv = nsDumpUtils::OpenTempFile(dmdFilename, - getter_AddRefs(dmdFile), - NS_LITERAL_CSTRING("memory-reports")); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - rv = dmdFile->OpenANSIFileDesc("wb", aOutFile); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "OpenANSIFileDesc failed"); - - // Print the path, because on some platforms (e.g. Mac) it's not obvious. - nsCString path; - rv = dmdFile->GetNativePath(path); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - dmd::StatusMsg("opened %s for writing\n", path.get()); - - return rv; -} - -nsresult -nsMemoryInfoDumper::DumpDMDToFile(FILE* aFile) -{ - RefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(); - nsresult rv = gzWriter->InitANSIFileDesc(aFile); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - // Dump DMD's memory reports analysis to the file. - dmd::Analyze(MakeUnique<GZWriterWrapper>(gzWriter)); - - rv = gzWriter->Finish(); - NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Finish failed"); - return rv; -} -#endif // MOZ_DMD - diff --git a/xpcom/base/nsMemoryInfoDumper.h b/xpcom/base/nsMemoryInfoDumper.h index 6bba176f2..281bb3e51 100644 --- a/xpcom/base/nsMemoryInfoDumper.h +++ b/xpcom/base/nsMemoryInfoDumper.h @@ -28,15 +28,6 @@ public: nsMemoryInfoDumper(); static void Initialize(); - -#ifdef MOZ_DMD - // Open an appropriately named file for a DMD report. If DMD is - // disabled, return a null FILE* instead. - static nsresult OpenDMDFile(const nsAString& aIdentifier, int aPid, - FILE** aOutFile); - // Write a DMD report to the given file and close it. - static nsresult DumpDMDToFile(FILE* aFile); -#endif }; #define NS_MEMORY_INFO_DUMPER_CID \ diff --git a/xpcom/base/nsMemoryReporterManager.cpp b/xpcom/base/nsMemoryReporterManager.cpp index aa3d74dfd..2d4f3fa9c 100644 --- a/xpcom/base/nsMemoryReporterManager.cpp +++ b/xpcom/base/nsMemoryReporterManager.cpp @@ -17,7 +17,7 @@ #include "nsIObserverService.h" #include "nsIGlobalObject.h" #include "nsIXPConnect.h" -#if defined(XP_UNIX) || defined(MOZ_DMD) +#if defined(XP_UNIX) #include "nsMemoryInfoDumper.h" #endif #include "mozilla/Attributes.h" @@ -439,13 +439,11 @@ static MOZ_MUST_USE nsresult ResidentDistinguishedAmountHelper(int64_t* aN, bool aDoPurge) { #ifdef HAVE_JEMALLOC_STATS -#ifndef MOZ_JEMALLOC4 if (aDoPurge) { Telemetry::AutoTimer<Telemetry::MEMORY_FREE_PURGED_PAGES_MS> timer; jemalloc_purge_freed_pages(); } #endif -#endif task_basic_info ti; if (!GetTaskBasicInfo(&ti)) { @@ -1427,62 +1425,6 @@ NS_IMPL_ISUPPORTS(DeadlockDetectorReporter, nsIMemoryReporter) #endif -#ifdef MOZ_DMD - -namespace mozilla { -namespace dmd { - -class DMDReporter final : public nsIMemoryReporter -{ -public: - NS_DECL_ISUPPORTS - - NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, - nsISupports* aData, bool aAnonymize) override - { - dmd::Sizes sizes; - dmd::SizeOf(&sizes); - - MOZ_COLLECT_REPORT( - "explicit/dmd/stack-traces/used", KIND_HEAP, UNITS_BYTES, - sizes.mStackTracesUsed, - "Memory used by stack traces which correspond to at least " - "one heap block DMD is tracking."); - - MOZ_COLLECT_REPORT( - "explicit/dmd/stack-traces/unused", KIND_HEAP, UNITS_BYTES, - sizes.mStackTracesUnused, - "Memory used by stack traces which don't correspond to any heap " - "blocks DMD is currently tracking."); - - MOZ_COLLECT_REPORT( - "explicit/dmd/stack-traces/table", KIND_HEAP, UNITS_BYTES, - sizes.mStackTraceTable, - "Memory used by DMD's stack trace table."); - - MOZ_COLLECT_REPORT( - "explicit/dmd/live-block-table", KIND_HEAP, UNITS_BYTES, - sizes.mLiveBlockTable, - "Memory used by DMD's live block table."); - - MOZ_COLLECT_REPORT( - "explicit/dmd/dead-block-list", KIND_HEAP, UNITS_BYTES, - sizes.mDeadBlockTable, - "Memory used by DMD's dead block list."); - - return NS_OK; - } - -private: - ~DMDReporter() {} -}; -NS_IMPL_ISUPPORTS(DMDReporter, nsIMemoryReporter) - -} // namespace dmd -} // namespace mozilla - -#endif // MOZ_DMD - /** ** nsMemoryReporterManager implementation **/ @@ -1562,10 +1504,6 @@ nsMemoryReporterManager::Init() RegisterStrongReporter(new DeadlockDetectorReporter()); #endif -#ifdef MOZ_DMD - RegisterStrongReporter(new mozilla::dmd::DMDReporter()); -#endif - #ifdef XP_WIN RegisterStrongReporter(new WindowsAddressSpaceReporter()); #endif @@ -1598,10 +1536,6 @@ nsMemoryReporterManager::~nsMemoryReporterManager() NS_ASSERTION(!mSavedWeakReporters, "failed to restore weak reporters"); } -#ifdef MOZ_WIDGET_GONK -#define DEBUG_CHILD_PROCESS_MEMORY_REPORTING 1 -#endif - #ifdef DEBUG_CHILD_PROCESS_MEMORY_REPORTING #define MEMORY_REPORTING_LOG(format, ...) \ printf_stderr("++++ MEMORY REPORTING: " format, ##__VA_ARGS__); @@ -1685,22 +1619,9 @@ nsMemoryReporterManager::StartGettingReports() PendingProcessesState* s = mPendingProcessesState; nsresult rv; - // Get reports for this process. - FILE* parentDMDFile = nullptr; -#ifdef MOZ_DMD - if (!s->mDMDDumpIdent.IsEmpty()) { - rv = nsMemoryInfoDumper::OpenDMDFile(s->mDMDDumpIdent, getpid(), - &parentDMDFile); - if (NS_WARN_IF(NS_FAILED(rv))) { - // Proceed with the memory report as if DMD were disabled. - parentDMDFile = nullptr; - } - } -#endif - // This is async. GetReportsForThisProcessExtended(s->mHandleReport, s->mHandleReportData, - s->mAnonymize, parentDMDFile, + s->mAnonymize, nullptr, s->mFinishReporting, s->mFinishReportingData); nsTArray<ContentParent*> childWeakRefs; @@ -1781,16 +1702,6 @@ nsMemoryReporterManager::GetReportsForThisProcessExtended( return NS_ERROR_IN_PROGRESS; } -#ifdef MOZ_DMD - if (aDMDFile) { - // Clear DMD's reportedness state before running the memory - // reporters, to avoid spurious twice-reported warnings. - dmd::ClearReports(); - } -#else - MOZ_ASSERT(!aDMDFile); -#endif - mPendingReportersState = new PendingReportersState( aFinishReporting, aFinishReportingData, aDMDFile); @@ -1816,11 +1727,6 @@ NS_IMETHODIMP nsMemoryReporterManager::EndReport() { if (--mPendingReportersState->mReportsPending == 0) { -#ifdef MOZ_DMD - if (mPendingReportersState->mDMDFile) { - nsMemoryInfoDumper::DumpDMDToFile(mPendingReportersState->mDMDFile); - } -#endif if (mPendingProcessesState) { // This is the parent process. EndProcessReport(mPendingProcessesState->mGeneration, true); @@ -1908,24 +1814,8 @@ nsMemoryReporterManager::StartChildReport(mozilla::dom::ContentParent* aChild, return false; } - mozilla::dom::MaybeFileDesc dmdFileDesc = void_t(); -#ifdef MOZ_DMD - if (!aState->mDMDDumpIdent.IsEmpty()) { - FILE *dmdFile = nullptr; - nsresult rv = nsMemoryInfoDumper::OpenDMDFile(aState->mDMDDumpIdent, - aChild->Pid(), &dmdFile); - if (NS_WARN_IF(NS_FAILED(rv))) { - // Proceed with the memory report as if DMD were disabled. - dmdFile = nullptr; - } - if (dmdFile) { - dmdFileDesc = mozilla::ipc::FILEToFileDescriptor(dmdFile); - fclose(dmdFile); - } - } -#endif return aChild->SendPMemoryReportRequestConstructor( - aState->mGeneration, aState->mAnonymize, aState->mMinimize, dmdFileDesc); + aState->mGeneration, aState->mAnonymize, aState->mMinimize, void_t()); } void @@ -2458,28 +2348,6 @@ nsMemoryReporterManager::GetHasMozMallocUsableSize(bool* aHas) return NS_OK; } -NS_IMETHODIMP -nsMemoryReporterManager::GetIsDMDEnabled(bool* aIsEnabled) -{ -#ifdef MOZ_DMD - *aIsEnabled = true; -#else - *aIsEnabled = false; -#endif - return NS_OK; -} - -NS_IMETHODIMP -nsMemoryReporterManager::GetIsDMDRunning(bool* aIsRunning) -{ -#ifdef MOZ_DMD - *aIsRunning = dmd::IsRunning(); -#else - *aIsRunning = false; -#endif - return NS_OK; -} - namespace { /** diff --git a/xpcom/base/nsSystemInfo.cpp b/xpcom/base/nsSystemInfo.cpp index f6d9fd5ad..4a92a2eb4 100644 --- a/xpcom/base/nsSystemInfo.cpp +++ b/xpcom/base/nsSystemInfo.cpp @@ -50,12 +50,6 @@ #include "mozilla/dom/ContentChild.h" #endif -#ifdef MOZ_WIDGET_GONK -#include <sys/system_properties.h> -#include "mozilla/Preferences.h" -#include "nsPrintfCString.h" -#endif - #ifdef ANDROID extern "C" { NS_EXPORT int android_sdk_version; @@ -66,10 +60,6 @@ NS_EXPORT int android_sdk_version; #include <sys/sysctl.h> #endif -#if defined(XP_LINUX) && defined(MOZ_SANDBOX) -#include "mozilla/SandboxInfo.h" -#endif - // Slot for NS_InitXPCOM2 to pass information to nsSystemInfo::Init. // Only set to nonzero (potentially) if XP_UNIX. On such systems, the // system call to discover the appropriate value is not thread-safe, @@ -751,67 +741,6 @@ nsSystemInfo::Init() } #endif -#ifdef MOZ_WIDGET_GONK - char sdk[PROP_VALUE_MAX]; - if (__system_property_get("ro.build.version.sdk", sdk)) { - android_sdk_version = atoi(sdk); - SetPropertyAsInt32(NS_LITERAL_STRING("sdk_version"), android_sdk_version); - - SetPropertyAsACString(NS_LITERAL_STRING("secondaryLibrary"), - nsPrintfCString("SDK %u", android_sdk_version)); - } - - char characteristics[PROP_VALUE_MAX]; - if (__system_property_get("ro.build.characteristics", characteristics)) { - if (!strcmp(characteristics, "tablet")) { - SetPropertyAsBool(NS_LITERAL_STRING("tablet"), true); - } else if (!strcmp(characteristics, "tv")) { - SetPropertyAsBool(NS_LITERAL_STRING("tv"), true); - } - } - - nsAutoString str; - rv = GetPropertyAsAString(NS_LITERAL_STRING("version"), str); - if (NS_SUCCEEDED(rv)) { - SetPropertyAsAString(NS_LITERAL_STRING("kernel_version"), str); - } - - const nsAdoptingString& b2g_os_name = - mozilla::Preferences::GetString("b2g.osName"); - if (b2g_os_name) { - SetPropertyAsAString(NS_LITERAL_STRING("name"), b2g_os_name); - } - - const nsAdoptingString& b2g_version = - mozilla::Preferences::GetString("b2g.version"); - if (b2g_version) { - SetPropertyAsAString(NS_LITERAL_STRING("version"), b2g_version); - } -#endif - -#if defined(XP_LINUX) && defined(MOZ_SANDBOX) - SandboxInfo sandInfo = SandboxInfo::Get(); - - SetPropertyAsBool(NS_LITERAL_STRING("hasSeccompBPF"), - sandInfo.Test(SandboxInfo::kHasSeccompBPF)); - SetPropertyAsBool(NS_LITERAL_STRING("hasSeccompTSync"), - sandInfo.Test(SandboxInfo::kHasSeccompTSync)); - SetPropertyAsBool(NS_LITERAL_STRING("hasUserNamespaces"), - sandInfo.Test(SandboxInfo::kHasUserNamespaces)); - SetPropertyAsBool(NS_LITERAL_STRING("hasPrivilegedUserNamespaces"), - sandInfo.Test(SandboxInfo::kHasPrivilegedUserNamespaces)); - - if (sandInfo.Test(SandboxInfo::kEnabledForContent)) { - SetPropertyAsBool(NS_LITERAL_STRING("canSandboxContent"), - sandInfo.CanSandboxContent()); - } - - if (sandInfo.Test(SandboxInfo::kEnabledForMedia)) { - SetPropertyAsBool(NS_LITERAL_STRING("canSandboxMedia"), - sandInfo.CanSandboxMedia()); - } -#endif // XP_LINUX && MOZ_SANDBOX - return NS_OK; } diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp index 3b415174b..da51305a9 100644 --- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -42,11 +42,6 @@ #include <dlfcn.h> #endif -#ifdef MOZ_DMD -#include "base/process_util.h" -#include "nsMemoryInfoDumper.h" -#endif - //////////////////////////////////////////////////////////////////////////////// #include "plhash.h" @@ -936,39 +931,6 @@ NS_LogTerm() mozilla::LogTerm(); } -#ifdef MOZ_DMD -// If MOZ_DMD_SHUTDOWN_LOG is set, dump a DMD report to a file. -// The value of this environment variable is used as the prefix -// of the file name, so you probably want something like "/tmp/". -// By default, this is run in all processes, but you can record a -// log only for a specific process type by setting MOZ_DMD_LOG_PROCESS -// to the process type you want to log, such as "default" or "tab". -// This method can't use the higher level XPCOM file utilities -// because it is run very late in shutdown to avoid recording -// information about refcount logging entries. -static void -LogDMDFile() -{ - const char* dmdFilePrefix = PR_GetEnv("MOZ_DMD_SHUTDOWN_LOG"); - if (!dmdFilePrefix) { - return; - } - - const char* logProcessEnv = PR_GetEnv("MOZ_DMD_LOG_PROCESS"); - if (logProcessEnv && !!strcmp(logProcessEnv, XRE_ChildProcessTypeToString(XRE_GetProcessType()))) { - return; - } - - nsPrintfCString fileName("%sdmd-%d.log.gz", dmdFilePrefix, base::GetCurrentProcId()); - FILE* logFile = fopen(fileName.get(), "w"); - if (NS_WARN_IF(!logFile)) { - return; - } - - nsMemoryInfoDumper::DumpDMDToFile(logFile); -} -#endif // MOZ_DMD - namespace mozilla { void LogTerm() @@ -1000,10 +962,6 @@ LogTerm() nsTraceRefcnt::Shutdown(); nsTraceRefcnt::SetActivityIsLegal(false); gActivityTLS = BAD_TLS_INDEX; - -#ifdef MOZ_DMD - LogDMDFile(); -#endif } } diff --git a/xpcom/build/BinaryPath.h b/xpcom/build/BinaryPath.h index 374763c79..53034fcd8 100644 --- a/xpcom/build/BinaryPath.h +++ b/xpcom/build/BinaryPath.h @@ -90,11 +90,6 @@ private: // On Android, we use the GRE_HOME variable that is set by the Java // bootstrap code. const char* greHome = getenv("GRE_HOME"); -#if defined(MOZ_WIDGET_GONK) - if (!greHome) { - greHome = "/system/b2g"; - } -#endif if (!greHome) { return NS_ERROR_FAILURE; diff --git a/xpcom/build/XPCOMInit.cpp b/xpcom/build/XPCOMInit.cpp index 6ead5cdc7..e8ee5828a 100644 --- a/xpcom/build/XPCOMInit.cpp +++ b/xpcom/build/XPCOMInit.cpp @@ -171,9 +171,7 @@ extern nsresult nsStringInputStreamConstructor(nsISupports*, REFNSIID, void**); #include "gfxPlatform.h" -#if EXPOSE_INTL_API #include "unicode/putil.h" -#endif using namespace mozilla; using base::AtExitManager; @@ -689,7 +687,7 @@ NS_InitXPCOM2(nsIServiceManager** aResult, memmove); #endif -#if EXPOSE_INTL_API && defined(MOZ_ICU_DATA_ARCHIVE) +#if defined(MOZ_ICU_DATA_ARCHIVE) nsCOMPtr<nsIFile> greDir; nsDirectoryService::gService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), @@ -1039,20 +1037,6 @@ ShutdownXPCOM(nsIServiceManager* aServMgr) NS_WARNING("Component Manager was never created ..."); } -#ifdef MOZ_ENABLE_PROFILER_SPS - // In optimized builds we don't do shutdown collections by default, so - // uncollected (garbage) objects may keep the nsXPConnect singleton alive, - // and its XPCJSContext along with it. However, we still destroy various - // bits of state in JS_ShutDown(), so we need to make sure the profiler - // can't access them when it shuts down. This call nulls out the - // JS pseudo-stack's internal reference to the main thread JSContext, - // duplicating the call in XPCJSContext::~XPCJSContext() in case that - // never fired. - if (PseudoStack* stack = mozilla_get_pseudo_stack()) { - stack->sampleContext(nullptr); - } -#endif - if (sInitializedJS) { // Shut down the JS engine. JS_ShutDown(); @@ -1106,17 +1090,6 @@ ShutdownXPCOM(nsIServiceManager* aServMgr) NS_LogTerm(); -#if defined(MOZ_WIDGET_GONK) - // This _exit(0) call is intended to be temporary, to get shutdown leak - // checking working on non-B2G platforms. - // On debug B2G, the child process crashes very late. Instead, just - // give up so at least we exit cleanly. See bug 1071866. - if (XRE_IsContentProcess()) { - NS_WARNING("Exiting child process early!"); - _exit(0); - } -#endif - return NS_OK; } diff --git a/xpcom/build/XREChildData.h b/xpcom/build/XREChildData.h index 487fede94..c849131d6 100644 --- a/xpcom/build/XREChildData.h +++ b/xpcom/build/XREChildData.h @@ -9,14 +9,6 @@ #include "mozilla/UniquePtr.h" -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -#include "mozilla/sandboxing/loggingTypes.h" - -namespace sandbox { -class TargetServices; -} -#endif - namespace mozilla { namespace gmp { class GMPLoader; @@ -28,24 +20,13 @@ class GMPLoader; */ struct XREChildData { -#if !defined(MOZ_WIDGET_ANDROID) && !defined(MOZ_WIDGET_GONK) +#if !defined(MOZ_WIDGET_ANDROID) /** * Used to load the GMP binary. */ mozilla::UniquePtr<mozilla::gmp::GMPLoader> gmpLoader; #endif -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - /** - * Chromium sandbox TargetServices. - */ - sandbox::TargetServices* sandboxTargetServices = nullptr; - - /** - * Function to provide a logging function to the chromium sandbox code. - */ - mozilla::sandboxing::ProvideLogFunctionCb ProvideLogFunction = nullptr; -#endif }; #endif // XREChildData_h diff --git a/xpcom/build/XREShellData.h b/xpcom/build/XREShellData.h deleted file mode 100644 index 11bc162d9..000000000 --- a/xpcom/build/XREShellData.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* 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/. */ - -#ifndef XREShellData_h -#define XREShellData_h - -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -namespace sandbox { -class BrokerServices; -} -#endif - -/** - * Data needed by XRE_XPCShellMain. - */ -struct XREShellData -{ -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - /** - * Chromium sandbox BrokerServices. - */ - sandbox::BrokerServices* sandboxBrokerServices; -#endif -}; - -#endif // XREShellData_h diff --git a/xpcom/build/moz.build b/xpcom/build/moz.build index 68bd001a2..e0adba0a2 100644 --- a/xpcom/build/moz.build +++ b/xpcom/build/moz.build @@ -12,7 +12,6 @@ EXPORTS += [ 'nsXULAppAPI.h', 'XREChildData.h', 'xrecore.h', - 'XREShellData.h', ] EXPORTS.mozilla += [ diff --git a/xpcom/build/nsXREAppData.h b/xpcom/build/nsXREAppData.h index fbc7adb8f..129336ac9 100644 --- a/xpcom/build/nsXREAppData.h +++ b/xpcom/build/nsXREAppData.h @@ -12,12 +12,6 @@ class nsIFile; -#if defined(XP_WIN) && defined(MOZ_SANDBOX) -namespace sandbox { -class BrokerServices; -} -#endif - /** * Application-specific data needed to start the apprunner. * @@ -134,13 +128,6 @@ struct nsXREAppData * The application name to use in the User Agent string. */ const char* UAName; - -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - /** - * Chromium sandbox BrokerServices. - */ - sandbox::BrokerServices* sandboxBrokerServices; -#endif }; /** diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index aae248ca1..c077c7e36 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -20,7 +20,6 @@ #include "mozilla/Vector.h" #include "mozilla/TimeStamp.h" #include "XREChildData.h" -#include "XREShellData.h" /** * A directory service key which provides the platform-correct "application @@ -504,8 +503,7 @@ XRE_API(void, XRE_EnableSameExecutableForContentProc, ()) XRE_API(int, - XRE_XPCShellMain, (int argc, char** argv, char** envp, - const XREShellData* aShellData)) + XRE_XPCShellMain, (int argc, char** argv, char** envp)) #if MOZ_WIDGET_GTK == 2 XRE_API(void, diff --git a/xpcom/glue/AppData.cpp b/xpcom/glue/AppData.cpp index 845267e60..2fdb6b009 100644 --- a/xpcom/glue/AppData.cpp +++ b/xpcom/glue/AppData.cpp @@ -65,10 +65,6 @@ ScopedAppData::ScopedAppData(const nsXREAppData* aAppData) if (aAppData->size > offsetof(nsXREAppData, UAName)) { SetAllocatedString(this->UAName, aAppData->UAName); } - -#if defined(XP_WIN) && defined(MOZ_SANDBOX) - sandboxBrokerServices = aAppData->sandboxBrokerServices; -#endif } ScopedAppData::~ScopedAppData() diff --git a/xpcom/glue/FileUtils.h b/xpcom/glue/FileUtils.h index aaf912b21..b808d52e0 100644 --- a/xpcom/glue/FileUtils.h +++ b/xpcom/glue/FileUtils.h @@ -161,7 +161,7 @@ void ReadAhead(filedesc_t aFd, const size_t aOffset = 0, const size_t aCount = SIZE_MAX); -#if defined(MOZ_WIDGET_GONK) || defined(XP_UNIX) +#if defined(XP_UNIX) #define MOZ_TEMP_FAILURE_RETRY(exp) (__extension__({ \ typeof (exp) _rc; \ do { \ @@ -171,10 +171,9 @@ void ReadAhead(filedesc_t aFd, const size_t aOffset = 0, })) #endif -/* Define ReadSysFile() and WriteSysFile() only on GONK to avoid unnecessary - * libxul bloat. Also define it in debug builds, so that unit tests for it can - * be written and run in non-GONK builds. */ -#if (defined(MOZ_WIDGET_GONK) || defined(DEBUG)) && defined(XP_UNIX) +/* Define ReadSysFile() and WriteSysFile() only in debug builds, so that + * unit tests for it can be written and run. */ +#if defined(DEBUG) && defined(XP_UNIX) #ifndef ReadSysFile_PRESENT #define ReadSysFile_PRESENT @@ -213,7 +212,7 @@ bool ReadSysFile(const char* aFilename, bool* aVal); bool WriteSysFile(const char* aFilename, const char* aBuf); -#endif /* (MOZ_WIDGET_GONK || DEBUG) && XP_UNIX */ +#endif /* DEBUG && XP_UNIX */ } // namespace mozilla diff --git a/xpcom/glue/PLDHashTable.cpp b/xpcom/glue/PLDHashTable.cpp index 6152e9000..5e932ccb2 100644 --- a/xpcom/glue/PLDHashTable.cpp +++ b/xpcom/glue/PLDHashTable.cpp @@ -216,17 +216,17 @@ PLDHashTable::operator=(PLDHashTable&& aOther) return *this; } - // Destruct |this|. - this->~PLDHashTable(); - - // |mOps| and |mEntrySize| are const so we can't assign them. Instead, we - // require that they are equal. The justification for this is that they're + // |mOps| and |mEntrySize| are required to stay the same, they're // conceptually part of the type -- indeed, if PLDHashTable was a templated // type like nsTHashtable, they *would* be part of the type -- so it only // makes sense to assign in cases where they match. MOZ_RELEASE_ASSERT(mOps == aOther.mOps); MOZ_RELEASE_ASSERT(mEntrySize == aOther.mEntrySize); + // Reconstruct |this|. + this->~PLDHashTable(); + new (KnownNotNull, this) PLDHashTable(aOther.mOps, aOther.mEntrySize, 0); + // Move non-const pieces over. mHashShift = Move(aOther.mHashShift); mEntryCount = Move(aOther.mEntryCount); diff --git a/xpcom/idl-parser/xpidl/xpidl.py b/xpcom/idl-parser/xpidl/xpidl.py index 8b2d8c884..6bb1ad5de 100755 --- a/xpcom/idl-parser/xpidl/xpidl.py +++ b/xpcom/idl-parser/xpidl/xpidl.py @@ -529,7 +529,7 @@ class Interface(object): raise IDLError("interface '%s' inherits from non-interface type '%s'" % (self.name, self.base), self.location) if self.attributes.scriptable and not realbase.attributes.scriptable: - print >>sys.stderr, IDLError("interface '%s' is scriptable but derives from non-scriptable '%s'" % (self.name, self.base), self.location, warning=True) + raise IDLError("interface '%s' is scriptable but derives from non-scriptable '%s'" % (self.name, self.base), self.location, warning=True) if self.attributes.scriptable and realbase.attributes.builtinclass and not self.attributes.builtinclass: raise IDLError("interface '%s' is not builtinclass but derives from builtinclass '%s'" % (self.name, self.base), self.location) diff --git a/xpcom/io/FilePreferences.cpp b/xpcom/io/FilePreferences.cpp new file mode 100644 index 000000000..ef942beb2 --- /dev/null +++ b/xpcom/io/FilePreferences.cpp @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "FilePreferences.h" + +#include "mozilla/Preferences.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsString.h" + +namespace mozilla { +namespace FilePreferences { + +static bool sBlockUNCPaths = false; +typedef nsTArray<nsString> Paths; + +static Paths& PathArray() +{ + static Paths sPaths; + return sPaths; +} + +static void AllowDirectory(char const* directory) +{ + nsCOMPtr<nsIFile> file; + NS_GetSpecialDirectory(directory, getter_AddRefs(file)); + if (!file) { + return; + } + + nsString path; + if (NS_FAILED(file->GetTarget(path))) { + return; + } + + // The whitelist makes sense only for UNC paths, because this code is used + // to block only UNC paths, hence, no need to add non-UNC directories here + // as those would never pass the check. + if (!StringBeginsWith(path, NS_LITERAL_STRING("\\\\"))) { + return; + } + + if (!PathArray().Contains(path)) { + PathArray().AppendElement(path); + } +} + +void InitPrefs() +{ + sBlockUNCPaths = Preferences::GetBool("network.file.disable_unc_paths", false); +} + +void InitDirectoriesWhitelist() +{ + // NS_GRE_DIR is the installation path where the binary resides. + AllowDirectory(NS_GRE_DIR); + // NS_APP_USER_PROFILE_50_DIR and NS_APP_USER_PROFILE_LOCAL_50_DIR are the two + // parts of the profile we store permanent and local-specific data. + AllowDirectory(NS_APP_USER_PROFILE_50_DIR); + AllowDirectory(NS_APP_USER_PROFILE_LOCAL_50_DIR); +} + +namespace { // anon + +class Normalizer +{ +public: + Normalizer(const nsAString& aFilePath, const char16_t aSeparator); + bool Get(nsAString& aNormalizedFilePath); + +private: + bool ConsumeItem(); + bool ConsumeSeparator(); + bool IsEOF() { return mFilePathCursor == mFilePathEnd; } + + bool ConsumeName(); + bool CheckParentDir(); + bool CheckCurrentDir(); + + nsString::const_char_iterator mFilePathCursor; + nsString::const_char_iterator mFilePathEnd; + + nsDependentSubstring mItem; + char16_t const mSeparator; + nsTArray<nsDependentSubstring> mStack; +}; + +Normalizer::Normalizer(const nsAString& aFilePath, const char16_t aSeparator) + : mFilePathCursor(aFilePath.BeginReading()) + , mFilePathEnd(aFilePath.EndReading()) + , mSeparator(aSeparator) +{ +} + +bool Normalizer::ConsumeItem() +{ + if (IsEOF()) { + return false; + } + + nsString::const_char_iterator nameBegin = mFilePathCursor; + while (mFilePathCursor != mFilePathEnd) { + if (*mFilePathCursor == mSeparator) { + break; // don't include the separator + } + ++mFilePathCursor; + } + + mItem.Rebind(nameBegin, mFilePathCursor); + return true; +} + +bool Normalizer::ConsumeSeparator() +{ + if (IsEOF()) { + return false; + } + + if (*mFilePathCursor != mSeparator) { + return false; + } + + ++mFilePathCursor; + return true; +} + +bool Normalizer::Get(nsAString& aNormalizedFilePath) +{ + aNormalizedFilePath.Truncate(); + + if (IsEOF()) { + return true; + } + if (ConsumeSeparator()) { + aNormalizedFilePath.Append(mSeparator); + } + + if (IsEOF()) { + return true; + } + if (ConsumeSeparator()) { + aNormalizedFilePath.Append(mSeparator); + } + + while (!IsEOF()) { + if (!ConsumeName()) { + return false; + } + } + + for (auto const& name : mStack) { + aNormalizedFilePath.Append(name); + } + + return true; +} + +bool Normalizer::ConsumeName() +{ + if (!ConsumeItem()) { + return true; + } + + if (CheckCurrentDir()) { + return true; + } + + if (CheckParentDir()) { + if (!mStack.Length()) { + // This means there are more \.. than valid names + return false; + } + + mStack.RemoveElementAt(mStack.Length() - 1); + return true; + } + + if (mItem.IsEmpty()) { + // this means an empty name (a lone slash), which is illegal + return false; + } + + if (ConsumeSeparator()) { + mItem.Rebind(mItem.BeginReading(), mFilePathCursor); + } + mStack.AppendElement(mItem); + + return true; +} + +bool Normalizer::CheckCurrentDir() +{ + if (mItem == NS_LITERAL_STRING(".")) { + ConsumeSeparator(); + // EOF is acceptable + return true; + } + + return false; +} + +bool Normalizer::CheckParentDir() +{ + if (mItem == NS_LITERAL_STRING("..")) { + ConsumeSeparator(); + // EOF is acceptable + return true; + } + + return false; +} + +} // anon + +bool IsBlockedUNCPath(const nsAString& aFilePath) +{ + if (!sBlockUNCPaths) { + return false; + } + + if (!StringBeginsWith(aFilePath, NS_LITERAL_STRING("\\\\"))) { + return false; + } + + nsAutoString normalized; + if (!Normalizer(aFilePath, L'\\').Get(normalized)) { + // Broken paths are considered invalid and thus inaccessible + return true; + } + + for (const auto& allowedPrefix : PathArray()) { + if (StringBeginsWith(normalized, allowedPrefix)) { + if (normalized.Length() == allowedPrefix.Length()) { + return false; + } + if (normalized[allowedPrefix.Length()] == L'\\') { + return false; + } + + // When we are here, the path has a form "\\path\prefixevil" + // while we have an allowed prefix of "\\path\prefix". + // Note that we don't want to add a slash to the end of a prefix + // so that opening the directory (no slash at the end) still works. + break; + } + } + + return true; +} + +void testing::SetBlockUNCPaths(bool aBlock) +{ + sBlockUNCPaths = aBlock; +} + +void testing::AddDirectoryToWhitelist(nsAString const & aPath) +{ + PathArray().AppendElement(aPath); +} + +bool testing::NormalizePath(nsAString const & aPath, nsAString & aNormalized) +{ + Normalizer normalizer(aPath, L'\\'); + return normalizer.Get(aNormalized); +} + +} // ::FilePreferences +} // ::mozilla diff --git a/xpcom/io/FilePreferences.h b/xpcom/io/FilePreferences.h new file mode 100644 index 000000000..fa281f9e6 --- /dev/null +++ b/xpcom/io/FilePreferences.h @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "nsIObserver.h" + +namespace mozilla { +namespace FilePreferences { + +void InitPrefs(); +void InitDirectoriesWhitelist(); +bool IsBlockedUNCPath(const nsAString& aFilePath); + +namespace testing { + +void SetBlockUNCPaths(bool aBlock); +void AddDirectoryToWhitelist(nsAString const& aPath); +bool NormalizePath(nsAString const & aPath, nsAString & aNormalized); + +} + +} // FilePreferences +} // mozilla diff --git a/xpcom/io/SpecialSystemDirectory.cpp b/xpcom/io/SpecialSystemDirectory.cpp index ab65d38f9..158431088 100644 --- a/xpcom/io/SpecialSystemDirectory.cpp +++ b/xpcom/io/SpecialSystemDirectory.cpp @@ -705,12 +705,6 @@ GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory, } return rv; } -#if defined(MOZ_CONTENT_SANDBOX) - case Win_LocalAppdataLow: { - GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow; - return GetKnownFolder(&localAppDataLowGuid, aFile); - } -#endif case Win_Documents: { return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS, FOLDERID_DocumentsLibrary, diff --git a/xpcom/io/SpecialSystemDirectory.h b/xpcom/io/SpecialSystemDirectory.h index 7c7f8fa42..b1ce31b74 100644 --- a/xpcom/io/SpecialSystemDirectory.h +++ b/xpcom/io/SpecialSystemDirectory.h @@ -76,9 +76,6 @@ enum SystemDirectories { Win_Pictures = 233, Win_Music = 234, Win_Videos = 235, -#if defined(MOZ_CONTENT_SANDBOX) - Win_LocalAppdataLow = 236, -#endif Unix_LocalDirectory = 301, Unix_LibDirectory = 302, diff --git a/xpcom/io/moz.build b/xpcom/io/moz.build index 6f21e0a72..fdefa841b 100644 --- a/xpcom/io/moz.build +++ b/xpcom/io/moz.build @@ -84,6 +84,7 @@ EXPORTS += [ EXPORTS.mozilla += [ 'Base64.h', + 'FilePreferences.h', 'SnappyCompressOutputStream.h', 'SnappyFrameUtils.h', 'SnappyUncompressInputStream.h', @@ -119,6 +120,10 @@ UNIFIED_SOURCES += [ 'SpecialSystemDirectory.cpp', ] +SOURCES += [ + 'FilePreferences.cpp', +] + if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': SOURCES += [ 'CocoaFileUtils.mm', diff --git a/xpcom/io/nsAppDirectoryServiceDefs.h b/xpcom/io/nsAppDirectoryServiceDefs.h index aa0a68816..3da85c987 100644 --- a/xpcom/io/nsAppDirectoryServiceDefs.h +++ b/xpcom/io/nsAppDirectoryServiceDefs.h @@ -84,35 +84,6 @@ #define NS_APP_PERMISSION_PARENT_DIR "permissionDBPDir" -#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) -// -// NS_APP_CONTENT_PROCESS_TEMP_DIR refers to a directory that is read and -// write accessible from a sandboxed content process. The key may be used in -// either process, but the directory is intended to be used for short-lived -// files that need to be saved to the filesystem by the content process and -// don't need to survive browser restarts. The directory is reset on startup. -// The key is only valid when MOZ_CONTENT_SANDBOX is defined. When -// MOZ_CONTENT_SANDBOX is defined, the directory the key refers to differs -// depending on whether or not content sandboxing is enabled. -// -// When MOZ_CONTENT_SANDBOX is defined and sandboxing is enabled (versus -// manually disabled via prefs), the content process replaces NS_OS_TEMP_DIR -// with NS_APP_CONTENT_PROCESS_TEMP_DIR so that legacy code in content -// attempting to write to NS_OS_TEMP_DIR will write to -// NS_APP_CONTENT_PROCESS_TEMP_DIR instead. When MOZ_CONTENT_SANDBOX is -// defined but sandboxing is disabled, NS_APP_CONTENT_PROCESS_TEMP_DIR -// falls back to NS_OS_TEMP_DIR in both content and chrome processes. -// -// New code should avoid writing to the filesystem from the content process -// and should instead proxy through the parent process whenever possible. -// -// At present, all sandboxed content processes use the same directory for -// NS_APP_CONTENT_PROCESS_TEMP_DIR, but that should not be relied upon. -// -#define NS_APP_CONTENT_PROCESS_TEMP_DIR "ContentTmpD" -#else -// Otherwise NS_APP_CONTENT_PROCESS_TEMP_DIR must match NS_OS_TEMP_DIR. #define NS_APP_CONTENT_PROCESS_TEMP_DIR "TmpD" -#endif // (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) #endif // nsAppDirectoryServiceDefs_h___ diff --git a/xpcom/io/nsDirectoryService.cpp b/xpcom/io/nsDirectoryService.cpp index a4d962395..cfcce096d 100644 --- a/xpcom/io/nsDirectoryService.cpp +++ b/xpcom/io/nsDirectoryService.cpp @@ -490,27 +490,6 @@ nsDirectoryService::UnregisterProvider(nsIDirectoryServiceProvider* aProv) return NS_OK; } -#if defined(MOZ_CONTENT_SANDBOX) && defined(XP_WIN) -static nsresult -GetLowIntegrityTempBase(nsIFile** aLowIntegrityTempBase) -{ - nsCOMPtr<nsIFile> localFile; - nsresult rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, - getter_AddRefs(localFile)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - rv = localFile->Append(NS_LITERAL_STRING(MOZ_USER_DIR)); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } - - localFile.forget(aLowIntegrityTempBase); - return rv; -} -#endif - // DO NOT ADD ANY LOCATIONS TO THIS FUNCTION UNTIL YOU TALK TO: dougt@netscape.com. // This is meant to be a place of xpcom or system specific file locations, not // application specific locations. If you need the later, register a callback for @@ -684,12 +663,6 @@ nsDirectoryService::GetFile(const char* aProp, bool* aPersistent, rv = GetSpecialSystemDirectory(Win_Appdata, getter_AddRefs(localFile)); } else if (inAtom == nsDirectoryService::sLocalAppdata) { rv = GetSpecialSystemDirectory(Win_LocalAppdata, getter_AddRefs(localFile)); -#if defined(MOZ_CONTENT_SANDBOX) - } else if (inAtom == nsDirectoryService::sLocalAppdataLow) { - rv = GetSpecialSystemDirectory(Win_LocalAppdataLow, getter_AddRefs(localFile)); - } else if (inAtom == nsDirectoryService::sLowIntegrityTempBase) { - rv = GetLowIntegrityTempBase(getter_AddRefs(localFile)); -#endif } else if (inAtom == nsDirectoryService::sPrinthood) { rv = GetSpecialSystemDirectory(Win_Printhood, getter_AddRefs(localFile)); } else if (inAtom == nsDirectoryService::sWinCookiesDirectory) { diff --git a/xpcom/io/nsDirectoryServiceAtomList.h b/xpcom/io/nsDirectoryServiceAtomList.h index 38a2f0e9d..f636f60d8 100644 --- a/xpcom/io/nsDirectoryServiceAtomList.h +++ b/xpcom/io/nsDirectoryServiceAtomList.h @@ -72,10 +72,6 @@ DIR_ATOM(sCommon_Desktopdirectory, NS_WIN_COMMON_DESKTOP_DIRECTORY) DIR_ATOM(sCommon_AppData, NS_WIN_COMMON_APPDATA_DIR) DIR_ATOM(sAppdata, NS_WIN_APPDATA_DIR) DIR_ATOM(sLocalAppdata, NS_WIN_LOCAL_APPDATA_DIR) -#if defined(MOZ_CONTENT_SANDBOX) -DIR_ATOM(sLocalAppdataLow, NS_WIN_LOCAL_APPDATA_LOW_DIR) -DIR_ATOM(sLowIntegrityTempBase, NS_WIN_LOW_INTEGRITY_TEMP_BASE) -#endif DIR_ATOM(sPrinthood, NS_WIN_PRINTHOOD) DIR_ATOM(sWinCookiesDirectory, NS_WIN_COOKIES_DIR) DIR_ATOM(sDefaultDownloadDirectory, NS_WIN_DEFAULT_DOWNLOAD_DIR) diff --git a/xpcom/io/nsDirectoryServiceDefs.h b/xpcom/io/nsDirectoryServiceDefs.h index 0bdc5e390..4c62e0a7c 100644 --- a/xpcom/io/nsDirectoryServiceDefs.h +++ b/xpcom/io/nsDirectoryServiceDefs.h @@ -129,10 +129,6 @@ #define NS_WIN_COMMON_APPDATA_DIR "CmAppData" #define NS_WIN_APPDATA_DIR "AppData" #define NS_WIN_LOCAL_APPDATA_DIR "LocalAppData" -#if defined(MOZ_CONTENT_SANDBOX) - #define NS_WIN_LOCAL_APPDATA_LOW_DIR "LocalAppDataLow" - #define NS_WIN_LOW_INTEGRITY_TEMP_BASE "LowTmpDBase" -#endif #define NS_WIN_PRINTHOOD "PrntHd" #define NS_WIN_COOKIES_DIR "CookD" #define NS_WIN_DEFAULT_DOWNLOAD_DIR "DfltDwnld" diff --git a/xpcom/io/nsEscape.cpp b/xpcom/io/nsEscape.cpp index f16edc4ce..117e20d60 100644 --- a/xpcom/io/nsEscape.cpp +++ b/xpcom/io/nsEscape.cpp @@ -346,7 +346,7 @@ static const uint32_t EscapeChars[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x - 0,1023, 0, 512,1023, 0,1023, 112,1023,1023,1023,1023,1023,1023, 953, 784, // 2x !"#$%&'()*+,-./ + 0,1023, 0, 512,1023, 0,1023, 624,1023,1023,1023,1023,1023,1023, 953, 784, // 2x !"#$%&'()*+,-./ 1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1008,1008, 0,1008, 0, 768, // 3x 0123456789:;<=>? 1008,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, // 4x @ABCDEFGHIJKLMNO 1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1008, 896,1008, 896,1023, // 5x PQRSTUVWXYZ[\]^_ diff --git a/xpcom/io/nsLocalFileWin.cpp b/xpcom/io/nsLocalFileWin.cpp index 66e267807..e73e15950 100644 --- a/xpcom/io/nsLocalFileWin.cpp +++ b/xpcom/io/nsLocalFileWin.cpp @@ -45,6 +45,7 @@ #include "prproces.h" #include "prlink.h" +#include "mozilla/FilePreferences.h" #include "mozilla/Mutex.h" #include "SpecialSystemDirectory.h" @@ -1166,6 +1167,10 @@ nsLocalFile::InitWithPath(const nsAString& aFilePath) return NS_ERROR_FILE_UNRECOGNIZED_PATH; } + if (FilePreferences::IsBlockedUNCPath(aFilePath)) { + return NS_ERROR_FILE_ACCESS_DENIED; + } + if (secondChar != L':' && (secondChar != L'\\' || firstChar != L'\\')) { return NS_ERROR_FILE_UNRECOGNIZED_PATH; } @@ -1976,6 +1981,10 @@ nsLocalFile::CopySingleFile(nsIFile* aSourceFile, nsIFile* aDestParent, dwCopyFlags |= COPY_FILE_NO_BUFFERING; } + if (FilePreferences::IsBlockedUNCPath(destPath)) { + return NS_ERROR_FILE_ACCESS_DENIED; + } + if (!move) { copyOK = ::CopyFileExW(filePath.get(), destPath.get(), nullptr, nullptr, nullptr, dwCopyFlags); @@ -3062,6 +3071,7 @@ nsLocalFile::IsExecutable(bool* aResult) "scf", // Windows explorer command "scr", "sct", + "settingcontent-ms", "shb", "shs", "url", diff --git a/xpcom/reflect/xptcall/md/unix/Makefile.in b/xpcom/reflect/xptcall/md/unix/Makefile.in index e4cdc389b..716d79623 100644 --- a/xpcom/reflect/xptcall/md/unix/Makefile.in +++ b/xpcom/reflect/xptcall/md/unix/Makefile.in @@ -7,17 +7,6 @@ # HPPA ###################################################################### # -# HP-UX/PA32 -# -# for gas and gcc, check comment in xptcinvoke_asm_pa32.s -ifeq ($(OS_ARCH),HP-UX) -ifneq ($(CC),gcc) -# #18875 Building the CPP's (CXX) optimized causes a crash -CXXFLAGS := $(filter-out $(MOZ_OPTIMIZE_FLAGS), $(CXXFLAGS)) -endif -endif - -# # Linux/HPPA/gcc # ifeq ($(OS_ARCH),Linux) diff --git a/xpcom/reflect/xptcall/md/unix/moz.build b/xpcom/reflect/xptcall/md/unix/moz.build index 1d182bbd6..148d3bf35 100644 --- a/xpcom/reflect/xptcall/md/unix/moz.build +++ b/xpcom/reflect/xptcall/md/unix/moz.build @@ -108,23 +108,6 @@ if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['OS_ARCH'] in ('Bitrig', 'OpenBSD'): 'xptcstubs_arm_openbsd.cpp', ] -if CONFIG['OS_ARCH'] == 'HP-UX': - if CONFIG['CC'] != 'gcc': - if CONFIG['OS_TEST'] == 'ia64': - SOURCES += [ - 'xptcinvoke_asm_ipf32.s', - 'xptcinvoke_ipf32.cpp', - 'xptcstubs_asm_ipf32.s', - 'xptcstubs_ipf32.cpp', - ] - else: - SOURCES += [ - 'xptcinvoke_asm_pa32.s', - 'xptcinvoke_pa32.cpp', - 'xptcstubs_asm_pa32.s', - 'xptcstubs_pa32.cpp' - ] - if CONFIG['OS_ARCH'] == 'Linux': if CONFIG['OS_TEST'] in ('hppa', 'hppa2.0', 'hppa1.1'): if CONFIG['GNU_CXX']: diff --git a/xpcom/reflect/xptcall/status.html b/xpcom/reflect/xptcall/status.html index 65de20596..7f8e54a0c 100644 --- a/xpcom/reflect/xptcall/status.html +++ b/xpcom/reflect/xptcall/status.html @@ -255,21 +255,6 @@ The word I hear is that this is working and done <TR> <TD bgcolor="green"><font color="white"><b>Done</b></font></TD> -<TD>HP-UX</TD> -<TD> -<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> -<a href="mailto:wang@cup.hp.com">Thomas Wang <wang@cup.hp.com></a><BR> -<img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> -<a href="mailto:mgleeson1@netscape.com">Mike Gleeson <mgleeson1@netscape.com></a> -</TD> -<TD>I hear that this code is checked in and working. Though, there is some -doubt - see bug -#<a href="http://bugzilla.mozilla.org/show_bug.cgi?id=17997">17997</a> -</TD> -</TR> - -<TR> -<TD bgcolor="green"><font color="white"><b>Done</b></font></TD> <TD>AIX PPC</TD> <TD><img alt="Contributed code!" title="Contributed code!" src="http://tinderbox.mozilla.org/star.gif"> <a href="mailto:jdunn@netscape.com">Jim Dunn <jdunn@netscape.com></a></TD> diff --git a/xpcom/reflect/xptcall/xptcall.h b/xpcom/reflect/xptcall/xptcall.h index 1f2367b5d..304787635 100644 --- a/xpcom/reflect/xptcall/xptcall.h +++ b/xpcom/reflect/xptcall/xptcall.h @@ -39,7 +39,7 @@ struct nsXPTCMiniVariant // Types below here are unknown to the assembly implementations, and // therefore _must_ be passed with indirect semantics. We put them in // the union here for type safety, so that we can avoid void* tricks. - JS::Value j; + JS::UninitializedValue j; } val; }; diff --git a/xpcom/tests/gtest/TestDeadlockDetectorScalability.cpp b/xpcom/tests/gtest/TestDeadlockDetectorScalability.cpp index e25217223..ac63168d6 100644 --- a/xpcom/tests/gtest/TestDeadlockDetectorScalability.cpp +++ b/xpcom/tests/gtest/TestDeadlockDetectorScalability.cpp @@ -4,9 +4,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/. */ -// Avoid DMD-specific parts of MOZ_DEFINE_MALLOC_SIZE_OF -#undef MOZ_DMD - #include "nsIMemoryReporter.h" #include "mozilla/Mutex.h" diff --git a/xpcom/tests/gtest/TestFilePreferencesWin.cpp b/xpcom/tests/gtest/TestFilePreferencesWin.cpp new file mode 100644 index 000000000..b7d3a3159 --- /dev/null +++ b/xpcom/tests/gtest/TestFilePreferencesWin.cpp @@ -0,0 +1,141 @@ +#include "gtest/gtest.h" + +#include "mozilla/FilePreferences.h" +#include "nsIFile.h" +#include "nsXPCOMCID.h" + +TEST(FilePreferencesWin, Normalization) +{ + nsAutoString normalized; + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("foo"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\foo"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\foo")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("foo\\some"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("foo\\some")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.\\foo"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\."), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.\\."), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\."), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\.\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\bar\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\..\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\.."), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\foo\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\..\\bar\\..\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\..\\bar"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\bar")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\.\\..\\.\\..\\"), normalized); + ASSERT_TRUE(normalized == NS_LITERAL_STRING("\\\\")); + + bool result; + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.."), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\..\\"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.\\..\\"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\\\bar"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\foo\\bar\\..\\..\\..\\..\\"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\\\"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\.\\\\"), normalized); + ASSERT_FALSE(result); + + result = mozilla::FilePreferences::testing::NormalizePath( + NS_LITERAL_STRING("\\\\..\\\\"), normalized); + ASSERT_FALSE(result); +} + +TEST(FilePreferencesWin, AccessUNC) +{ + nsCOMPtr<nsIFile> lf = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); + + nsresult rv; + + mozilla::FilePreferences::testing::SetBlockUNCPaths(false); + + rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + ASSERT_EQ(rv, NS_OK); + + mozilla::FilePreferences::testing::SetBlockUNCPaths(true); + + rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); + + mozilla::FilePreferences::testing::AddDirectoryToWhitelist(NS_LITERAL_STRING("\\\\nice")); + + rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\share")); + ASSERT_EQ(rv, NS_OK); + + rv = lf->InitWithPath(NS_LITERAL_STRING("\\\\nice\\..\\evil\\share")); + ASSERT_EQ(rv, NS_ERROR_FILE_ACCESS_DENIED); +} diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 53836eaef..ac98c2217 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -56,6 +56,11 @@ if CONFIG['MOZ_DEBUG'] and CONFIG['OS_ARCH'] not in ('WINNT') and CONFIG['OS_TAR 'TestDeadlockDetectorScalability.cpp', ] +if CONFIG['OS_TARGET'] == 'WINNT': + UNIFIED_SOURCES += [ + 'TestFilePreferencesWin.cpp', + ] + if CONFIG['WRAP_STL_INCLUDES'] and not CONFIG['CLANG_CL']: UNIFIED_SOURCES += [ 'TestSTLWrappers.cpp', diff --git a/xpcom/threads/HangMonitor.cpp b/xpcom/threads/HangMonitor.cpp index bd415be50..6def6ed61 100644 --- a/xpcom/threads/HangMonitor.cpp +++ b/xpcom/threads/HangMonitor.cpp @@ -26,10 +26,6 @@ #include <windows.h> #endif -#if defined(MOZ_ENABLE_PROFILER_SPS) && defined(MOZ_PROFILING) && defined(XP_WIN) - #define REPORT_CHROME_HANGS -#endif - namespace mozilla { namespace HangMonitor { @@ -41,10 +37,6 @@ volatile bool gDebugDisableHangMonitor = false; const char kHangMonitorPrefName[] = "hangmonitor.timeout"; -#ifdef REPORT_CHROME_HANGS -const char kTelemetryPrefName[] = "toolkit.telemetry.enabled"; -#endif - // Monitor protects gShutdown and gTimeout, but not gTimestamp which rely on // being atomically set by the processor; synchronization doesn't really matter // in this use case. @@ -62,31 +54,11 @@ bool gShutdown; // we're currently not processing events. Atomic<PRIntervalTime> gTimestamp(PR_INTERVAL_NO_WAIT); -#ifdef REPORT_CHROME_HANGS -// Main thread ID used in reporting chrome hangs under Windows -static HANDLE winMainThreadHandle = nullptr; - -// Default timeout for reporting chrome hangs to Telemetry (5 seconds) -static const int32_t DEFAULT_CHROME_HANG_INTERVAL = 5; - -// Maximum number of PCs to gather from the stack -static const int32_t MAX_CALL_STACK_PCS = 400; -#endif - // PrefChangedFunc void PrefChanged(const char*, void*) { int32_t newval = Preferences::GetInt(kHangMonitorPrefName); -#ifdef REPORT_CHROME_HANGS - // Monitor chrome hangs on the profiling branch if Telemetry enabled - if (newval == 0) { - bool telemetryEnabled = Preferences::GetBool(kTelemetryPrefName); - if (telemetryEnabled) { - newval = DEFAULT_CHROME_HANG_INTERVAL; - } - } -#endif MonitorAutoLock lock(*gMonitor); if (newval != gTimeout) { gTimeout = newval; @@ -110,89 +82,6 @@ Crash() NS_RUNTIMEABORT("HangMonitor triggered"); } -#ifdef REPORT_CHROME_HANGS - -static void -ChromeStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure) -{ - MOZ_ASSERT(aClosure); - std::vector<uintptr_t>* stack = - static_cast<std::vector<uintptr_t>*>(aClosure); - if (stack->size() == MAX_CALL_STACK_PCS) { - return; - } - MOZ_ASSERT(stack->size() < MAX_CALL_STACK_PCS); - stack->push_back(reinterpret_cast<uintptr_t>(aPC)); -} - -static void -GetChromeHangReport(Telemetry::ProcessedStack& aStack, - int32_t& aSystemUptime, - int32_t& aFirefoxUptime) -{ - MOZ_ASSERT(winMainThreadHandle); - - // The thread we're about to suspend might have the alloc lock - // so allocate ahead of time - std::vector<uintptr_t> rawStack; - rawStack.reserve(MAX_CALL_STACK_PCS); - - // Workaround possible deadlock where the main thread is running a - // long-standing JS job, and happens to be in the JIT allocator when we - // suspend it. Since, on win 64, this requires holding a process lock that - // MozStackWalk requires, take this "workaround lock" to avoid deadlock. -#ifdef _WIN64 - AcquireStackWalkWorkaroundLock(); -#endif - DWORD ret = ::SuspendThread(winMainThreadHandle); - bool suspended = false; - if (ret != -1) { - // SuspendThread is asynchronous, so the thread may still be running. Use - // GetThreadContext to ensure it's really suspended. - // See https://blogs.msdn.microsoft.com/oldnewthing/20150205-00/?p=44743. - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL; - if (::GetThreadContext(winMainThreadHandle, &context)) { - suspended = true; - } - } - -#ifdef _WIN64 - ReleaseStackWalkWorkaroundLock(); -#endif - - if (!suspended) { - if (ret != -1) { - MOZ_ALWAYS_TRUE(::ResumeThread(winMainThreadHandle) != DWORD(-1)); - } - return; - } - - MozStackWalk(ChromeStackWalker, /* skipFrames */ 0, /* maxFrames */ 0, - reinterpret_cast<void*>(&rawStack), - reinterpret_cast<uintptr_t>(winMainThreadHandle), nullptr); - ret = ::ResumeThread(winMainThreadHandle); - if (ret == -1) { - return; - } - aStack = Telemetry::GetStackAndModules(rawStack); - - // Record system uptime (in minutes) at the time of the hang - aSystemUptime = ((GetTickCount() / 1000) - (gTimeout * 2)) / 60; - - // Record Firefox uptime (in minutes) at the time of the hang - bool error; - TimeStamp processCreation = TimeStamp::ProcessCreation(error); - if (!error) { - TimeDuration td = TimeStamp::Now() - processCreation; - aFirefoxUptime = (static_cast<int32_t>(td.ToSeconds()) - (gTimeout * 2)) / 60; - } else { - aFirefoxUptime = -1; - } -} - -#endif - void ThreadMain(void*) { @@ -206,13 +95,6 @@ ThreadMain(void*) PRIntervalTime lastTimestamp = 0; int waitCount = 0; -#ifdef REPORT_CHROME_HANGS - Telemetry::ProcessedStack stack; - int32_t systemUptime = -1; - int32_t firefoxUptime = -1; - UniquePtr<HangAnnotations> annotations; -#endif - while (true) { if (gShutdown) { return; // Exit the thread @@ -233,14 +115,6 @@ ThreadMain(void*) timestamp == lastTimestamp && gTimeout > 0) { ++waitCount; -#ifdef REPORT_CHROME_HANGS - // Capture the chrome-hang stack + Firefox & system uptimes after - // the minimum hang duration has been reached (not when the hang ends) - if (waitCount == 2) { - GetChromeHangReport(stack, systemUptime, firefoxUptime); - annotations = ChromeHangAnnotatorCallout(); - } -#else // This is the crash-on-hang feature. // See bug 867313 for the quirk in the waitCount comparison if (waitCount >= 2) { @@ -251,16 +125,7 @@ ThreadMain(void*) Crash(); } } -#endif } else { -#ifdef REPORT_CHROME_HANGS - if (waitCount >= 2) { - uint32_t hangDuration = PR_IntervalToSeconds(now - lastTimestamp); - Telemetry::RecordChromeHang(hangDuration, stack, systemUptime, - firefoxUptime, Move(annotations)); - stack.Clear(); - } -#endif lastTimestamp = timestamp; waitCount = 0; } @@ -289,15 +154,6 @@ Startup() Preferences::RegisterCallback(PrefChanged, kHangMonitorPrefName, nullptr); PrefChanged(nullptr, nullptr); -#ifdef REPORT_CHROME_HANGS - Preferences::RegisterCallback(PrefChanged, kTelemetryPrefName, nullptr); - winMainThreadHandle = - OpenThread(THREAD_ALL_ACCESS, FALSE, GetCurrentThreadId()); - if (!winMainThreadHandle) { - return; - } -#endif - // Don't actually start measuring hangs until we hit the main event loop. // This potentially misses a small class of really early startup hangs, // but avoids dealing with some xpcshell tests and other situations which diff --git a/xpcom/threads/ThreadStackHelper.cpp b/xpcom/threads/ThreadStackHelper.cpp index d31bf6359..2c0e87986 100644 --- a/xpcom/threads/ThreadStackHelper.cpp +++ b/xpcom/threads/ThreadStackHelper.cpp @@ -9,9 +9,6 @@ #include "nsJSPrincipals.h" #include "nsScriptSecurityManager.h" #include "jsfriendapi.h" -#ifdef MOZ_THREADSTACKHELPER_NATIVE -#include "shared-libraries.h" -#endif #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" @@ -62,17 +59,6 @@ #endif #endif -#ifdef MOZ_THREADSTACKHELPER_NATIVE -#if defined(MOZ_THREADSTACKHELPER_X86) || \ - defined(MOZ_THREADSTACKHELPER_X64) || \ - defined(MOZ_THREADSTACKHELPER_ARM) -// On these architectures, the stack grows downwards (toward lower addresses). -#define MOZ_THREADSTACKHELPER_STACK_GROWS_DOWN -#else -#error "Unsupported architecture" -#endif -#endif // MOZ_THREADSTACKHELPER_NATIVE - namespace mozilla { void @@ -114,14 +100,6 @@ ThreadStackHelper::Shutdown() ThreadStackHelper::ThreadStackHelper() : mStackToFill(nullptr) -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - , mPseudoStack(mozilla_get_pseudo_stack()) -#ifdef MOZ_THREADSTACKHELPER_NATIVE - , mContextToFill(nullptr) -#endif - , mMaxStackSize(Stack::sMaxInlineStorage) - , mMaxBufferSize(512) -#endif { #if defined(XP_LINUX) MOZ_ALWAYS_TRUE(!::sem_init(&mSem, 0, 0)); @@ -131,18 +109,11 @@ ThreadStackHelper::ThreadStackHelper() ::GetCurrentProcess(), ::GetCurrentThread(), ::GetCurrentProcess(), &mThreadID, THREAD_SUSPEND_RESUME -#ifdef MOZ_THREADSTACKHELPER_NATIVE - | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION -#endif , FALSE, 0); MOZ_ASSERT(mInitialized); #elif defined(XP_MACOSX) mThreadID = mach_thread_self(); #endif - -#ifdef MOZ_THREADSTACKHELPER_NATIVE - GetThreadStackBase(); -#endif } ThreadStackHelper::~ThreadStackHelper() @@ -156,45 +127,6 @@ ThreadStackHelper::~ThreadStackHelper() #endif } -#ifdef MOZ_THREADSTACKHELPER_NATIVE -void ThreadStackHelper::GetThreadStackBase() -{ - mThreadStackBase = 0; - -#if defined(XP_LINUX) - void* stackAddr; - size_t stackSize; - ::pthread_t pthr = ::pthread_self(); - ::pthread_attr_t pthr_attr; - NS_ENSURE_TRUE_VOID(!::pthread_getattr_np(pthr, &pthr_attr)); - if (!::pthread_attr_getstack(&pthr_attr, &stackAddr, &stackSize)) { -#ifdef MOZ_THREADSTACKHELPER_STACK_GROWS_DOWN - mThreadStackBase = intptr_t(stackAddr) + stackSize; -#else - mThreadStackBase = intptr_t(stackAddr); -#endif - } - MOZ_ALWAYS_TRUE(!::pthread_attr_destroy(&pthr_attr)); - -#elif defined(XP_WIN) - ::MEMORY_BASIC_INFORMATION meminfo = {}; - NS_ENSURE_TRUE_VOID(::VirtualQuery(&meminfo, &meminfo, sizeof(meminfo))); -#ifdef MOZ_THREADSTACKHELPER_STACK_GROWS_DOWN - mThreadStackBase = intptr_t(meminfo.BaseAddress) + meminfo.RegionSize; -#else - mThreadStackBase = intptr_t(meminfo.AllocationBase); -#endif - -#elif defined(XP_MACOSX) - ::pthread_t pthr = ::pthread_self(); - mThreadStackBase = intptr_t(::pthread_get_stackaddr_np(pthr)); - -#else - #error "Unsupported platform" -#endif // platform -} -#endif // MOZ_THREADSTACKHELPER_NATIVE - namespace { template<typename T> class ScopedSetPtr @@ -281,53 +213,10 @@ ThreadStackHelper::GetStack(Stack& aStack) #endif } -#ifdef MOZ_THREADSTACKHELPER_NATIVE -class ThreadStackHelper::ThreadContext final -{ -public: - // TODO: provide per-platform definition of Context. - typedef struct {} Context; - - // Limit copied stack to 4kB - static const size_t kMaxStackSize = 0x1000; - // Limit unwound stack to 32 frames - static const unsigned int kMaxStackFrames = 32; - // Whether this structure contains valid data - bool mValid; - // Processor context - Context mContext; - // Stack area - UniquePtr<uint8_t[]> mStack; - // Start of stack area - uintptr_t mStackBase; - // Size of stack area - size_t mStackSize; - // End of stack area - const void* mStackEnd; - - ThreadContext() - : mValid(false) - , mStackBase(0) - , mStackSize(0) - , mStackEnd(nullptr) {} -}; -#endif // MOZ_THREADSTACKHELPER_NATIVE - void ThreadStackHelper::GetNativeStack(Stack& aStack) { -#ifdef MOZ_THREADSTACKHELPER_NATIVE - ThreadContext context; - context.mStack = MakeUnique<uint8_t[]>(ThreadContext::kMaxStackSize); - - ScopedSetPtr<ThreadContext> contextPtr(mContextToFill, &context); - - // Get pseudostack first and fill the thread context. - GetStack(aStack); - NS_ENSURE_TRUE_VOID(context.mValid); - - // TODO: walk the saved stack frames. -#endif // MOZ_THREADSTACKHELPER_NATIVE + /*** STUB ***/ } #ifdef XP_LINUX @@ -353,374 +242,20 @@ ThreadStackHelper::PrepareStackBuffer(Stack& aStack) { // Return false to skip getting the stack and return an empty stack aStack.clear(); -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - /* Normally, provided the profiler is enabled, it would be an error if we - don't have a pseudostack here (the thread probably forgot to call - profiler_register_thread). However, on B2G, profiling secondary threads - may be disabled despite profiler being enabled. This is by-design and - is not an error. */ -#ifdef MOZ_WIDGET_GONK - if (!mPseudoStack) { - return false; - } -#endif - MOZ_ASSERT(mPseudoStack); - if (!aStack.reserve(mMaxStackSize) || - !aStack.reserve(aStack.capacity()) || // reserve up to the capacity - !aStack.EnsureBufferCapacity(mMaxBufferSize)) { - return false; - } - return true; -#else return false; -#endif -} - -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - -namespace { - -bool -IsChromeJSScript(JSScript* aScript) -{ - // May be called from another thread or inside a signal handler. - // We assume querying the script is safe but we must not manipulate it. - - nsIScriptSecurityManager* const secman = - nsScriptSecurityManager::GetScriptSecurityManager(); - NS_ENSURE_TRUE(secman, false); - - JSPrincipals* const principals = JS_GetScriptPrincipals(aScript); - return secman->IsSystemPrincipal(nsJSPrincipals::get(principals)); -} - -// Get the full path after the URI scheme, if the URI matches the scheme. -// For example, GetFullPathForScheme("a://b/c/d/e", "a://") returns "b/c/d/e". -template <size_t LEN> -const char* -GetFullPathForScheme(const char* filename, const char (&scheme)[LEN]) { - // Account for the null terminator included in LEN. - if (!strncmp(filename, scheme, LEN - 1)) { - return filename + LEN - 1; - } - return nullptr; -} - -// Get the full path after a URI component, if the URI contains the component. -// For example, GetPathAfterComponent("a://b/c/d/e", "/c/") returns "d/e". -template <size_t LEN> -const char* -GetPathAfterComponent(const char* filename, const char (&component)[LEN]) { - const char* found = nullptr; - const char* next = strstr(filename, component); - while (next) { - // Move 'found' to end of the component, after the separator '/'. - // 'LEN - 1' accounts for the null terminator included in LEN, - found = next + LEN - 1; - // Resume searching before the separator '/'. - next = strstr(found - 1, component); - } - return found; } -} // namespace - -const char* -ThreadStackHelper::AppendJSEntry(const volatile StackEntry* aEntry, - intptr_t& aAvailableBufferSize, - const char* aPrevLabel) -{ - // May be called from another thread or inside a signal handler. - // We assume querying the script is safe but we must not manupulate it. - // Also we must not allocate any memory from heap. - MOZ_ASSERT(aEntry->isJs()); - - const char* label; - JSScript* script = aEntry->script(); - if (!script) { - label = "(profiling suppressed)"; - } else if (IsChromeJSScript(aEntry->script())) { - const char* filename = JS_GetScriptFilename(aEntry->script()); - const unsigned lineno = JS_PCToLineNumber(aEntry->script(), aEntry->pc()); - MOZ_ASSERT(filename); - - char buffer[128]; // Enough to fit longest js file name from the tree - - // Some script names are in the form "foo -> bar -> baz". - // Here we find the origin of these redirected scripts. - const char* basename = GetPathAfterComponent(filename, " -> "); - if (basename) { - filename = basename; - } - - basename = GetFullPathForScheme(filename, "chrome://"); - if (!basename) { - basename = GetFullPathForScheme(filename, "resource://"); - } - if (!basename) { - // If the (add-on) script is located under the {profile}/extensions - // directory, extract the path after the /extensions/ part. - basename = GetPathAfterComponent(filename, "/extensions/"); - } - if (!basename) { - // Only keep the file base name for paths outside the above formats. - basename = strrchr(filename, '/'); - basename = basename ? basename + 1 : filename; - // Look for Windows path separator as well. - filename = strrchr(basename, '\\'); - if (filename) { - basename = filename + 1; - } - } - - size_t len = SprintfLiteral(buffer, "%s:%u", basename, lineno); - if (len < sizeof(buffer)) { - if (mStackToFill->IsSameAsEntry(aPrevLabel, buffer)) { - return aPrevLabel; - } - - // Keep track of the required buffer size - aAvailableBufferSize -= (len + 1); - if (aAvailableBufferSize >= 0) { - // Buffer is big enough. - return mStackToFill->InfallibleAppendViaBuffer(buffer, len); - } - // Buffer is not big enough; fall through to using static label below. - } - // snprintf failed or buffer is not big enough. - label = "(chrome script)"; - } else { - label = "(content script)"; - } - - if (mStackToFill->IsSameAsEntry(aPrevLabel, label)) { - return aPrevLabel; - } - mStackToFill->infallibleAppend(label); - return label; -} - -#endif // MOZ_THREADSTACKHELPER_PSEUDO - void ThreadStackHelper::FillStackBuffer() { MOZ_ASSERT(mStackToFill->empty()); - -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - size_t reservedSize = mStackToFill->capacity(); - size_t reservedBufferSize = mStackToFill->AvailableBufferSize(); - intptr_t availableBufferSize = intptr_t(reservedBufferSize); - - // Go from front to back - const volatile StackEntry* entry = mPseudoStack->mStack; - const volatile StackEntry* end = entry + mPseudoStack->stackSize(); - // Deduplicate identical, consecutive frames - const char* prevLabel = nullptr; - for (; reservedSize-- && entry != end; entry++) { - /* We only accept non-copy labels, including js::RunScript, - because we only want static labels in the hang stack. */ - if (entry->isCopyLabel()) { - continue; - } - if (entry->isJs()) { - prevLabel = AppendJSEntry(entry, availableBufferSize, prevLabel); - continue; - } -#ifdef MOZ_THREADSTACKHELPER_NATIVE - if (mContextToFill) { - mContextToFill->mStackEnd = entry->stackAddress(); - } -#endif - const char* const label = entry->label(); - if (mStackToFill->IsSameAsEntry(prevLabel, label)) { - // Avoid duplicate labels to save space in the stack. - continue; - } - mStackToFill->infallibleAppend(label); - prevLabel = label; - } - - // end != entry if we exited early due to not enough reserved frames. - // Expand the number of reserved frames for next time. - mMaxStackSize = mStackToFill->capacity() + (end - entry); - - // availableBufferSize < 0 if we needed a larger buffer than we reserved. - // Calculate a new reserve size for next time. - if (availableBufferSize < 0) { - mMaxBufferSize = reservedBufferSize - availableBufferSize; - } -#endif + /*** STUB ***/ } MOZ_ASAN_BLACKLIST void ThreadStackHelper::FillThreadContext(void* aContext) { -#ifdef MOZ_THREADSTACKHELPER_NATIVE - if (!mContextToFill) { - return; - } - -#if 0 // TODO: remove dependency on Breakpad structs. -#if defined(XP_LINUX) - const ucontext_t& context = *reinterpret_cast<ucontext_t*>(aContext); -#if defined(MOZ_THREADSTACKHELPER_X86) - mContextToFill->mContext.context_flags = MD_CONTEXT_X86_FULL; - mContextToFill->mContext.edi = context.uc_mcontext.gregs[REG_EDI]; - mContextToFill->mContext.esi = context.uc_mcontext.gregs[REG_ESI]; - mContextToFill->mContext.ebx = context.uc_mcontext.gregs[REG_EBX]; - mContextToFill->mContext.edx = context.uc_mcontext.gregs[REG_EDX]; - mContextToFill->mContext.ecx = context.uc_mcontext.gregs[REG_ECX]; - mContextToFill->mContext.eax = context.uc_mcontext.gregs[REG_EAX]; - mContextToFill->mContext.ebp = context.uc_mcontext.gregs[REG_EBP]; - mContextToFill->mContext.eip = context.uc_mcontext.gregs[REG_EIP]; - mContextToFill->mContext.eflags = context.uc_mcontext.gregs[REG_EFL]; - mContextToFill->mContext.esp = context.uc_mcontext.gregs[REG_ESP]; -#elif defined(MOZ_THREADSTACKHELPER_X64) - mContextToFill->mContext.context_flags = MD_CONTEXT_AMD64_FULL; - mContextToFill->mContext.eflags = uint32_t(context.uc_mcontext.gregs[REG_EFL]); - mContextToFill->mContext.rax = context.uc_mcontext.gregs[REG_RAX]; - mContextToFill->mContext.rcx = context.uc_mcontext.gregs[REG_RCX]; - mContextToFill->mContext.rdx = context.uc_mcontext.gregs[REG_RDX]; - mContextToFill->mContext.rbx = context.uc_mcontext.gregs[REG_RBX]; - mContextToFill->mContext.rsp = context.uc_mcontext.gregs[REG_RSP]; - mContextToFill->mContext.rbp = context.uc_mcontext.gregs[REG_RBP]; - mContextToFill->mContext.rsi = context.uc_mcontext.gregs[REG_RSI]; - mContextToFill->mContext.rdi = context.uc_mcontext.gregs[REG_RDI]; - memcpy(&mContextToFill->mContext.r8, - &context.uc_mcontext.gregs[REG_R8], 8 * sizeof(int64_t)); - mContextToFill->mContext.rip = context.uc_mcontext.gregs[REG_RIP]; -#elif defined(MOZ_THREADSTACKHELPER_ARM) - mContextToFill->mContext.context_flags = MD_CONTEXT_ARM_FULL; - memcpy(&mContextToFill->mContext.iregs[0], - &context.uc_mcontext.arm_r0, 17 * sizeof(int32_t)); -#else - #error "Unsupported architecture" -#endif // architecture - -#elif defined(XP_WIN) - // Breakpad context struct is based off of the Windows CONTEXT struct, - // so we assume they are the same; do some sanity checks to make sure. - static_assert(sizeof(ThreadContext::Context) == sizeof(::CONTEXT), - "Context struct mismatch"); - static_assert(offsetof(ThreadContext::Context, context_flags) == - offsetof(::CONTEXT, ContextFlags), - "Context struct mismatch"); - mContextToFill->mContext.context_flags = CONTEXT_FULL; - NS_ENSURE_TRUE_VOID(::GetThreadContext(mThreadID, - reinterpret_cast<::CONTEXT*>(&mContextToFill->mContext))); - -#elif defined(XP_MACOSX) -#if defined(MOZ_THREADSTACKHELPER_X86) - const thread_state_flavor_t flavor = x86_THREAD_STATE32; - x86_thread_state32_t state = {}; - mach_msg_type_number_t count = x86_THREAD_STATE32_COUNT; -#elif defined(MOZ_THREADSTACKHELPER_X64) - const thread_state_flavor_t flavor = x86_THREAD_STATE64; - x86_thread_state64_t state = {}; - mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; -#elif defined(MOZ_THREADSTACKHELPER_ARM) - const thread_state_flavor_t flavor = ARM_THREAD_STATE; - arm_thread_state_t state = {}; - mach_msg_type_number_t count = ARM_THREAD_STATE_COUNT; -#endif - NS_ENSURE_TRUE_VOID(KERN_SUCCESS == ::thread_get_state( - mThreadID, flavor, reinterpret_cast<thread_state_t>(&state), &count)); -#if __DARWIN_UNIX03 -#define GET_REGISTER(s, r) ((s).__##r) -#else -#define GET_REGISTER(s, r) ((s).r) -#endif -#if defined(MOZ_THREADSTACKHELPER_X86) - mContextToFill->mContext.context_flags = MD_CONTEXT_X86_FULL; - mContextToFill->mContext.edi = GET_REGISTER(state, edi); - mContextToFill->mContext.esi = GET_REGISTER(state, esi); - mContextToFill->mContext.ebx = GET_REGISTER(state, ebx); - mContextToFill->mContext.edx = GET_REGISTER(state, edx); - mContextToFill->mContext.ecx = GET_REGISTER(state, ecx); - mContextToFill->mContext.eax = GET_REGISTER(state, eax); - mContextToFill->mContext.ebp = GET_REGISTER(state, ebp); - mContextToFill->mContext.eip = GET_REGISTER(state, eip); - mContextToFill->mContext.eflags = GET_REGISTER(state, eflags); - mContextToFill->mContext.esp = GET_REGISTER(state, esp); -#elif defined(MOZ_THREADSTACKHELPER_X64) - mContextToFill->mContext.context_flags = MD_CONTEXT_AMD64_FULL; - mContextToFill->mContext.eflags = uint32_t(GET_REGISTER(state, rflags)); - mContextToFill->mContext.rax = GET_REGISTER(state, rax); - mContextToFill->mContext.rcx = GET_REGISTER(state, rcx); - mContextToFill->mContext.rdx = GET_REGISTER(state, rdx); - mContextToFill->mContext.rbx = GET_REGISTER(state, rbx); - mContextToFill->mContext.rsp = GET_REGISTER(state, rsp); - mContextToFill->mContext.rbp = GET_REGISTER(state, rbp); - mContextToFill->mContext.rsi = GET_REGISTER(state, rsi); - mContextToFill->mContext.rdi = GET_REGISTER(state, rdi); - memcpy(&mContextToFill->mContext.r8, - &GET_REGISTER(state, r8), 8 * sizeof(int64_t)); - mContextToFill->mContext.rip = GET_REGISTER(state, rip); -#elif defined(MOZ_THREADSTACKHELPER_ARM) - mContextToFill->mContext.context_flags = MD_CONTEXT_ARM_FULL; - memcpy(mContextToFill->mContext.iregs, - GET_REGISTER(state, r), 17 * sizeof(int32_t)); -#else - #error "Unsupported architecture" -#endif // architecture -#undef GET_REGISTER - -#else - #error "Unsupported platform" -#endif // platform - - intptr_t sp = 0; -#if defined(MOZ_THREADSTACKHELPER_X86) - sp = mContextToFill->mContext.esp; -#elif defined(MOZ_THREADSTACKHELPER_X64) - sp = mContextToFill->mContext.rsp; -#elif defined(MOZ_THREADSTACKHELPER_ARM) - sp = mContextToFill->mContext.iregs[13]; -#else - #error "Unsupported architecture" -#endif // architecture - NS_ENSURE_TRUE_VOID(sp); - NS_ENSURE_TRUE_VOID(mThreadStackBase); - - size_t stackSize = std::min(intptr_t(ThreadContext::kMaxStackSize), - std::abs(sp - mThreadStackBase)); - - if (mContextToFill->mStackEnd) { - // Limit the start of stack to a certain location if specified. - stackSize = std::min(intptr_t(stackSize), - std::abs(sp - intptr_t(mContextToFill->mStackEnd))); - } - -#ifndef MOZ_THREADSTACKHELPER_STACK_GROWS_DOWN - // If if the stack grows upwards, and we need to recalculate our - // stack copy's base address. Subtract sizeof(void*) so that the - // location pointed to by sp is included. - sp -= stackSize - sizeof(void*); -#endif - -#ifndef MOZ_ASAN - memcpy(mContextToFill->mStack.get(), reinterpret_cast<void*>(sp), stackSize); - // Valgrind doesn't care about the access outside the stack frame, but - // the presence of uninitialised values on the stack does cause it to - // later report a lot of false errors when Breakpad comes to unwind it. - // So mark the extracted data as defined. - MOZ_MAKE_MEM_DEFINED(mContextToFill->mStack.get(), stackSize); -#else - // ASan will flag memcpy for access outside of stack frames, - // so roll our own memcpy here. - intptr_t* dst = reinterpret_cast<intptr_t*>(&mContextToFill->mStack[0]); - const intptr_t* src = reinterpret_cast<intptr_t*>(sp); - for (intptr_t len = stackSize; len > 0; len -= sizeof(*src)) { - *(dst++) = *(src++); - } -#endif - - mContextToFill->mStackBase = uintptr_t(sp); - mContextToFill->mStackSize = stackSize; - mContextToFill->mValid = true; -#endif -#endif // MOZ_THREADSTACKHELPER_NATIVE + /*** STUB ***/ } } // namespace mozilla diff --git a/xpcom/threads/ThreadStackHelper.h b/xpcom/threads/ThreadStackHelper.h index 9c40ad5e2..f06e704b4 100644 --- a/xpcom/threads/ThreadStackHelper.h +++ b/xpcom/threads/ThreadStackHelper.h @@ -23,27 +23,6 @@ #include <mach/mach.h> #endif -// Support pseudostack on these platforms. -#if defined(XP_LINUX) || defined(XP_WIN) || defined(XP_MACOSX) -# ifdef MOZ_ENABLE_PROFILER_SPS -# define MOZ_THREADSTACKHELPER_PSEUDO -# endif -#endif - -#ifdef MOZ_THREADSTACKHELPER_PSEUDO -# define MOZ_THREADSTACKHELPER_NATIVE -# if defined(__i386__) || defined(_M_IX86) -# define MOZ_THREADSTACKHELPER_X86 -# elif defined(__x86_64__) || defined(_M_X64) -# define MOZ_THREADSTACKHELPER_X64 -# elif defined(__arm__) || defined(_M_ARM) -# define MOZ_THREADSTACKHELPER_ARM -# else - // Unsupported architecture -# undef MOZ_THREADSTACKHELPER_NATIVE -# endif -#endif - namespace mozilla { /** @@ -63,29 +42,10 @@ public: private: Stack* mStackToFill; -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - const PseudoStack* const mPseudoStack; -#ifdef MOZ_THREADSTACKHELPER_NATIVE - class ThreadContext; - // Set to non-null if GetStack should get the thread context. - ThreadContext* mContextToFill; - intptr_t mThreadStackBase; -#endif - size_t mMaxStackSize; - size_t mMaxBufferSize; -#endif bool PrepareStackBuffer(Stack& aStack); void FillStackBuffer(); void FillThreadContext(void* aContext = nullptr); -#ifdef MOZ_THREADSTACKHELPER_PSEUDO - const char* AppendJSEntry(const volatile StackEntry* aEntry, - intptr_t& aAvailableBufferSize, - const char* aPrevLabel); -#endif -#ifdef MOZ_THREADSTACKHELPER_NATIVE - void GetThreadStackBase(); -#endif public: /** diff --git a/xpcom/threads/moz.build b/xpcom/threads/moz.build index 5d54a4bf4..53e6b5922 100644 --- a/xpcom/threads/moz.build +++ b/xpcom/threads/moz.build @@ -76,11 +76,9 @@ LOCAL_INCLUDES += [ # BHR disabled for Release builds because of bug 965392. # BHR disabled for debug builds because of bug 979069. -# BHR disabled on gonk because of bug 1180533 # BHR disabled for TSan builds because of bug 1121216. if CONFIG['MOZ_UPDATE_CHANNEL'] not in ('release') and \ not CONFIG['MOZ_DEBUG'] and \ - not CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and \ not CONFIG['MOZ_TSAN']: DEFINES['MOZ_ENABLE_BACKGROUND_HANG_MONITOR'] = 1 |