Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | const Cc = SpecialPowers.Cc; |
michael@0 | 2 | const Ci = SpecialPowers.Ci; |
michael@0 | 3 | const RETURN_CONTINUE = Ci.jsdIExecutionHook.RETURN_CONTINUE; |
michael@0 | 4 | const DebuggerService = Cc["@mozilla.org/js/jsd/debugger-service;1"]; |
michael@0 | 5 | |
michael@0 | 6 | var jsd = Cc['@mozilla.org/js/jsd/debugger-service;1'] |
michael@0 | 7 | .getService(Ci.jsdIDebuggerService); |
michael@0 | 8 | var jsdOnAtStart = false; |
michael@0 | 9 | |
michael@0 | 10 | function setupJSD(test) { |
michael@0 | 11 | netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); |
michael@0 | 12 | jsdOnAtStart = jsd.isOn; |
michael@0 | 13 | if (jsdOnAtStart) { |
michael@0 | 14 | runTest(); |
michael@0 | 15 | } else { |
michael@0 | 16 | jsd.asyncOn({ onDebuggerActivated: function() { runTest(); } }); |
michael@0 | 17 | } |
michael@0 | 18 | } |
michael@0 | 19 | |
michael@0 | 20 | // Ugly workaround: when you turn the debugger on, it will only see scripts |
michael@0 | 21 | // compiled after that point. And it may be turned on asynchronously. So |
michael@0 | 22 | // we put the debugged code into a separate script that gets loaded after |
michael@0 | 23 | // the debugger is on. |
michael@0 | 24 | function loadScript(url, element) { |
michael@0 | 25 | var script = document.createElement('script'); |
michael@0 | 26 | script.type = 'text/javascript'; |
michael@0 | 27 | script.src = url; |
michael@0 | 28 | script.defer = false; |
michael@0 | 29 | element.appendChild(script); |
michael@0 | 30 | } |
michael@0 | 31 | |
michael@0 | 32 | function findScriptByFunction(name) { |
michael@0 | 33 | var script; |
michael@0 | 34 | jsd.enumerateScripts({ enumerateScript: |
michael@0 | 35 | function(script_) { |
michael@0 | 36 | if (script_.functionName === name) { |
michael@0 | 37 | script = script_; |
michael@0 | 38 | } |
michael@0 | 39 | } |
michael@0 | 40 | }); |
michael@0 | 41 | |
michael@0 | 42 | if (typeof(script) === "undefined") { |
michael@0 | 43 | throw("Cannot find function named '" + name + "'"); |
michael@0 | 44 | } |
michael@0 | 45 | |
michael@0 | 46 | return script; |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | // Pass in a JSD script |
michael@0 | 50 | function breakOnAllLines(script) { |
michael@0 | 51 | // Map each line to a PC, and collect that set of PCs (removing |
michael@0 | 52 | // duplicates.) |
michael@0 | 53 | var pcs = {}; |
michael@0 | 54 | for (i = 0; i < script.lineExtent; i++) { |
michael@0 | 55 | var jsdLine = script.baseLineNumber + i; |
michael@0 | 56 | var pc = script.lineToPc(jsdLine, Ci.jsdIScript.PCMAP_SOURCETEXT); |
michael@0 | 57 | pcs[pc] = 1; |
michael@0 | 58 | } |
michael@0 | 59 | |
michael@0 | 60 | // Set a breakpoint on each of those PCs. |
michael@0 | 61 | for (pc in pcs) { |
michael@0 | 62 | try { |
michael@0 | 63 | script.setBreakpoint(pc); |
michael@0 | 64 | } catch(e) { |
michael@0 | 65 | alert("Error setting breakpoint: " + e); |
michael@0 | 66 | } |
michael@0 | 67 | } |
michael@0 | 68 | } |
michael@0 | 69 | |
michael@0 | 70 | // Set a breakpoint on a script, where lineno is relative to the beginning |
michael@0 | 71 | // of the script (NOT the absolute line number within the file). |
michael@0 | 72 | function breakOnLine(script, lineno) { |
michael@0 | 73 | breakOnAbsoluteLine(script, script.baseLineNumber + lineno); |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | function breakOnAbsoluteLine(script, lineno) { |
michael@0 | 77 | var pc = script.lineToPc(lineno, Ci.jsdIScript.PCMAP_SOURCETEXT); |
michael@0 | 78 | script.setBreakpoint(pc); |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | function loadPage(page) { |
michael@0 | 82 | var url; |
michael@0 | 83 | if (page.match(/^\w+:/)) { |
michael@0 | 84 | // Full URI, so just use it |
michael@0 | 85 | url = page; |
michael@0 | 86 | } else { |
michael@0 | 87 | // Treat as relative to previous page |
michael@0 | 88 | url = document.location.href.replace(/\/[^\/]*$/, "/" + page); |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | dump("Switching to URL " + url + "\n"); |
michael@0 | 92 | |
michael@0 | 93 | gURLBar.value = url; |
michael@0 | 94 | gURLBar.handleCommand(); |
michael@0 | 95 | } |
michael@0 | 96 | |
michael@0 | 97 | function breakpointObserver(lines, interesting, callback) { |
michael@0 | 98 | jsd.breakpointHook = { onExecute: function(frame, type, rv) { |
michael@0 | 99 | breakpoints_hit.push(frame.line); |
michael@0 | 100 | if (frame.line in interesting) { |
michael@0 | 101 | return callback(frame, type, breakpoints_hit); |
michael@0 | 102 | } else { |
michael@0 | 103 | return RETURN_CONTINUE; |
michael@0 | 104 | } |
michael@0 | 105 | } }; |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | function dumpStack(frame, msg) { |
michael@0 | 109 | dump(msg + ":\n"); |
michael@0 | 110 | while(frame) { |
michael@0 | 111 | var callee = frame.callee; |
michael@0 | 112 | if (callee !== null) |
michael@0 | 113 | callee = callee.jsClassName; |
michael@0 | 114 | dump(" " + frame.script.fileName + ":" + frame.line + " func=" + frame.script.functionName + " ffunc=" + frame.functionName + " callee=" + callee + " pc=" + frame.pc + "\n"); |
michael@0 | 115 | frame = frame.callingFrame; |
michael@0 | 116 | } |
michael@0 | 117 | } |