Source code
Revision control
Copy as Markdown
Other Tools
/* 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,
/* Helpers for recognising ASan's allocator fill byte in Web Audio tests. */
"use strict";
// Keep these values in sync with build/sanitizers/AsanOptions.cpp.
const ASAN_EXPECTED_MALLOC_FILL_BYTE = 0xe4;
const ASAN_EXPECTED_MAX_MALLOC_FILL_SIZE = 268435456;
// Uint32Array reads unsigned values, so convert the byte tile to unsigned.
function asanTileByte(b) {
return ((b << 24) | (b << 16) | (b << 8) | b) >>> 0;
}
const ASAN_EXPECTED_SENTINEL = asanTileByte(ASAN_EXPECTED_MALLOC_FILL_BYTE);
// Compiler-rt accepts colon, comma, and whitespace separators; the last value wins.
function asanParseOption(opts, key) {
const sep = "[:\\s,]";
const re = new RegExp(`(?:^|${sep})${key}=([^:\\s,]+)(?=${sep}|$)`, "g");
return [...opts.matchAll(re)].at(-1)?.[1];
}
// Fail if ASAN_OPTIONS differs from the expected fill configuration.
function asanVerifyFillOptions() {
const env = SpecialPowers.Services.env;
const opts = env.exists("ASAN_OPTIONS") ? env.get("ASAN_OPTIONS") : "";
const liveByte = asanParseOption(opts, "malloc_fill_byte");
const liveSize = asanParseOption(opts, "max_malloc_fill_size");
info(
`Live ASAN_OPTIONS overrides: malloc_fill_byte=${liveByte} ` +
`max_malloc_fill_size=${liveSize}; ` +
`expected sentinel=0x${ASAN_EXPECTED_SENTINEL.toString(16)}`
);
if (
liveByte !== undefined &&
parseInt(liveByte, 10) !== ASAN_EXPECTED_MALLOC_FILL_BYTE
) {
ok(
false,
`ASan malloc_fill_byte=${liveByte} on this worker differs from the ` +
`value this test was written against ` +
`(${ASAN_EXPECTED_MALLOC_FILL_BYTE}, per build/sanitizers/AsanOptions.cpp). ` +
`Update ASAN_OPTIONS or both files in lockstep to re-align.`
);
return false;
}
if (
liveSize !== undefined &&
parseInt(liveSize, 10) !== ASAN_EXPECTED_MAX_MALLOC_FILL_SIZE
) {
ok(
false,
`ASan max_malloc_fill_size=${liveSize} on this worker differs from the ` +
`value this test was written against ` +
`(${ASAN_EXPECTED_MAX_MALLOC_FILL_SIZE}, per build/sanitizers/AsanOptions.cpp). ` +
`Update ASAN_OPTIONS or both files in lockstep to re-align.`
);
return false;
}
return true;
}
// Return the number and first index of ASan fill values in one channel.
function asanCountFillSentinel(channelData) {
const u32 = new Uint32Array(
channelData.buffer,
channelData.byteOffset,
channelData.length
);
let count = 0;
let firstIndex = -1;
for (let i = 0; i < u32.length; i++) {
if (u32[i] === ASAN_EXPECTED_SENTINEL) {
if (firstIndex < 0) {
firstIndex = i;
}
count++;
}
}
return { count, firstIndex };
}