Is there any automatical way to trace execution in a javascript application (in browser) ?
My need is to know according to the use case :
which functions are called
which functions call which functions
In fact, it's a code coverage by instrumentation (like Istanbul) but for runtime.
------------------------- EDIT -------------------------
I want to generate a map of functions used during execution.
Example :
1 - for use case #1 :
functA1 -> [functB3, functC2 -> [functE5, functD8 ] ]
functA2 -> [functT2]
functA3
With this kind of execution map, i can understand how the appl works
and compare execution between two releases.
on chrome debugging is awesomely done:
ctrl + option + j
click on 'Sources'
and then go to "Event Listener Breakpoints" and choose the event that may call your function and after that where the function call is going just press the F10 on it will move to next statement to execute and so on.
Please refer the screenshot: https://iamlalit.tinytake.com/sf/MTY5MDc1N181NjM1ODA1
You can set breakpoints in the browser's sources tab. On chrome it's ctrl + option + j and click on 'Sources'. From there you set a breakpoint at the function you want and can trace what gets executed line by line.
Hope this helps.
Related
I have a windbg-issue concerning the execution
of a javascript-function as a breakpoint-command.
This observation was made in windbg Preview 10.0.17030.1002
and also in recent versions of windbg
when debugging a native x86 C++ program on Windows 10.
Test Setup
In my javascript-file dbg_test.js I have the following function:
function test()
{
var ctl = host.namespace.Debugger.Utility.Control;
host.diagnostics.debugLog(">>> Test\n");
ctl.ExecuteCommand("g");
}
In windbg, I load the javascript-provider, load my dbg_test.js script
and define a breakpoint-command to call this javascript-function:
bs 0 "dx #$scriptContents.test()"
Expected Behavior
The string ">>> Test" is shown in the output-pane of the command-window
everytime when breakpoint 0 is hit.
The debugger resumes execution.
Observed Behavior
The output ">>> Test" is shown only the first time
when breakpoint 0 is hit.
Subsequently hitting breakpoint 0 does not
produce any output.
Remarks
1) Doing the analogous test with "old style" windbg-commands works fine:
bs 0 ".printf \">>> Test\\n\\n\";g;"
but only after ending and restarting windbg
2) The same behavior is shown when I move the code of function "test" to the function "invokeScript()" and define the breakpoint-command via
bs 0 ".scriptrun d:\\dbg_scripts\\dbg_test.js"
3) Running the script from the windbg-command-line works.
4) Calling javascript-functions as in the test-scenario above worked in previous versions of windbg.
5) It seems that the statement
ctl.ExecuteCommand("g");
is the crucial one: If I comment out this statement, then the breakpoint
is hit every time and the output from
host.diagnostics.debugLog(">>> Test\n");
is shown on each hit of the breakpoint.
Of course, I have to resume the execution manually by pressing F5 or entering the command "g"
Questions
Can someone reproduce this issue ?
Is it legal to use javascript-functions in this way or am I doing something wrong here ?
Your feedback is greatly appreciated!
Kind/Best regards!
I ran into the same problem as you did. I was able to somewhat bypass the problem by declaring a script global variable
var lines = [];
and pushing log messages to this array rather than debug printing them:
lines.push(">>> Test");
In order to see the lines, I created a function
function print_lines() {
for (var line of lines) {
host.diagnostics.debugLog(line + "\n");
}
lines = [];
}
which I called from the prompt like so
dx #$scriptContents.print_lines();
I know that this is not really answering your question, but it might still be helpful for someone else that faces the same problem.
I have a jsp file with html content, and a script inside and I am also using dhtmlx. The other parts of my Web Application are working, so with this, I want only to focus on this problem because the environment works well. In one point of the file I have got:
numTabs = getNumTabs();
for (var i=0; i<numTabs;i++) {
var mytab = "tab_"+i;
tabbar.addTab(mytab,'Tab Numer: ' + i,'');
//alert("for " + i); PLACE 1
initTabContent(mytab);
}
function initTabContent(tabID){
//alert("initTabContent " + i); PLACE 2
tab = tabbar.cells(tabID);
toolbar = tab.attachToolbar();
toolbar.loadXML('.../...file.xml',function(){
//alert(i); PLACE 3
toolbar.setItemText('botton1', 'Botton 1');
});
grid = tab.attachGrid();
//more stuff
}
The point is:
If I uncomment the alert in PLACE 1, everything goes pretty well, it loads the XML and everything is working but if I comment the alert it doesn't go well.
If I uncomment alert 1 and alert 2, I will see in the web page:
I see: "for 0" -> OK
I see: "for 1" that changes almost immediately to "initTabContent 0" -> OK but I can see it
I see: "for 1" -> OK
I see: "for 2" that changes almost immediately to "initTabContent 1" -> OK
I see: "for 2" -> OK
I see: "for 3" that changes almost immediately to "initTabContent 2" -> OK
....and on
So, I understand that despite of myfunction the loop goes on and doesn't wait the complete termination of that function.
The funny part is that if I comment alert 1 and 2, and uncomment alert 3, the first thing I see on the web page is 4, then 3, 2, 1, 0...
And if I leave again, only alert 1 uncommented, everything goes ok. The reason about that I suppose is that the alert makes the system wait to the user and therefore the XML is well loaded.
My questions:
First: Why the loop is not waiting for the function to finish? It should be sequential right?
Second: How can I solve it without the alert? I also tried to put an empty for loop inside to make time but it didn't work out...(and that is not a good way to do it)
Thank you very much,
Alex.
Part of what is causing you trouble is that an 'alert' blocks execution, while the loadXML call is asynchronous.
To get a more accurate depiction of what is happening in what order, use console.log instead of alert.
Are you trying to use the value of i in your call myFunction for some purpose other than alerts ?
If that is the case. Try replacing:
myfunction(i);
With:
(function (num) { return function() {myfunction(num)} })(i);
Thanks to #KevinB I realized that indeed the toolbar declaration was missing in the whole jsp file.
The toolbar = tab.attachToolbar(); is overriden before the loading of the XML.
Now with **var** toolbar = tab.attachToolbar(); the problem is solved.
To see the reason that the loop doesn't behave properly, you can read the comments under the question.
I would like to be able to perform manipulations on a given JS app, and then simply get a large log of all the functions that have been called. This is possible in Chrome, but only if one puts a breakpoint somewhere. My problem is when I am reverse-engineering a given website (only for self-teaching purposes, of course) it often takes me a whole lot of time to figure out where to even start from. Something like that will help me tremendously because I will no longer have to search within the code, rather, I will just do a user action, and grab the stack log afterwards.
I suppose that there should be a way to intercept (or wrap) every function call, so that it is dumped to the log before the function is called.
Try this article:
http://eriwen.com/javascript/stacktrace-update/
or this post:
http://ivan-ghandhi.livejournal.com/942493.html
and, probably, this: How can I get a Javascript stack trace when I throw an exception?
In Firebug, you can use the profiler to log every function called. Use console.profile() and console.profileEnd() to trigger it programatically.
However, this will not give you proper stack traces. (Are you sure that's what you want?)
To log methods of specific objects, you can overwrite them like so:
for (var key in obj) {
if (typeof obj[key] == 'function') {
(function(){
var origFun = obj[key];
obj[key] = function () {
var result = origFun.apply(this, arguments);
console.log('call to method', key, 'with arguments', arguments,' - Result:', result);
// console.trace(); // for a trace with every call
return result;
};
})();
}
}
Maybe aspect oriented programming (AOP) can provide an answer. I just found out about aspectJS which could help intercept and log function calls
You can use dynatrace. Dynatrace is a profiling tool for IE and FF. Dynatrace can monitor your application while it is running, and then serves you a timeline of all what happened. In the timeline, there is blocks representing the javascript activity. You can right-click on it (purepath), and then walk through the whole call stack. You can export that to excel or other If you want.
You can add markers in your code, those markers will appear on the timeline and in the purepath:
if(typeof(_dt_addMark)!="undefined") _dt_addMark('MyCustomTimerName');
alternatively, if you only want to find "a way to intercept (or wrap) every function call",
there is a low-tech solution, if you are using a real webbapp (single-load javascript app):
bookmarklets
With bookmarklets, once you have loaded your page, you can execute some custom javascript. So what you can do there, is to override the functions methods that you want to observe with the same function containing logging (so just copy and paste the function, and add some console.log in there). This actually works even with native js functions.
I am trying to debug legacy scripts with Firebug. As per my knowledge (Which I got yesterday)
we use Step over (F10) to debug line by line and Step into (F11) to dig into JS function.
But when I use Step into on any JS function call, it takes control to next line. I want to see what is hidden inside the function. How can we do it ?
I kept break-point inside the function and then tried Step into then it takes control inside the function body. But it is tedious to find each function method and set break-point.
Is there any other way to do it ? or which is the right way ?
For example :
i2b2.ONT.ctrlr.FindBy = {
clickSearchName: function() {
// do some stuff
i2b2.ONT.ctrlr.FindBy.doNameSearch(search_info); // I tried Step into here
// some more stuff
}
doNameSearch: function(inSearchData) {
// If I set break-point here then only I can debug it
// or it directly takes control to `// some more stuff` in `clickSearchName:function`
}
}
PS: It also more external JS function calls.
Thanks,
Ajinkya.
"Step into" will step into the function if there is JS source for the function. If not (like for document.getElementById("foo"), it will step over it since it doesn't have anything that it understand to step into.
If you can point us to a working example where you are having the problem (either a jsFiddle reduction of the problem or a working web page) with instruction on where the relevant code is, we can probably help more.
Judging by your code example, I'm wondering what you're trying to step into. The line of code that starts with clickSearchName defines a function. It doesn't execute it. So, it won't go into that function until some later code actually calls clickSearchName. So, perhaps you're breaking on the definition of the function and trying to step into the function when it isn't being executed. That's just a guess though since we don't have a working example to try ourselves.
Add the line debugger; to your code at the place where you want to break into the debugger, it's a JavaScript keyword, which should do what you want. Just remember to take it out when you're done debugging your code.
I need this because I often work on existing projects, and I'm required to crash right into the middle of somebody else's work. With little time nowadays, I'm looking for whatever tool I can find to do this:
Load a JS application
Start / Pause recording activity
Show me exactly what happened, in the form of what functions were called without requiring me to change the source code.
For example:
<script language="javascript">
var fn1 = function(strvar){ alert('var='+strvar); fn2(strvar); }
var fn2 = function(strvar2){ alert('var='+strvar2); }
</script>
click here
After I click the anchor, (at best) should get something like this:
(click) event on a
(call) fn1("click here")
(call) fn2("click here") from inside fn1 called at pct. 2
Some sort of stack tracing but without having to alter the source because it takes formidable time as it is.
If you write
debugger;
in your innermost function, you can open firebug or the chrome dev tools and their debugger will pause when it hits that line. Then in the section on the right of the tools, you can see the stack trace and other relevant data (locals, etc...).
You only need to add one line to a function you own and it will show you any calls made with anyone's code.