Backed out 2 changesets (bug 1678152, bug 1751041) for causing failures in test_missing_intermediate.js CLOSED TREE

Backed out changeset 034ae0e4c467 (bug 1751041)
Backed out changeset 46640f068ae4 (bug 1678152)
This commit is contained in:
Noemi Erli 2022-01-25 20:09:51 +02:00
Родитель c07c87c034
Коммит f471472a6b
14 изменённых файлов: 70 добавлений и 230 удалений

Просмотреть файл

@ -760,7 +760,7 @@ void APZCTreeManager::SampleForWebRender(const Maybe<VsyncId>& aVsyncId,
it->second->RecordSampledResult(
apzc->GetCurrentAsyncScrollOffsetInCssPixels(
AsyncPanZoomController::eForCompositing),
(aSampleTime.Time() - TimeStamp::ProcessCreation())
(aSampleTime.Time() - TimeStamp::ProcessCreation(nullptr))
.ToMicroseconds(),
guid.mLayersId, guid.mScrollId);
}

Просмотреть файл

@ -36,29 +36,7 @@ struct TimeStampInitialization {
TimeStampInitialization() {
TimeStamp::Startup();
TimeStamp now = TimeStamp::Now();
TimeStamp process_creation;
char* mozAppRestart = getenv("MOZ_APP_RESTART");
/* When calling PR_SetEnv() with an empty value the existing variable may
* be unset or set to the empty string depending on the underlying platform
* thus we have to check if the variable is present and not empty. */
if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
process_creation = now;
} else {
uint64_t uptime = TimeStamp::ComputeProcessUptime();
process_creation =
now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
if ((process_creation > now) || (uptime == 0)) {
process_creation = now;
}
}
mFirstTimeStamp = now;
mProcessCreation = process_creation;
mFirstTimeStamp = TimeStamp::Now();
// On Windows < 10, initializing the uptime requires `mFirstTimeStamp` to be
// valid.
mozilla::InitializeUptime();
@ -69,12 +47,47 @@ struct TimeStampInitialization {
static TimeStampInitialization sInitOnce;
MFBT_API TimeStamp TimeStamp::ProcessCreation() {
MFBT_API TimeStamp TimeStamp::ProcessCreation(bool* aIsInconsistent) {
if (aIsInconsistent) {
*aIsInconsistent = false;
}
if (sInitOnce.mProcessCreation.IsNull()) {
char* mozAppRestart = getenv("MOZ_APP_RESTART");
TimeStamp ts;
/* When calling PR_SetEnv() with an empty value the existing variable may
* be unset or set to the empty string depending on the underlying platform
* thus we have to check if the variable is present and not empty. */
if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
/* Firefox was restarted, use the first time-stamp we've taken as the new
* process startup time. */
ts = sInitOnce.mFirstTimeStamp;
} else {
TimeStamp now = Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(uptime);
if ((ts > sInitOnce.mFirstTimeStamp) || (uptime == 0)) {
/* If the process creation timestamp was inconsistent replace it with
* the first one instead and notify that a telemetry error was
* detected. */
if (aIsInconsistent) {
*aIsInconsistent = true;
}
ts = sInitOnce.mFirstTimeStamp;
}
}
sInitOnce.mProcessCreation = ts;
}
return sInitOnce.mProcessCreation;
}
void TimeStamp::RecordProcessRestart() {
sInitOnce.mProcessCreation = TimeStamp::Now();
sInitOnce.mProcessCreation = TimeStamp();
}
} // namespace mozilla

Просмотреть файл

@ -7,14 +7,14 @@
#ifndef mozilla_TimeStamp_h
#define mozilla_TimeStamp_h
#include <stdint.h>
#include <algorithm> // for std::min, std::max
#include <ostream>
#include <type_traits>
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/Types.h"
#include <algorithm> // for std::min, std::max
#include <ostream>
#include <stdint.h>
#include <type_traits>
namespace IPC {
template <typename T>
@ -422,11 +422,16 @@ class TimeStamp {
/**
* Return a timestamp representing the time when the current process was
* created which will be comparable with other timestamps taken with this
* class.
* class. If the actual process creation time is detected to be inconsistent
* the @a aIsInconsistent parameter will be set to true, the returned
* timestamp however will still be valid though inaccurate.
*
* @returns A timestamp representing the time when the process was created
* @param aIsInconsistent If non-null, set to true if an inconsistency was
* detected in the process creation time
* @returns A timestamp representing the time when the process was created,
* this timestamp is always valid even when errors are reported
*/
static MFBT_API TimeStamp ProcessCreation();
static MFBT_API TimeStamp ProcessCreation(bool* aIsInconsistent = nullptr);
/**
* Records a process restart. After this call ProcessCreation() will return
@ -526,10 +531,8 @@ class TimeStamp {
private:
friend struct IPC::ParamTraits<mozilla::TimeStamp>;
friend struct TimeStampInitialization;
MOZ_IMPLICIT
TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
MOZ_IMPLICIT TimeStamp(TimeStampValue aValue) : mValue(aValue) {}
static MFBT_API TimeStamp Now(bool aHighResolution);

Просмотреть файл

@ -42,7 +42,8 @@ static nsReturnRef<HANDLE> CreateProcessWrapper(const wchar_t* aPath) {
int ChildMain() {
// Make sure a process creation timestamp is always not bigger than
// the current timestamp.
auto t0 = mozilla::TimeStamp::ProcessCreation();
bool inconsistent = false;
auto t0 = mozilla::TimeStamp::ProcessCreation(&inconsistent);
auto t1 = mozilla::TimeStamp::Now();
if (t0 > t1) {
printf(

Просмотреть файл

@ -45,11 +45,14 @@ void StartupTimeline::RecordOnce(Event ev, const TimeStamp& aWhen) {
// Record first paint timestamp as a scalar.
if (ev == FIRST_PAINT || ev == FIRST_PAINT2) {
bool error = false;
uint32_t firstPaintTime =
(uint32_t)(aWhen - TimeStamp::ProcessCreation()).ToMilliseconds();
Telemetry::ScalarSet(ev == FIRST_PAINT
? Telemetry::ScalarID::TIMESTAMPS_FIRST_PAINT
: Telemetry::ScalarID::TIMESTAMPS_FIRST_PAINT_TWO,
firstPaintTime);
(uint32_t)(aWhen - TimeStamp::ProcessCreation(&error)).ToMilliseconds();
if (!error) {
Telemetry::ScalarSet(
ev == FIRST_PAINT ? Telemetry::ScalarID::TIMESTAMPS_FIRST_PAINT
: Telemetry::ScalarID::TIMESTAMPS_FIRST_PAINT_TWO,
firstPaintTime);
}
}
}

Просмотреть файл

@ -823,7 +823,9 @@ nsAppStartup::GetStartupInfo(JSContext* aCx,
TimeStamp procTime = StartupTimeline::Get(StartupTimeline::PROCESS_CREATION);
if (procTime.IsNull()) {
procTime = TimeStamp::ProcessCreation();
bool error = false;
procTime = TimeStamp::ProcessCreation(&error);
StartupTimeline::Record(StartupTimeline::PROCESS_CREATION, procTime);
}

Просмотреть файл

@ -53,7 +53,6 @@ if CONFIG["MOZ_CRASHREPORTER"]:
"google-breakpad/src/common",
"google-breakpad/src/common/linux",
"google-breakpad/src/processor",
"pthread_create_interposer",
]
if CONFIG["MOZ_OXIDIZED_BREAKPAD"]:

Просмотреть файл

@ -1,12 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
NoVisibilityFlags()
UNIFIED_SOURCES += [
"pthread_create_interposer.cpp",
]
FINAL_LIBRARY = "mozglue"

Просмотреть файл

@ -1,119 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm>
#include <dlfcn.h>
#include <pthread.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/mman.h>
#include "mozilla/Assertions.h"
#include "mozilla/DebugOnly.h"
using mozilla::DebugOnly;
struct PthreadCreateParams {
void* (*start_routine)(void*);
void* arg;
};
const size_t kSigStackSize = std::max(size_t(16384), size_t(SIGSTKSZ));
// Install the alternate signal stack, returns a pointer to the memory area we
// mapped to store the stack only if it was installed successfully, otherwise
// returns NULL.
static void* install_sig_alt_stack() {
void* alt_stack_mem = mmap(nullptr, kSigStackSize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (alt_stack_mem) {
stack_t alt_stack = {
.ss_sp = alt_stack_mem,
.ss_flags = 0,
.ss_size = kSigStackSize,
};
int rv = sigaltstack(&alt_stack, nullptr);
if (rv == 0) {
return alt_stack_mem;
}
rv = munmap(alt_stack_mem, kSigStackSize);
MOZ_ASSERT(rv == 0);
}
return nullptr;
}
// Uninstall the alternate signal handler and unmaps it. Does nothing if
// alt_stack_mem is NULL.
static void uninstall_sig_alt_stack(void* alt_stack_mem) {
if (alt_stack_mem) {
stack_t disable_alt_stack = {};
disable_alt_stack.ss_flags = SS_DISABLE;
DebugOnly<int> rv = sigaltstack(&disable_alt_stack, nullptr);
MOZ_ASSERT(rv == 0);
rv = munmap(alt_stack_mem, kSigStackSize);
MOZ_ASSERT(rv == 0);
}
}
// This replaces the routine passed to pthread_create() when a thread is
// started, it handles the alternate signal stack and calls the thread's
// actual routine.
void* set_alt_signal_stack_and_start(PthreadCreateParams* params) {
void* (*start_routine)(void*) = params->start_routine;
void* arg = params->arg;
free(params);
void* thread_rv = nullptr;
void* alt_stack_mem = install_sig_alt_stack();
pthread_cleanup_push(uninstall_sig_alt_stack, alt_stack_mem);
thread_rv = start_routine(arg);
pthread_cleanup_pop(1);
return thread_rv;
}
using pthread_create_func_t = int (*)(pthread_t*, const pthread_attr_t*,
void* (*)(void*), void*);
extern "C" {
// This interposer replaces libpthread's pthread_create() so that we can
// inject an alternate signal stack in every new thread.
__attribute__((visibility("default"))) int pthread_create(
pthread_t* thread, const pthread_attr_t* attr,
void* (*start_routine)(void*), void* arg) {
// static const pthread_create_func_t real_pthread_create =
static const pthread_create_func_t real_pthread_create =
(pthread_create_func_t)dlsym(RTLD_NEXT, "pthread_create");
if (real_pthread_create == nullptr) {
MOZ_CRASH(
"pthread_create() interposition failed but the interposer function is "
"still being called, this won't work!");
}
if (real_pthread_create == pthread_create) {
MOZ_CRASH(
"We could not obtain the real pthread_create(). Calling the symbol we "
"got would make us enter an infinte loop so stop here instead.");
}
PthreadCreateParams* params =
(PthreadCreateParams*)malloc(sizeof(PthreadCreateParams));
params->start_routine = start_routine;
params->arg = arg;
int result = real_pthread_create(
thread, attr, (void* (*)(void*))set_alt_signal_stack_and_start, params);
if (result != 0) {
free(params);
}
return result;
}
}

Просмотреть файл

@ -36,7 +36,6 @@ var CrashTestUtils = {
CRASH_PHC_BOUNDS_VIOLATION: 23,
CRASH_HEAP_CORRUPTION: 24,
CRASH_EXC_GUARD: 25,
CRASH_STACK_OVERFLOW: 26,
// Constants for dumpHasStream()
// From google_breakpad/common/minidump_format.h

Просмотреть файл

@ -97,7 +97,6 @@ const int16_t CRASH_PHC_DOUBLE_FREE = 22;
const int16_t CRASH_PHC_BOUNDS_VIOLATION = 23;
const int16_t CRASH_HEAP_CORRUPTION = 24;
const int16_t CRASH_EXC_GUARD = 25;
const int16_t CRASH_STACK_OVERFLOW = 26;
#if XP_WIN && HAVE_64BIT_BUILD && defined(_M_X64) && !defined(__MINGW32__)
@ -154,23 +153,6 @@ uint8_t* GetPHCAllocation(size_t aSize) {
}
#endif
#ifndef XP_WIN
static void* overflow_stack(void* aUnused) {
// We use a dummy variable and a bit of magic to pretend we care about what's
// on the stack so the compiler doesn't optimize the loop and allocations away
void* rv = nullptr;
for (size_t i = 0; i < 1024 * 1024 * 1024; i++) {
void* ptr = alloca(sizeof(void*));
if (ptr != nullptr) {
rv = ptr;
}
}
return rv;
}
#endif // XP_WIN
extern "C" NS_EXPORT void Crash(int16_t how) {
switch (how) {
case CRASH_INVALID_POINTER_DEREF: {
@ -283,17 +265,6 @@ extern "C" NS_EXPORT void Crash(int16_t how) {
}
}
#endif // XP_MACOSX
#ifndef XP_WIN
case CRASH_STACK_OVERFLOW: {
pthread_t thread_id;
int rv = pthread_create(&thread_id, nullptr, overflow_stack, nullptr);
if (!rv) {
pthread_join(thread_id, nullptr);
}
break; // This should be unreachable
}
#endif // XP_WIN
default:
break;
}

Просмотреть файл

@ -1,21 +0,0 @@
add_task(async function run_test() {
if (!("@mozilla.org/toolkit/crash-reporter;1" in Cc)) {
dump(
"INFO | test_crash_stack_overflow.js | Can't test crashreporter in a non-libxul build.\n"
);
return;
}
// Try crashing by overflowing a thread's stack
await do_crash(
function() {
crashType = CrashTestUtils.CRASH_STACK_OVERFLOW;
crashReporter.annotateCrashReport("TestKey", "TestValue");
},
async function(mdump, extra, extraFile) {
Assert.equal(extra.TestKey, "TestValue");
},
// process will exit with a zero exit status
true
);
});

Просмотреть файл

@ -124,6 +124,3 @@ skip-if = !(os == 'win' && bits == 64 && processor == 'x86_64')
reason = Windows test specific to the x86-64 architecture
support-files = test_crash_win64cfi_not_a_pe.exe
[test_crash_stack_overflow.js]
skip-if = os != 'linux'
reason = Still broken on macOS and not yet supported on Windows

Просмотреть файл

@ -41,7 +41,11 @@ void SchedulerGroup::MarkVsyncReceived() {
// May be called on any thread when a vsync is received and scheduled to be
// processed. This may occur on the main thread due to queued messages when
// the channel is connected.
TimeStamp creation = TimeStamp::ProcessCreation();
bool inconsistent = false;
TimeStamp creation = TimeStamp::ProcessCreation(&inconsistent);
if (inconsistent) {
return;
}
// Attempt to set gEarliestUnprocessedVsync to our new value. If we've seen a
// vsync already, but haven't handled it, the `compareExchange` will fail and