Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TT-1112] Fix the sourcemap handler script #1229

Open
wants to merge 73 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
372c8ef
Assert MojoPageTimingSender and RenderFrameImpl::DidCommitNavigationI…
Domiii May 8, 2024
7d09422
Fix the GetCreationContextChecked call
Domiii May 8, 2024
caff513
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 9, 2024
ae03a35
Move replay_sourcemap_handler to its own file
Domiii May 9, 2024
d85d112
Read replay_sourcemap_handler.js + fix
Domiii May 9, 2024
9c3ad72
DEPS (v8)
Domiii May 9, 2024
87b23f1
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 10, 2024
45c09aa
DEPS (v8)
Domiii May 10, 2024
c5ab8c5
undo
Domiii May 10, 2024
2690dda
update lint + build scripts
Domiii May 10, 2024
d5340a8
Add safety net to `receiver_context` generation
Domiii May 10, 2024
1077fc2
Remove `LocalDOMWindowPointerIsValid` workaround
Domiii May 10, 2024
66dd222
DEPS (v8)
Domiii May 10, 2024
32d7a55
DEPS (v8)
Domiii May 10, 2024
6f5ebaa
more checks
Domiii May 10, 2024
95d7b21
Don't crash intentionally anymore
Domiii May 10, 2024
86652af
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 12, 2024
40f37f7
WIP
Domiii May 14, 2024
72adac1
DEPS (v8)
Domiii May 14, 2024
82f5fac
DEPS (v8)
Domiii May 14, 2024
862ac54
DEPS (v8)
Domiii May 14, 2024
11be808
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 16, 2024
3ac5c89
DEPS (v8)
Domiii May 16, 2024
f3dd571
notes
Domiii May 16, 2024
0de85ee
Small things
Domiii May 16, 2024
0a5cb9b
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 17, 2024
a9d1f9a
WIP
Domiii May 17, 2024
04001f6
WIP
Domiii May 17, 2024
c863175
DEPS (v8)
Domiii May 17, 2024
19e9073
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 19, 2024
59caef9
WIP: Get the right file path for assets
Domiii May 19, 2024
887ffe2
DEPS (v8)
Domiii May 19, 2024
3268285
WIP
Domiii May 20, 2024
b2c05c3
DEPS (v8)
Domiii May 20, 2024
b9266d1
Dirty solutions!
Domiii May 20, 2024
8a926fe
WIP
Domiii May 21, 2024
0ed4689
DEPS (v8)
Domiii May 21, 2024
8f5a0a4
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 24, 2024
60a1642
fix lint problem + linter problem
Domiii May 24, 2024
6f9da13
DEPS (v8)
Domiii May 24, 2024
189488e
Fixing things
Domiii May 24, 2024
9b89e43
DEPS (v8)
Domiii May 24, 2024
6f09e1c
WIP
Domiii May 25, 2024
ae7f0b8
DEPS (v8)
Domiii May 25, 2024
71ed459
WIP
Domiii May 25, 2024
c052ec9
DEPS (v8)
Domiii May 25, 2024
2c0df14
WIP
Domiii May 26, 2024
561d5ca
WIP
Domiii May 27, 2024
4725082
WIP
Domiii May 27, 2024
5c0fa0a
WIP
Domiii May 27, 2024
122ac49
Alwys initialize the ReplayJsEventEmitter, when recording or replaying
Domiii May 28, 2024
c9ce2d5
whoops
Domiii May 28, 2024
3029c25
fix `AutoMarkReplayCode`
Domiii May 28, 2024
faa00ce
Fix `RunScriptAndCallBack` order
Domiii May 28, 2024
a10b104
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 29, 2024
99cf7f8
Rename and init order fixes
Domiii May 29, 2024
d94d8ef
DEPS (v8)
Domiii May 29, 2024
0b42ec6
DEPS (v8)
Domiii May 29, 2024
226d03d
DEPS (v8)
Domiii May 29, 2024
bebbcd6
More small fixes
Domiii May 29, 2024
48aa647
DEPS (v8)
Domiii May 29, 2024
e9a6f0c
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii May 31, 2024
19627ca
missing merged changes
Domiii May 31, 2024
857cd6a
Slightly better failed CHECK logging
Domiii May 31, 2024
bb18ed8
DEPS (v8)
Domiii May 31, 2024
52281cb
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii Jun 4, 2024
0c08c9a
Fixing bugs + cleaning up
Domiii Jun 4, 2024
6a2d39b
DEPS (v8)
Domiii Jun 4, 2024
951aede
lint
Domiii Jun 4, 2024
722f35d
fix recorder tests
Domiii Jun 4, 2024
8300b82
Merge branch 'master' of github.com:replayio/chromium into dominik/tt…
Domiii Jun 7, 2024
cadb278
DEPS (v8)
Domiii Jun 7, 2024
8b8abec
DEPS (v8)
Domiii Jun 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ steps:
depends_on:
- "build-chromium-linux-x86_64"
build:
branch: dominik/tt-1261-recorder-crashes-from-save-examplests-are-not-uploaded
env:
OS: "linux"
ARCH: "x86_64"
Expand All @@ -231,6 +232,7 @@ steps:
depends_on:
- "build-chromium-mac-arm64"
build:
branch: dominik/tt-1261-recorder-crashes-from-save-examplests-are-not-uploaded
env:
OS: "macos"
ARCH: "arm64"
Expand Down
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling V8
# and whatever else without interference from each other.
'v8_revision': '7e105ba00a264f31ed04d5bada4d3aa63be1e0f0',
'v8_revision': 'ea1ffeb18c92e9a1c7f3fda7307bc7c9825d1fb5',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling swarming_client
# and whatever else without interference from each other.
Expand Down
2 changes: 1 addition & 1 deletion REPLAY_BACKEND_REV
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9e69b244fd0973ea3f8fb46fc9eb2ce39fa615a8
63be1e1d8a17bdfe09f570f2eed77136ec29ae81
49 changes: 38 additions & 11 deletions base/logging.cc
Original file line number Diff line number Diff line change
Expand Up @@ -127,29 +127,46 @@ typedef FILE* FileHandle;
#include <windows.h>
#endif

static void* REPLAY_NO_HANDLE = reinterpret_cast<void*>(1);

static void* LookupRecordReplaySymbol(const char* name) {
#if !BUILDFLAG(IS_WIN)
void* fnptr = dlsym(RTLD_DEFAULT, name);
#else
HMODULE module = GetModuleHandleA("windows-recordreplay.dll");
void* fnptr = module ? (void*)GetProcAddress(module, name) : nullptr;
#endif
return fnptr ? fnptr : reinterpret_cast<void*>(1);
return fnptr ? fnptr : REPLAY_NO_HANDLE;
}

static void RecordReplayPrint(const char* aFormat, ...) {
static void* fnptr;
if (!fnptr) {
fnptr = LookupRecordReplaySymbol("RecordReplayPrint");
static void* g_record_replay_print_ptr;
static bool HasReplayModule() {
if (!g_record_replay_print_ptr) {
g_record_replay_print_ptr = LookupRecordReplaySymbol("RecordReplayPrint");
}
if (fnptr != reinterpret_cast<void*>(1)) {
return g_record_replay_print_ptr != REPLAY_NO_HANDLE;
}

static void RecordReplayPrint(const char* aFormat, ...) {
if (HasReplayModule()) {
va_list ap;
va_start(ap, aFormat);
reinterpret_cast<void(*)(const char*, va_list)>(fnptr)(aFormat, ap);
reinterpret_cast<void(*)(const char*, va_list)>(g_record_replay_print_ptr)(aFormat, ap);
va_end(ap);
}
}

static bool RecordReplayIsReplaying() {
static void* fnptr;
if (!fnptr) {
fnptr = LookupRecordReplaySymbol("RecordReplayIsReplaying");
}
if (fnptr != REPLAY_NO_HANDLE) {
return reinterpret_cast<bool(*)()>(fnptr)();
}
return false;
}

namespace logging {

namespace {
Expand Down Expand Up @@ -743,7 +760,10 @@ LogMessage::~LogMessage() {
size_t stack_start = stream_.str().length();
#if !defined(OFFICIAL_BUILD) && !BUILDFLAG(IS_NACL) && !defined(__UCLIBC__) && \
!BUILDFLAG(IS_AIX)
if (severity_ == LOGGING_FATAL && !base::debug::BeingDebugged()) {

// Prevent calling |BeingDebugged| since it tries to create a debugger process.
// That attempt will cause a crash when replaying when events are disallowed.
if (severity_ == LOGGING_FATAL && !RecordReplayIsReplaying() && !base::debug::BeingDebugged()) {
// Include a stack trace on a fatal, unless a debugger is attached.
base::debug::StackTrace stack_trace;
stream_ << std::endl; // Newline to separate from log message.
Expand All @@ -766,8 +786,15 @@ LogMessage::~LogMessage() {
#endif
stream_ << std::endl;
std::string str_newline(stream_.str());

RecordReplayPrint("LogMessage %s", str_newline.c_str());

if (severity_ == LOGGING_FATAL) {
// TODO: We actually want to crash with the right reason, but we don't have
// access to V8RecordReplayCrash.
// RecordReplayCrash("FATAL: %s", str_newline.c_str());
RecordReplayPrint("FATAL: %s", str_newline.c_str());
} else {
RecordReplayPrint("LogMessage [%d/%d] %s", severity_, LOGGING_NUM_SEVERITIES-1, str_newline.c_str());
}

TRACE_LOG_MESSAGE(
file_, base::StringPiece(str_newline).substr(message_start_), line_);
Expand Down Expand Up @@ -981,7 +1008,7 @@ LogMessage::~LogMessage() {
// information, and displaying message boxes when the application is
// hosed can cause additional problems.
#ifndef NDEBUG
if (!base::debug::BeingDebugged()) {
if (!RecordReplayIsReplaying() && !base::debug::BeingDebugged()) {
// Displaying a dialog is unnecessary when debugging and can complicate
// debugging.
DisplayDebugMessageInDialog(stream_.str());
Expand Down
7 changes: 4 additions & 3 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ function spawnChecked(cmd, args, options) {

const rv = spawnSync(cmd, args, options);

if (rv.status != 0 || rv.error) {
if (rv.status || rv.error || rv.signal) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this related to this change or TT-1150?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latter. But also: Its just a bug in this function 🤷‍♀️

const errMsg = ` Spawned process "${prettyCmd}" failed: status=${rv.status || ""}, signal=${rv.signal || ""}, err=${rv.error || ""}`;
console.error(
`Process failed: err=${rv.error || ""}, signal=${rv.signal || ""}`
errMsg
);
throw new Error(`Spawned process failed with exit code ${rv.status}`);
throw new Error(errMsg);
}

return rv;
Expand Down
80 changes: 45 additions & 35 deletions replay-assets/replay_command_handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ const {
hasDiverged,
setCDPMessageCallback,
sendCDPMessage: sendCDPMessageRaw,
setCommandCallback,
setClearPauseDataCallback,
addNewScriptHandler,
getCurrentError,

layoutDom,
Expand Down Expand Up @@ -53,7 +50,7 @@ const {
// utils.js
///////////////////////////////////////////////////////////////////////////////

// Some of these are duplicated in gSourceMapScript, so watch out when making
// Some of these are duplicated in replay_sourcemap_handler, so watch out when making
// modifications to update both versions...

function isFunction(val) {
Expand Down Expand Up @@ -144,13 +141,11 @@ function isValidBaseURL(url) {
}

///////////////////////////////////////////////////////////////////////////////
// message.js
// CDP Handlers.
///////////////////////////////////////////////////////////////////////////////

function initMessages() {
function initCdp() {
setCDPMessageCallback(messageCallback);
setCommandCallback(commandCallback);
setClearPauseDataCallback(clearPauseDataCallback);
}

let gNextMessageId = 1;
Expand Down Expand Up @@ -232,7 +227,7 @@ function sendCDPMessage(method, params) {
const sendMessage = sendCDPMessage;


function addEventListener(method, callback) {
function addCDPEventListener(method, callback) {
gEventListeners.set(method, callback);
}

Expand Down Expand Up @@ -323,19 +318,23 @@ function executeCommand(method, params) {
VerboseCommands && log(`[Command ${method}] Handling command, params=${JSON_stringify(params)}...`);
const result = CommandCallbacks[method](params);
VerboseCommands && log(`[Command ${method}] Handled command, result=${JSON_stringify(result)}`);
if (!result) {
// NOTE: CommandCallback expects a result.
throw new Error(`[Command ${method}] Did not return a result.`);
}
return result;
}

function commandCallback(method, params) {
if (!CommandCallbacks[method]) {
log(`[RuntimeError][Command ${method}] Missing command callback: ${method}`);
function commandCallback(commandName, params) {
if (!CommandCallbacks[commandName]) {
log(`[RuntimeError][Command ${commandName}] Missing command callback: ${commandName}`);
return {};
}

try {
return executeCommand(method, params);
return executeCommand(commandName, params);
} catch (e) {
log(`[RuntimeError][Command ${method}]${getAliveLabel()} ${e?.stack || e}`);
log(`[RuntimeError][Command ${commandName}]${getAliveLabel()} ${e?.stack || e}`);
// Pass the error up to V8; it can (for now) decide how to handle itself, whether
// it should crash or not, etc. Eventually, the caller of the command should make
// that decision.
Expand Down Expand Up @@ -426,21 +425,6 @@ function Target_getCurrentMessageContents() {
};
}

addNewScriptHandler((scriptId, sourceURL, relativeSourceMapURL) => {
if (!relativeSourceMapURL)
return;

const urls = getSourceMapURLs(sourceURL, relativeSourceMapURL);
if (!urls)
return;

const { sourceMapURL, sourceMapBaseURL } = urls;
gSourceMapData.set(scriptId, {
url: sourceMapURL,
baseUrl: sourceMapBaseURL
});
}, /* disallowEvents */ true);

function Target_getSourceMapURL({ sourceId }) {
return gSourceMapData.get(sourceId) || {};
}
Expand Down Expand Up @@ -3317,28 +3301,52 @@ function wrapReplayApiFunction(fn) {
};
}

/** ###########################################################################
* ReplayJs: Internal event handling.
* ##########################################################################*/

function handleNewScript(scriptId, sourceURL, relativeSourceMapURL) {
if (!relativeSourceMapURL)
return;

const urls = getSourceMapURLs(sourceURL, relativeSourceMapURL);
if (!urls)
return;

const { sourceMapURL, sourceMapBaseURL } = urls;
gSourceMapData.set(scriptId, {
url: sourceMapURL,
baseUrl: sourceMapBaseURL
});
}

function initializeReplayJsEvents(ReplayJsEventEmitter) {
ReplayJsEventEmitter.on("command", commandCallback);
ReplayJsEventEmitter.on("clearPauseDataCallback", clearPauseDataCallback);
ReplayJsEventEmitter.on("newScriptEventsDisallowed", handleNewScript);
}

///////////////////////////////////////////////////////////////////////////////
// main.js
///////////////////////////////////////////////////////////////////////////////

patchReplayApi();
initMessages();
addEventListener("Runtime.consoleAPICalled", onConsoleAPICall);
addEventListener("Runtime.executionContextCreated", ({ context }) => {
initCdp();
addCDPEventListener("Runtime.consoleAPICalled", onConsoleAPICall);
addCDPEventListener("Runtime.executionContextCreated", ({ context }) => {
gExecutionContexts.set(context.id, context);
for (const callback of gContextChangeCallbacks) {
callback(context, "add");
}
});
addEventListener("Runtime.executionContextDestroyed", ({ executionContextId }) => {
addCDPEventListener("Runtime.executionContextDestroyed", ({ executionContextId }) => {
const context = gExecutionContexts.get(executionContextId);
for (const callback of gContextChangeCallbacks) {
callback(context, "remove");
}
gExecutionContexts.delete(executionContextId);
});
addEventListener("Runtime.executionContextsCleared", () => {
addCDPEventListener("Runtime.executionContextsCleared", () => {
for (const context of gExecutionContexts.values()) {
for (const callback of gContextChangeCallbacks) {
callback(context, "remove");
Expand All @@ -3348,4 +3356,6 @@ addEventListener("Runtime.executionContextsCleared", () => {
});
sendCDPMessage("Runtime.enable");

})();
// Script return value
return initializeReplayJsEvents;
})()
37 changes: 37 additions & 0 deletions replay-assets/replay_init.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(() => {
/** ###########################################################################
* ReplayJs: Internal event handling.
* ##########################################################################*/

const ReplayJsEventEmitterPrototype = {
on(event, cb) {
this._callbacks[event] ||= [];
this._callbacks[event].push(cb);
},

emit(event, ...args) {
let cbs = this._callbacks[event];
if (cbs) {
cbs.forEach((cb) => cb(...args));
}
},

emitWithResult(event, ...args) {
let cbs = this._callbacks[event];
if (!cbs?.length) {
// If the caller expects a return value, there must be at least one callback registered.
throw new Error(`ReplayJsEvent_emitWithResult_failed_unknown_event: ${event}`);
}
const rv = cbs[0](...args);
return rv;
},
};

function initializeReplayJsEvents(ReplayJsEventEmitter) {
// Set up the event emitter.
Object.assign(ReplayJsEventEmitter, ReplayJsEventEmitterPrototype);
ReplayJsEventEmitter._callbacks = {};
}

return initializeReplayJsEvents;
})();
Loading