tor-browser

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

browser_sandbox_profiler.js (4036B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { ProfilerTestUtils } = ChromeUtils.importESModule(
      7  "resource://testing-common/ProfilerTestUtils.sys.mjs"
      8 );
      9 
     10 async function addTab() {
     11  const tab = BrowserTestUtils.addTab(gBrowser, "https://example.com/browser", {
     12    forceNewProcess: true,
     13  });
     14  const browser = gBrowser.getBrowserForTab(tab);
     15  await BrowserTestUtils.browserLoaded(browser);
     16  return tab;
     17 }
     18 
     19 const sandboxSettingsEnabled = {
     20  entries: 8 * 1024 * 1024, // 8M entries = 64MB
     21  interval: 1, // ms
     22  features: ["stackwalk", "sandbox"],
     23  threads: ["SandboxProfilerEmitter"],
     24 };
     25 
     26 const sandboxSettingsDisabled = {
     27  entries: 8 * 1024 * 1024, // 8M entries = 64MB
     28  interval: 1, // ms
     29  features: ["stackwalk"],
     30  threads: ["SandboxProfilerEmitter"],
     31 };
     32 
     33 const kNewProcesses = 2;
     34 
     35 async function waitForMaybeSandboxProfilerData(
     36  threadName,
     37  name1,
     38  withStacks,
     39  enabled
     40 ) {
     41  let tabs = [];
     42  for (let i = 0; i < kNewProcesses; ++i) {
     43    tabs.push(await addTab());
     44  }
     45 
     46  let profile;
     47  let intercepted = undefined;
     48  try {
     49    await TestUtils.waitForCondition(
     50      async () => {
     51        profile = await Services.profiler.getProfileDataAsync();
     52        intercepted = profile.processes
     53          .flatMap(ps => {
     54            let sandboxThreads = ps.threads.filter(
     55              th => th.name === threadName
     56            );
     57            return sandboxThreads.flatMap(th => {
     58              let markersData = th.markers.data;
     59              return markersData.flatMap(d => {
     60                let [, , , , , o] = d;
     61                return o;
     62              });
     63            });
     64          })
     65          .filter(x => "name1" in x && name1.includes(x.name1) >= 0);
     66        return !!intercepted.length;
     67      },
     68      `Wait for some samples from ${threadName}`,
     69      /* interval*/ 100,
     70      /* maxTries */ 25
     71    );
     72    Assert.greater(
     73      intercepted.length,
     74      0,
     75      `Should have collected some data from ${threadName}`
     76    );
     77  } catch (ex) {
     78    if (!enabled && ex.includes(`Wait for some samples from ${threadName}`)) {
     79      Assert.equal(
     80        intercepted.length,
     81        0,
     82        `Should have NOT collected data from ${threadName}`
     83      );
     84    } else {
     85      throw ex;
     86    }
     87  }
     88 
     89  if (withStacks) {
     90    let stacks = profile.processes.flatMap(ps => {
     91      let sandboxThreads = ps.threads.filter(th => th.name === threadName);
     92      return sandboxThreads.flatMap(th => {
     93        let stackTableData = th.stackTable.data;
     94        return stackTableData.flatMap(d => {
     95          return [d];
     96        });
     97      });
     98    });
     99    if (enabled) {
    100      Assert.greater(stacks.length, 0, "Should have some stack as well");
    101    } else {
    102      Assert.equal(stacks.length, 0, "Should have NO stack as well");
    103    }
    104  }
    105 
    106  for (let tab of tabs) {
    107    await BrowserTestUtils.removeTab(tab);
    108  }
    109 }
    110 
    111 add_task(async () => {
    112  await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
    113  await waitForMaybeSandboxProfilerData(
    114    "SandboxProfilerEmitterSyscalls",
    115    ["id", "init"],
    116    /* withStacks */ true,
    117    /* enabled */ true
    118  );
    119  await Services.profiler.StopProfiler();
    120 });
    121 
    122 add_task(async () => {
    123  await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
    124  await waitForMaybeSandboxProfilerData(
    125    "SandboxProfilerEmitterLogs",
    126    ["log"],
    127    /* withStacks */ false,
    128    /* enabled */ true
    129  );
    130  await Services.profiler.StopProfiler();
    131 });
    132 
    133 add_task(async () => {
    134  await ProfilerTestUtils.startProfiler(sandboxSettingsDisabled);
    135  await waitForMaybeSandboxProfilerData(
    136    "SandboxProfilerEmitterSyscalls",
    137    ["id", "init"],
    138    /* withStacks */ true,
    139    /* enabled */ false
    140  );
    141  await Services.profiler.StopProfiler();
    142 });
    143 
    144 add_task(async () => {
    145  await ProfilerTestUtils.startProfiler(sandboxSettingsEnabled);
    146  await waitForMaybeSandboxProfilerData(
    147    "SandboxProfilerEmitterLogs",
    148    ["log"],
    149    /* withStacks */ false,
    150    /* enabled */ false
    151  );
    152  await Services.profiler.StopProfiler();
    153 });