tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 234d2b5a25db0aa6f959d746bb0f0c4d05fa5990
parent 081289856ab1b9aa0810a8e7a770a412fe8634bd
Author: Serban Stanca <sstanca@mozilla.com>
Date:   Wed,  1 Oct 2025 06:21:55 +0300

Revert "Bug 1982963 - Test case to make sure LinuxMemoryPSI is in the crash report. r=xpcom-reviewers,nika" for causing build bustages in AvailableMemoryWatcherLinux.cpp.

This reverts commit a266216a54e3369f5b46fb1a327bb25a5061141c.

Diffstat:
Mtoolkit/crashreporter/test/unit/crasher_subprocess_head.js | 1-
Mtoolkit/crashreporter/test/unit/crasher_subprocess_tail.js | 2+-
Dtoolkit/crashreporter/test/unit/test_crash_psi_annotation.js | 215-------------------------------------------------------------------------------
Mtoolkit/crashreporter/test/unit/xpcshell.toml | 4----
Mxpcom/base/AvailableMemoryWatcherLinux.cpp | 64+++++++++++++---------------------------------------------------
Mxpcom/base/moz.build | 5-----
Dxpcom/base/nsIAvailableMemoryWatcherTestingLinux.idl | 23-----------------------
7 files changed, 14 insertions(+), 300 deletions(-)

diff --git a/toolkit/crashreporter/test/unit/crasher_subprocess_head.js b/toolkit/crashreporter/test/unit/crasher_subprocess_head.js @@ -27,7 +27,6 @@ const { CrashTestUtils } = ChromeUtils.importESModule( ); var crashType = CrashTestUtils.CRASH_INVALID_POINTER_DEREF; var shouldDelay = false; -var shouldWaitSetup = false; // Turn PHC on so that the PHC tests work. CrashTestUtils.enablePHC(); diff --git a/toolkit/crashreporter/test/unit/crasher_subprocess_tail.js b/toolkit/crashreporter/test/unit/crasher_subprocess_tail.js @@ -12,7 +12,7 @@ if (shouldDelay) { Services.tm.spinEventLoopUntil( "Test(crasher_subprocess_tail.js:shouldDelay)", - () => shouldCrashNow && !shouldWaitSetup + () => shouldCrashNow ); } diff --git a/toolkit/crashreporter/test/unit/test_crash_psi_annotation.js b/toolkit/crashreporter/test/unit/test_crash_psi_annotation.js @@ -1,215 +0,0 @@ -add_task(async function test_psi_annotation_in_crash_report() { - if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { - dump( - "INFO | test_crash_psi_annotation.js | Can't test crashreporter in a non-libxul build.\n" - ); - return; - } - - // Create a mock PSI file with known values for testing - const mockPSIContent = - "some avg10=10.00 avg60=8.00 avg300=6.00 total=1000\n" + - "full avg10=2.00 avg60=1.50 avg300=1.00 total=500\n"; - - // Create mock PSI file as a temporary file - const psiFile = do_get_tempdir(); - psiFile.append("test_psi_memory"); - psiFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0o600); - - // Write mock PSI data - await IOUtils.writeUTF8(psiFile.path, mockPSIContent); - - // Register cleanup to remove the test file - registerCleanupFunction(async function () { - if (psiFile.exists()) { - try { - psiFile.remove(false); - } catch (e) { - // Ignore cleanup errors - } - } - }); - - // Set the PSI path for testing through environment variable - // The callback runs in a separate process, so we need to pass the path via env - Services.env.set("MOZ_TEST_PSI_PATH", psiFile.path); - - // Test that PSI annotation is recorded in crash report - await do_crash( - async function () { - shouldWaitSetup = true; - shouldDelay = true; - - // Read the PSI path from environment variable in the separate process - const psiPath = Services.env.get("MOZ_TEST_PSI_PATH"); - const watcher = Cc["@mozilla.org/xpcom/memory-watcher;1"].getService( - Ci.nsIAvailableMemoryWatcherBase - ); - if (psiPath) { - const testingWatcher = watcher.QueryInterface( - Ci.nsIAvailableMemoryWatcherTestingLinux - ); - testingWatcher.setPSIPathForTesting(psiPath); - } - - // Set up tab unloader and wait for it to be called - let tabUnloaderCalled = false; - const tabUnloaderPromise = new Promise(resolve => { - const mockTabUnloader = { - queryInterface: ChromeUtils.generateQI(["nsITabUnloader"]), - unloadTabAsync() { - tabUnloaderCalled = true; - resolve(); - }, - }; - - // Register our mock tab unloader through the service - watcher.registerTabUnloader(mockTabUnloader); - }); - - // Set memory threshold to 100% to ensure memory pressure is detected - Services.prefs.setIntPref( - "browser.low_commit_space_threshold_percent", - 100 - ); - - // Start user interaction to begin polling - Services.obs.notifyObservers(null, "user-interaction-active"); - - // Wait for the tab unloader to be called - await tabUnloaderPromise; - - // Verify that the tab unloader was actually called - if (!tabUnloaderCalled) { - throw new Error("Tab unloader was not called"); - } - - // Trigger the crash now that PSI data has been processed - crashType = CrashTestUtils.CRASH_PURE_VIRTUAL_CALL; - shouldWaitSetup = false; - }, - function (mdump, extra) { - Assert.ok( - "LinuxMemoryPSI" in extra, - "LinuxMemoryPSI annotation should be present" - ); - - // Verify the format is correct (comma-separated values) - const psiValues = extra.LinuxMemoryPSI; - Assert.strictEqual( - typeof psiValues, - "string", - "PSI values should be a string" - ); - - // Parse the comma-separated values - const values = psiValues.split(","); - Assert.equal( - values.length, - 8, - "PSI annotation should have 8 comma-separated values" - ); - - // Verify the expected values from our mock PSI file - // Format: some_avg10,some_avg60,some_avg300,some_total,full_avg10,full_avg60,full_avg300,full_total - Assert.equal(values[0], "10", "some_avg10 should be 10"); - Assert.equal(values[1], "8", "some_avg60 should be 8"); - Assert.equal(values[2], "6", "some_avg300 should be 6"); - Assert.equal(values[3], "1000", "some_total should be 1000"); - Assert.equal(values[4], "2", "full_avg10 should be 2"); - Assert.equal(values[5], "1", "full_avg60 should be 1"); - Assert.equal(values[6], "1", "full_avg300 should be 1"); - Assert.equal(values[7], "500", "full_total should be 500"); - - dump("INFO | PSI annotation test passed: " + psiValues + "\n"); - }, - // process will exit with a zero exit status - true - ); -}); - -// Test PSI annotation when PSI file is not available -add_task(async function test_psi_annotation_no_psi_file() { - if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) { - dump( - "INFO | test_crash_psi_annotation.js | Can't test crashreporter in a non-libxul build.\n" - ); - return; - } - - await do_crash( - async function () { - shouldWaitSetup = true; - shouldDelay = true; - - // Set the PSI path for testing (point to a unique non-existent file) - const watcher = Cc["@mozilla.org/xpcom/memory-watcher;1"].getService( - Ci.nsIAvailableMemoryWatcherBase - ); - const testingWatcher = watcher.QueryInterface( - Ci.nsIAvailableMemoryWatcherTestingLinux - ); - - // Build a unique path by appending PID and timestamp to the base name. - // If a file happens to exist at that path, append a sequence number. - const basePath = - Services.env.get("XPCSHELL_TEST_TEMP_DIR") + "/non_existent_psi_file"; - const pid = Services.appinfo.processID; - const timestamp = Date.now(); - let sequence = 0; - let psiPath = `${basePath}_${pid}_${timestamp}`; - while (await IOUtils.exists(psiPath)) { - sequence++; - psiPath = `${basePath}_${pid}_${timestamp}_${sequence}`; - } - - testingWatcher.setPSIPathForTesting(psiPath); - - // Set memory threshold to 100% to ensure memory pressure is detected - Services.prefs.setIntPref( - "browser.low_commit_space_threshold_percent", - 100 - ); - - // Wait for PSI data to be processed - await new Promise(resolve => { - Services.obs.addObserver(function observer(_subject, _topic) { - Services.obs.removeObserver(observer, "memory-poller-sync"); - resolve(); - }, "memory-poller-sync"); - - Services.obs.notifyObservers(null, "user-interaction-active"); - }); - - // Trigger the crash now that PSI data has been processed - crashType = CrashTestUtils.CRASH_PURE_VIRTUAL_CALL; - shouldWaitSetup = false; - }, - function (mdump, extra) { - Assert.ok( - "LinuxMemoryPSI" in extra, - "LinuxMemoryPSI annotation should be present even when PSI file is unavailable" - ); - - const psiValues = extra.LinuxMemoryPSI; - const values = psiValues.split(","); - Assert.equal( - values.length, - 8, - "PSI annotation should have 8 values even when PSI file is unavailable" - ); - - // All values should be zero when PSI file is not available - for (let i = 0; i < 8; i++) { - Assert.equal( - values[i], - "0", - `PSI value ${i} should be 0 when PSI file is unavailable` - ); - } - - dump("INFO | PSI annotation test (no file) passed: " + psiValues + "\n"); - }, - true - ); -}); diff --git a/toolkit/crashreporter/test/unit/xpcshell.toml b/toolkit/crashreporter/test/unit/xpcshell.toml @@ -47,10 +47,6 @@ reason = "Test covering Linux-specific module handling" ["test_crash_oom.js"] -["test_crash_psi_annotation.js"] -run-if = ["os == 'linux'"] -reason = "Test covering Linux-specific PSI (Pressure Stall Information) annotation" - ["test_crash_purevirtual.js"] ["test_crash_rust_panic.js"] diff --git a/xpcom/base/AvailableMemoryWatcherLinux.cpp b/xpcom/base/AvailableMemoryWatcherLinux.cpp @@ -10,7 +10,6 @@ #include "mozilla/StaticPrefs_browser.h" #include "mozilla/Unused.h" #include "nsAppRunner.h" -#include "nsIAvailableMemoryWatcherTestingLinux.h" #include "nsIObserverService.h" #include "nsISupports.h" #include "nsITimer.h" @@ -107,17 +106,14 @@ static nsresult ReadPSIFile(const char* aPSIPath, PSIInfo& aResult) { // Linux has no native low memory detection. This class creates a timer that // polls for low memory and sends a low memory notification if it notices a // memory pressure event. -class nsAvailableMemoryWatcher final - : public nsITimerCallback, - public nsINamed, - public nsAvailableMemoryWatcherBase, - public nsIAvailableMemoryWatcherTestingLinux { +class nsAvailableMemoryWatcher final : public nsITimerCallback, + public nsINamed, + public nsAvailableMemoryWatcherBase { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSITIMERCALLBACK NS_DECL_NSIOBSERVER NS_DECL_NSINAMED - NS_DECL_NSIAVAILABLEMEMORYWATCHERTESTINGLINUX nsresult Init() override; nsAvailableMemoryWatcher(); @@ -126,7 +122,7 @@ class nsAvailableMemoryWatcher final void MaybeHandleHighMemory(); private: - ~nsAvailableMemoryWatcher(); + ~nsAvailableMemoryWatcher() = default; void StartPolling(const MutexAutoLock&); void StopPolling(const MutexAutoLock&); void ShutDown(); @@ -141,12 +137,6 @@ class nsAvailableMemoryWatcher final bool mUnderMemoryPressure MOZ_GUARDED_BY(mMutex); PSIInfo mPSIInfo MOZ_GUARDED_BY(mMutex); - // PSI file path - can be overridden for testing - nsCString mPSIPath MOZ_GUARDED_BY(mMutex); - - // Flag to track if SetPSIPathForTesting has been called - bool mIsTesting MOZ_GUARDED_BY(mMutex); - // Polling interval to check for low memory. In high memory scenarios, // default to 5000 ms between each check. static const uint32_t kHighMemoryPollingIntervalMS = 5000; @@ -161,16 +151,12 @@ class nsAvailableMemoryWatcher final static const char* kMeminfoPath = "/proc/meminfo"; // Linux memory PSI (Pressure Stall Information) path -static const auto kPSIPath = "/proc/pressure/memory"_ns; +static const char* kPSIPath = "/proc/pressure/memory"; nsAvailableMemoryWatcher::nsAvailableMemoryWatcher() : mPolling(false), mUnderMemoryPressure(false), - mPSIInfo{}, - mPSIPath(kPSIPath), - mIsTesting(false) {} - -nsAvailableMemoryWatcher::~nsAvailableMemoryWatcher() {} + mPSIInfo{} {} nsresult nsAvailableMemoryWatcher::Init() { nsresult rv = nsAvailableMemoryWatcherBase::Init(); @@ -212,8 +198,7 @@ already_AddRefed<nsAvailableMemoryWatcherBase> CreateAvailableMemoryWatcher() { NS_IMPL_ISUPPORTS_INHERITED(nsAvailableMemoryWatcher, nsAvailableMemoryWatcherBase, nsITimerCallback, - nsIObserver, nsINamed, - nsIAvailableMemoryWatcherTestingLinux); + nsIObserver, nsINamed); void nsAvailableMemoryWatcher::StopPolling(const MutexAutoLock&) MOZ_REQUIRES(mMutex) { @@ -282,17 +267,6 @@ nsAvailableMemoryWatcher::Notify(nsITimer* aTimer) { } else { self->MaybeHandleHighMemory(); } - if (self->mIsTesting) { - NS_DispatchToMainThread( - NS_NewRunnableFunction("MemoryPollerSync", [self]() { - nsCOMPtr<nsIObserverService> observerService = - mozilla::services::GetObserverService(); - if (observerService) { - observerService->NotifyObservers( - nullptr, "memory-poller-sync", nullptr); - } - })); - } })); if NS_FAILED (rv) { @@ -344,7 +318,7 @@ void nsAvailableMemoryWatcher::UpdateCrashAnnotation(const MutexAutoLock&) void nsAvailableMemoryWatcher::UpdatePSIInfo(const MutexAutoLock&) MOZ_REQUIRES(mMutex) { - nsresult rv = ReadPSIFile(mPSIPath.get(), mPSIInfo); + nsresult rv = ReadPSIFile(kPSIPath, mPSIInfo); if (NS_FAILED(rv)) { mPSIInfo = {}; } @@ -373,23 +347,19 @@ void nsAvailableMemoryWatcher::MaybeHandleHighMemory() { // on the new interval. void nsAvailableMemoryWatcher::StartPolling(const MutexAutoLock& aLock) MOZ_REQUIRES(mMutex) { - // Determine the effective polling interval up-front. uint32_t pollingInterval = mUnderMemoryPressure ? kLowMemoryPollingIntervalMS : kHighMemoryPollingIntervalMS; - // For tests, enforce a very small interval to speed up polling. - if (gIsGtest || mIsTesting) { - pollingInterval = 10; - } - if (!mPolling) { // Restart the timer with the new interval if it has stopped. - if (NS_SUCCEEDED(mTimer->InitWithCallback( - this, pollingInterval, nsITimer::TYPE_REPEATING_SLACK))) { + // For testing, use a small polling interval. + if (NS_SUCCEEDED( + mTimer->InitWithCallback(this, gIsGtest ? 10 : pollingInterval, + nsITimer::TYPE_REPEATING_SLACK))) { mPolling = true; } } else { - mTimer->SetDelay(pollingInterval); + mTimer->SetDelay(gIsGtest ? 10 : pollingInterval); } } @@ -423,12 +393,4 @@ NS_IMETHODIMP nsAvailableMemoryWatcher::GetName(nsACString& aName) { return NS_OK; } -NS_IMETHODIMP nsAvailableMemoryWatcher::SetPSIPathForTesting( - const nsACString& aPSIPath) { - MutexAutoLock lock(mMutex); - mPSIPath.Assign(aPSIPath); - mIsTesting = true; - return NS_OK; -} - } // namespace mozilla diff --git a/xpcom/base/moz.build b/xpcom/base/moz.build @@ -23,11 +23,6 @@ XPIDL_SOURCES += [ "nsrootidl.idl", ] -if CONFIG["OS_TARGET"] == "Linux": - XPIDL_SOURCES += [ - "nsIAvailableMemoryWatcherTestingLinux.idl", - ] - if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": XPIDL_SOURCES += [ "nsIMacPreferencesReader.idl", diff --git a/xpcom/base/nsIAvailableMemoryWatcherTestingLinux.idl b/xpcom/base/nsIAvailableMemoryWatcherTestingLinux.idl @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* 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 "nsISupports.idl" - -/** - * nsIAvailableMemoryWatcherTestingLinux: Linux-only testing interface for - * methods related to the available memory watcher. This interface is kept - * separate from nsIAvailableMemoryWatcherBase so that testing methods remain - * isolated from production code. - */ - -[builtinclass, scriptable, uuid(88c3f4a6-6f9a-4f6b-9a4b-5c1b1b0c2ad3)] -interface nsIAvailableMemoryWatcherTestingLinux : nsISupports -{ - /** - * Set the PSI file path for testing purposes. - * Only meaningful on Linux in testing builds. - */ - void setPSIPathForTesting(in ACString aPSIPath); -};