Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/devtools/server/actors/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 6 kB image not shown  

Quelle  breakpoint.js   Sprache: JAVA

 
/* 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/. */


/* global assert */

"use strict";

const {
  logEvent,
  getThrownMessage,
} = require("resource://devtools/server/actors/utils/logEvent.js");

/**
 * Set breakpoints on all the given entry points with the given
 * BreakpointActor as the handler.
 *
 * @param BreakpointActor actor
 *        The actor handling the breakpoint hits.
 * @param Array entryPoints
 *        An array of objects of the form `{ script, offsets }`.
 */

function setBreakpointAtEntryPoints(actor, entryPoints) {
  for (const { script, offsets } of entryPoints) {
    actor.addScript(script, offsets);
  }
}

exports.setBreakpointAtEntryPoints = setBreakpointAtEntryPoints;

/**
 * BreakpointActors are instantiated for each breakpoint that has been installed
 * by the client. They are not true actors and do not communicate with the
 * client directly, but encapsulate the DebuggerScript locations where the
 * breakpoint is installed.
 */

class BreakpointActor {
  constructor(threadActor, location) {
    // A map from Debugger.Script instances to the offsets which the breakpoint
    // has been set for in that script.
    this.scripts = new Map();

    this.threadActor = threadActor;
    this.location = location;
    this.options = null;
  }

  setOptions(options) {
    const oldOptions = this.options;
    this.options = options;

    for (const [script, offsets] of this.scripts) {
      this._newOffsetsOrOptions(script, offsets, oldOptions);
    }
  }

  destroy() {
    this.removeScripts();
    this.options = null;
  }

  hasScript(script) {
    return this.scripts.has(script);
  }

  /**
   * Called when this same breakpoint is added to another Debugger.Script
   * instance.
   *
   * @param script Debugger.Script
   *        The new source script on which the breakpoint has been set.
   * @param offsets Array
   *        Any offsets in the script the breakpoint is associated with.
   */

  addScript(script, offsets) {
    this.scripts.set(script, offsets.concat(this.scripts.get(offsets) || []));
    this._newOffsetsOrOptions(script, offsets, null);
  }

  /**
   * Remove the breakpoints from associated scripts and clear the script cache.
   */

  removeScripts() {
    for (const [script] of this.scripts) {
      script.clearBreakpoint(this);
    }
    this.scripts.clear();
  }

  /**
   * Called on changes to this breakpoint's script offsets or options.
   */

  _newOffsetsOrOptions(script, offsets) {
    // Clear any existing handler first in case this is called multiple times
    // after options change.
    for (const offset of offsets) {
      script.clearBreakpoint(this, offset);
    }

    // In all other cases, this is used as a script breakpoint handler.
    for (const offset of offsets) {
      script.setBreakpoint(offset, this);
    }
  }

  /**
   * Check if this breakpoint has a condition that doesn't error and
   * evaluates to true in frame.
   *
   * @param frame Debugger.Frame
   *        The frame to evaluate the condition in
   * @returns Object
   *          - result: boolean|undefined
   *            True when the conditional breakpoint should trigger a pause,
   *            false otherwise. If the condition evaluation failed/killed,
   *            `result` will be `undefined`.
   *          - message: string
   *            If the condition throws, this is the thrown message.
   */

  checkCondition(frame, condition) {
    // Ensure disabling breakpoint while evaluating the condition.
    // All but exception breakpoint to report any exception when running the condition.
    this.threadActor.insideClientEvaluation = {
      disableBreaks: true,
      reportExceptionsWhenBreaksAreDisabled: true,
    };
    let completion;

    // Temporarily enable pause on exception when evaluating the condition.
    const hadToEnablePauseOnException =
      !this.threadActor.isPauseOnExceptionsEnabled();
    try {
      if (hadToEnablePauseOnException) {
        this.threadActor.setPauseOnExceptions(true);
      }
      completion = frame.eval(condition, { hideFromDebugger: true });
    } finally {
      this.threadActor.insideClientEvaluation = null;
      if (hadToEnablePauseOnException) {
        this.threadActor.setPauseOnExceptions(false);
      }
    }
    if (completion) {
      if (completion.throw) {
        // The evaluation failed and threw
        return {
          result: true,
          message: getThrownMessage(completion),
        };
      } else if (completion.yield) {
        assert(false"Shouldn't ever get yield completions from an eval");
      } else {
        return { result: !!completion.return };
      }
    }
    // The evaluation was killed (possibly by the slow script dialog)
    return { result: undefined };
  }

  /**
   * A function that the engine calls when a breakpoint has been hit.
   *
   * @param frame Debugger.Frame
   *        The stack frame that contained the breakpoint.
   */

  // eslint-disable-next-line complexity
  hit(frame) {
    if (this.threadActor.shouldSkipAnyBreakpoint) {
      return undefined;
    }

    // Don't pause if we are currently stepping (in or over) or the frame is
    // black-boxed.
    const location = this.threadActor.sourcesManager.getFrameLocation(frame);
    if (this.threadActor.sourcesManager.isFrameBlackBoxed(frame)) {
      return undefined;
    }

    // If we're trying to pop this frame, and we see a breakpoint at
    // the spot at which popping started, ignore it.  See bug 970469.
    const locationAtFinish = frame.onPop?.location;
    if (
      locationAtFinish &&
      locationAtFinish.line === location.line &&
      locationAtFinish.column === location.column
    ) {
      return undefined;
    }

    if (!this.threadActor.hasMoved(frame, "breakpoint")) {
      return undefined;
    }

    const reason = { type: "breakpoint", actors: [this.actorID] };
    const { condition, logValue } = this.options || {};

    if (condition) {
      const { result, message } = this.checkCondition(frame, condition);

      // Don't pause if the result is falsey
      if (!result) {
        return undefined;
      }

      if (message) {
        reason.type = "breakpointConditionThrown";
        reason.message = message;
      }
    }

    if (logValue) {
      return logEvent({
        threadActor: this.threadActor,
        frame,
        level: "logPoint",
        expression: `[${logValue}]`,
      });
    }

    return this.threadActor._pauseAndRespond(frame, reason);
  }

  delete() {
    // Remove from the breakpoint store.
    this.threadActor.breakpointActorMap.deleteActor(this.location);
    // Remove the actual breakpoint from the associated scripts.
    this.removeScripts();
    this.destroy();
  }
}

exports.BreakpointActor = BreakpointActor;

91%


¤ Dauer der Verarbeitung: 0.20 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 ist noch experimentell.