mozilla
Your Search Results

    JavaScript Debugger Service

    Obsolete since Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30)
    This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.

    In Firefox versions prior to Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30), the JavaScript Debugger Service (or simply JSD) used to be an XPCOM component that allows the tracking of JavaScript while it was being executed in the browser. However, JSD has been removed in favor of the Debugger API. See the tracking bug bug 800200 for more details.

    Snippets

    Acquiring the service

    We acquire the service by calling the XPCOM object.

    var jsd = Components.classes["@mozilla.org/js/jsd/debugger-service;1"]
              .getService(Components.interfaces.jsdIDebuggerService);
    
     jsd.on(); // enables the service till firefox 3.6, for 4.x use asyncOn
     if (jsd.isOn) jsd.off(); // disables the service
    

    Hooks

    JSD operates using the events hook mechanism. Next, we add code to the various hooks.

    jsd.scriptHook = {
    	onScriptCreated: function(script) {
    		// your function here
    	},
    	onScriptDestroyed: function(script) {
    		// your function here
    	}
    };
    jsd.errorHook = {
    	onError: function(message, fileName, lineNo, colNo, flags, errnum, exc) {
    		// your function here
    	}
    };
    		
    // triggered when jsd.errorHook[onError] returns false 
    jsd.debugHook = {
    	onExecute: function(frame, type, rv) {
    		 // your function here
    	}
    };
    
    jsd.enumerateScripts({
    	// the enumerateScript method will be called once for every script JSD knows about
    	enumerateScript: function(script) {
    		// your function here
    	}
    });
    

    A simple stack trace

    Here, we will show how to implement a simple JavaScript stack trace using the JSD. Note that onError is called for every exception.

    jsd.errorHook = {
    	onError: function(message, fileName, lineNo, colNo, flags, errnum, exc) {
    		dump(message + "@" + fileName + "@" + lineNo + "@" + colNo + "@" + errnum + "\n");
    				
    		// check message type
    		var jsdIErrorHook = Components.interfaces.jsdIErrorHook;
    		var messageType;		
    		if (flags & jsdIErrorHook.REPORT_ERROR)
    			messageType = "Error";
    		if (flags & jsdIErrorHook.REPORT_WARNING)
    			messageType = "Warning";
    		if (flags & jsdIErrorHook.REPORT_EXCEPTION)
    			messageType = "Uncaught-Exception";
    		if (flags & jsdIErrorHook.REPORT_STRICT)
    			messageType += "-Strict";
    
    		dump(messageType + "\n");
    
    		return false;	// trigger debugHook
    		// return true; if you do not wish to trigger debugHook
    	}
    };
    		
    // note that debugHook does not _always_ trigger when jsd.errorHook[onError] returns false 
    // it is not well-known why debugHook sometimes fails to trigger 
    jsd.debugHook = {
    	onExecute: function(frame, type, rv) {
    		stackTrace = "";
    		for (var f = frame; f; f = f.callingFrame) {
    			stackTrace += f.script.fileName + "@" + f.line + "@" + f.functionName + "\n";
    		}
    		dump(stackTrace);
    
    		return Components.interfaces.jsdIExecutionHook.RETURN_CONTINUE;
    	}
    };
    

    Filters

    JSD also allows the use of filters to track which scripts should trigger the hooks. Note that the jsdIFilter only applies to jsdIExecutionHooks, which are breakpointHook, debugHook, debuggerHook, interruptHook and throwHook.

    Note that Filters are matched in a first in, first compared fashion. The first filter to match determines whether or not the hook is called.

    We create a generic createFilter function that acts as a jsdIFilter factory.

    function createFilter(pattern, pass) {
    	var jsdIFilter = Components.interfaces.jsdIFilter;
    	
    	var filter = {
    		globalObject: null,
    		flags: pass ? (jsdIFilter.FLAG_ENABLED | jsdIFilter.FLAG_PASS) : jsdIFilter.FLAG_ENABLED,
    		urlPattern: pattern,
    		startLine: 0,
    		endLine: 0
    	};
    	return filter;
    },
    

    We then add the filters we want.

    jsd.clearFilters(); // clear the list of filters
    
    // we exclude the scripts with the following filenames from being tracked
    jsd.appendFilter(createFilter("*/firefox/components/*"));
    jsd.appendFilter(createFilter("*/firefox/modules/*"));
    jsd.appendFilter(createFilter("XStringBundle"));
    jsd.appendFilter(createFilter("chrome://*"));
    jsd.appendFilter(createFilter("x-jsd:ppbuffer*"));
    jsd.appendFilter(createFilter("XPCSafeJSObjectWrapper.cpp"));
    jsd.appendFilter(createFilter("file://*"));
    

    Note that appendFilter adds the filter to the end of the list. You can use insertFilter (jsdIFilter filter, jsdIFilter after) to insert the filter after a particular filter; you can pass null for jsdIFilter after to insert at the head of the list. You can also use swapFilters (jsdIFilter filter_a, jsdIFilter filter_b) to swap filters, and removeFilter(jsdIFilter filter) to remove a filter.

    Learning more

    Document Tags and Contributors

    Tags: 
    Contributors to this page: wbamberg, apurba, fscholz, Mh512
    Last updated by: fscholz,
    Hide Sidebar