Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/toolkit/crashreporter/test/unit/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  head_win64cfi.js   Sprache: JAVA

 
/* import-globals-from head_crashreporter.js */

let gTestCrasherSyms = null;
let gModules = null;

// Returns the offset (int) of an IP with a given base address.
// This is effectively (ip - base), except a bit more complication due to
// Javascript's shaky handling of 64-bit integers.
// base & ip are passed as hex strings.
function getModuleOffset(base, ip) {
  let i = 0;
  // Find where the two addresses diverge, which enables us to perform a 32-bit
  // subtraction.
  // e.g.    "0x1111111111112222"
  //       - "0x1111111111111111"
  // becomes 2222 - 1111
  for (; i < base.length; ++i) {
    if (base[i] != ip[i]) {
      break;
    }
  }
  if (i == base.length) {
    return 0;
  }
  let lhs2 = "0x" + base.substring(i);
  let rhs2 = "0x" + ip.substring(i);
  return parseInt(rhs2) - parseInt(lhs2);
}

// Uses gTestCrasherSyms to convert an address to a symbol.
function findNearestTestCrasherSymbol(addr) {
  addr += 1; // Breakpad sometimes offsets addresses; correct for this.
  let closestDistance = null;
  let closestSym = null;
  for (let sym in gTestCrasherSyms) {
    if (addr >= gTestCrasherSyms[sym]) {
      let thisDistance = addr - gTestCrasherSyms[sym];
      if (closestDistance === null || thisDistance < closestDistance) {
        closestDistance = thisDistance;
        closestSym = sym;
      }
    }
  }
  if (closestSym === null) {
    return null;
  }
  return { symbol: closestSym, offset: closestDistance };
}

// Populate known symbols for testcrasher.dll.
// Use the same prop names as from CrashTestUtils to avoid the need for mapping.
function initTestCrasherSymbols() {
  gTestCrasherSyms = {};
  for (let k in CrashTestUtils) {
    // Not all keys here are valid symbol names. getWin64CFITestFnAddrOffset
    // will return 0 in those cases, no need to filter here.
    if (Number.isInteger(CrashTestUtils[k])) {
      let t = CrashTestUtils.getWin64CFITestFnAddrOffset(CrashTestUtils[k]);
      if (t > 0) {
        gTestCrasherSyms[k] = t;
      }
    }
  }
}

function stackFrameToString(frameIndex, frame) {
  // Calculate the module offset.
  let ip = frame.ip;
  let symbol = "";
  let moduleOffset = "unknown_offset";
  let filename = "unknown_module";

  if (
    typeof frame.module_index !== "undefined" &&
    frame.module_index >= 0 &&
    frame.module_index < gModules.length
  ) {
    let base = gModules[frame.module_index].base_addr;
    moduleOffset = getModuleOffset(base, ip);
    filename = gModules[frame.module_index].filename;

    if (filename === "testcrasher.dll") {
      let nearestSym = findNearestTestCrasherSymbol(moduleOffset);
      if (nearestSym !== null) {
        symbol = nearestSym.symbol + "+" + nearestSym.offset.toString(16);
      }
    }
  }

  let ret =
    "frames[" +
    frameIndex +
    "] ip=" +
    ip +
    " " +
    symbol +
    ", module:" +
    filename +
    ", trust:" +
    frame.trust +
    ", moduleOffset:" +
    moduleOffset.toString(16);
  return ret;
}

function dumpStackFrames(frames, maxFrames) {
  for (let i = 0; i < Math.min(maxFrames, frames.length); ++i) {
    info(stackFrameToString(i, frames[i]));
  }
}

// Test that the top of the given stack (from extra data) matches the given
// expected frames.
//
// expected is { symbol: "", trust: "" }
function assertStack(stack, expected) {
  for (let i = 0; i < stack.length; ++i) {
    if (i >= expected.length) {
      ok("Top stack frames were expected");
      return;
    }
    let frame = stack[i];
    let expectedFrame = expected[i];
    let dumpThisFrame = function () {
      info(" Actual frame: " + stackFrameToString(i, frame));
      info(
        "Expected { symbol: " +
          expectedFrame.symbol +
          ", trust: " +
          expectedFrame.trust +
          "}"
      );
    };

    if (expectedFrame.trust) {
      if (expectedFrame.trust.startsWith("!")) {
        // A "!" prefix on the frame trust matching is a logical "not".
        if (frame.trust === expectedFrame.trust.substring(1)) {
          dumpThisFrame();
          info("Expected frame trust matched when it should not have.");
          ok(false);
        }
      } else if (frame.trust !== expectedFrame.trust) {
        dumpThisFrame();
        info("Expected frame trust did not match.");
        ok(false);
      }
    }

    if (expectedFrame.symbol) {
      if (typeof frame.module_index === "undefined") {
        // Without a module_index, it happened in an unknown module. Currently
        // you can't specify an expected "unknown" module.
        info("Unknown symbol in unknown module.");
        ok(false);
      }
      if (frame.module_index < 0 || frame.module_index >= gModules.length) {
        dumpThisFrame();
        info("Unknown module.");
        ok(false);
        return;
      }
      let base = gModules[frame.module_index].base_addr;
      let moduleOffset = getModuleOffset(base, frame.ip);
      let filename = gModules[frame.module_index].filename;
      if (filename == "testcrasher.dll") {
        let nearestSym = findNearestTestCrasherSymbol(moduleOffset);
        if (nearestSym === null) {
          dumpThisFrame();
          info("Unknown symbol.");
          ok(false);
          return;
        }

        if (nearestSym.symbol !== expectedFrame.symbol) {
          dumpThisFrame();
          info("Mismatching symbol.");
          ok(false);
        }
      }
    }
  }
}

// Performs a crash, runs crashreporter minidump analyzer, and checks expected
// stack analysis.
//
// how: The crash to perform. Constants defined in both CrashTestUtils.sys.mjs
//   and nsTestCrasher.cpp (i.e. CRASH_X64CFI_PUSH_NONVOL)
// expectedStack: An array of {"symbol", "trust"} where trust is "cfi",
//   "context", "scan", et al. May be null if you don't need to check the stack.
async function do_x64CFITest(how, expectedStack) {
  // Setup is run in the subprocess so we cannot use any closures.
  let setupFn = "crashType = CrashTestUtils." + how + ";";

  let callbackFn = async function (minidumpFile, extra, extraFile) {
    runMinidumpAnalyzer(minidumpFile);

    // Refresh updated extra data
    extra = await IOUtils.readJSON(extraFile.path);

    initTestCrasherSymbols();
    let stackTraces = extra.StackTraces;
    let crashingThreadIndex = stackTraces.crash_info.crashing_thread;
    gModules = stackTraces.modules;
    let crashingFrames = stackTraces.threads[crashingThreadIndex].frames;

    dumpStackFrames(crashingFrames, 10);

    assertStack(crashingFrames, expectedStack);
  };

  do_crash(setupFn, callbackFn, truetrue);
}

Messung V0.5
C=92 H=94 G=92

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.