Debugger showing wrong information with source maps - javascript

This has happened for the second time now and as you can imagine, a debugger that shows wrong information is the worst thing that can happen when debugging. What happens is that when using source maps that debugger thinks the VM is at a certain line, but actually it's not yet there, or worse, will never reach this line. The source maps are generated with the Grunt uglify plugin, which uses UglifyJS2.
An example:
if(something === 1){
console.log("it's something"); // debugger thinks the VM is here
else{
console.log("no it's not"); // while actually it's here
}
This did then print no it's not although the debugger jumped into the if
The other example I experienced was:
var that = this;
some.functionCall(1, function(){
console.log(that); //this is where the debugger thinks the vm is
// debugger: that = undefined
// console prints nothing to that point
});
When I continued the program the console.log(that) did fire eventually.
Did anyone else experience the same problem? Is it more likely a problem of UglifyJS2 or of Google Chrome?
Chrome Version: 38.0.2125.8 dev (64-bit)
Uglify2JS: 2.4.0
grunt-contrib-uglify: 0.5.1

I observe similar issue. The offset is equal exactly to number of comment lines.
EDIT The root cause occured to be lines prefixed with //>> which occured in 3rd party libraries. Every such a line makes 1 line offset. They seem to be some depreciated requirejs build pragmas.
For us the solution was to find&replace them in the code on the build time, as we do not use pragmas in our build system.
sed -i -e 's_//>>_// pragma was here: _g' `find . -type f -name "*.js"`

Related

ghost line does nothing even when viewing through the Node debugger?

I have the weirdest bug I have ever seen. I recently upgraded my config package and my Google strategy started failing.
I used the debugger to troubleshoot this error:
In the debugger I got to the line were the internal authorizationURL is supposed to be set:
I even set a watch on it ( it is a property on the options object )
Here is a closeup of the line that does nothing, I call it the ghost line:
I stepped through the code line by line and that particular line does nothing for some reason.
For a reality check I put it in a fiddle / replit:
https://repl.it/#johnmorsey/OpenQueasyHashmap
I have no idea how updating my config package has caused this internal error in Passport - Google Strategy.
In my mind the authorizationURL is clearly an internal property that is being set though "ghosting" in the debugger. But in reality my app is crashing b.c. of the error.

Is there a way to echo every line of JavaScript as it is executed?

I have two programs that should be running the same . They are not. I'd like to see where their execution diverges. Is there an option in Chrome or Firefox or Safari to log/echo every line of JavaScript as it is executed ? Or some other way to do this short of manually adding console.log every few lines? Note: the divergence is 10k or 20k maybe 100k lines deep and ideally I'd want it to print variables similar to the Chrome dev tools.
Then I can just dump the logs and find the divergence
Stepping through the code in the debugger is not a solution as it would take hours if not days to step that far.
One idea is to use a babel or uglify plugin to use the last to emit code for each line to print what it is about to do or just did.
Another idea is if there is a way to dump all of memory from js so I can compare all objects and all references. They should be the same so when I see two dumps that differ I'll have found my bug. note: JSON.stringify is not an option as I need to see all variables/objects/classes etc.
Note: I'm not looking for basic answers like "use console.log" or "step in the debugger". I appreciate the help and maybe I've overlooked something simple but I do have quite a bit of JavaScript experience.
Maybe an example would help. Imagine you got the source to an app as large as google docs. You run some processor over it that's not supposed to break anything or change anything. Except it does. You look at the changes and can't see anything wrong. All you know is when you run it it runs but a few things are subtly broken. So you put a breakpoint there and see the data is bad. But when did it go bad? You don't know the code (you just got it). It could have been 100s of thousands of lines before. You have no idea where to put breakpoints or console.logs. It could take weeks. But, given you know the code should run exactly the same if you could print all lines of execution you'd find the bug in minutes instead of days.
You can add debugger; at the begin of the function() or where you want and open the console.
When the debugger is reached it stop the execution. After that you can execute code step by step and add some watches.
It works fine with all recent browser.
Example :
function test()
{
var rand = Math.random();
debugger;
return rand;
}
test();
It is node js but it may be helpful for you. set the NODE_V8_COVERAGE environment variable to a directory, coverage data will be output to that directory when the program exits.
https://blog.npmjs.org/post/178487845610/rethinking-javascript-test-coverage

Getting more information from “SyntaxError: Parse error” message in PhantomJS/CasperJS

I have a long CasperJS script. When I run it I get:
phantomjs file.js
SyntaxError: Parse error
Is there a way to get some more information about the error.
At least a line number? or any hint at all?
Try run the file.js with node, so for your example:
node file.js
It's not possible to determine this in PhantomJS itself. The documentation on phantom.onError says:
This is the closest it gets to having a global error handler in PhantomJS
And this doesn't catch the syntax error. If you try to run it with the --debug=true option, you will see a lot of debug messages, but the final error has still the same amount of information.
Another thing that I tried was to use a second PhantomJS script which reads the original script and tries to eval it. The phantom.onError event is triggered in this case, but the trace argument is empty.
The good thing is that PhantomJS/CasperJS scripts are just JavaScript, so you can paste them to http://jslint.com/ or run a dedicated jslinter on them to see where the problem lies. There are some options that you have to mark on the site or otherwise you will get a lot of errors:
add phantom to the global variables box,
enable node.js mode and
tolerate "everything" (or those things that you actually want to tolerate)
I spent a whole 8hrs on this to find a trick for this problem. The trick is to run "phantomjs" and type 'require "path_to_js_file"'. I used 2.1.1 version of phantomjs. Likely 2.2 also works.
Then there will be a stack trace that shows which line is the offender. You won't see this in testem output.
In my case, if you define a property twice for an object, it will work for chrome, firefox etc, but not phantomjs. Lint might help but there are >5K lint errors for the project I work on and it is practically impossible to see what's wrong. Also the particular problem is likely hidden under the same bucket of "javascript strict mode violation". Nodejs didn't complain this either.

javascript server under XULRunner fails

I'm trying to debug a DOM scraping packaged called crowbar. Anyhow, when I run I get:
Error: [Exception... "Component returned failure code: 0xc1f30001 (NS_ERROR_NOT_INITIALIZED) [nsIServerSocket.asyncListen]" nsresult: "0xc1f30001 (NS_ERROR_NOT_INITIALIZED)" location: "JS frame :: chrome://crowbar/content/crowbar.js :: onLoad :: line 375" data: no]
Source File: chrome://crowbar/content/crowbar.js
Line: 375
Basically, asyncListen() is throwing NS_ERROR_NOT_INITIALIZED. This is weird because the line of code immediately before this is a call to init()! I've tried adding:
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
just before the call to asyncListen() and it had no effect. Is this a security issue? (btw, in case it matters, this is on a Fedora box, running as root, with selinux disabled)... I've also tried a few different port numbers...
Here's the source code: http://mxr.mozilla.org/mozilla-central/source/netwerk/base/src/nsServerSocket.cpp#369
Are you sure init() doesn't fail (that's what initializes mFD)? Maybe something closes it before your call?
I would build a debug XULRunner to build a debug version and/or try to get logging output from the app. Unfortunately, I can't figure out what the LOG() macro in that code resolves to, usually it's NSPR logging, but you have to guess the module name in order to enable logging for this module.
Boris Zbarsky (one mozilla core developers) says:
Since you're calling init(), the only other way I see to get an
NS_ERROR_NOT_INITIALIZED out of asyncListen is for the thread you're running on
to no longer be accepting events...
So something odd is happening. Are there in fact multiple threads involved?
I am too facing this problem. I have derived my code from CrowBar and running it through xulrunner 1.9.1 on Win 7.
I get the problem when I am diconnected from the net. If I am on a network it works. I do have multiple threads [multiple xul elements ]. But I belive I am running it on main thread (I am not sure how I can find current thread though), so thread not listening should not be the issue.
Also I have noted that in nsSocketTransportService2.cpp thread becomes null, so Boris maybe right.
NS_IMETHODIMP
nsSocketTransportService::Dispatch (nsIRunnable *event, PRUint32 flags)
{
LOG(("STS dispatch [%p]\n", event));
nsCOMPtr<nsIThread> thread = GetThreadSafely();
NS_ENSURE_TRUE(thread, NS_ERROR_NOT_INITIALIZED);
nsresult rv = thread->Dispatch(event, flags);
if (rv == NS_ERROR_UNEXPECTED) {
// Thread is no longer accepting events. We must have just shut it
// down on the main thread. Pretend we never saw it.
rv = NS_ERROR_NOT_INITIALIZED;
}
return rv;
}
Hope this helps pin down the problem.
thanks
harvinder

'Invalid Argument' Error in IE, in a line number that doesn't exist

I'm getting the following error in IE 6:
Line: 454
Char: 13
Error: Invalid Argument
Code: 0
URL: xxxxx/Iframe1.aspx
and I can't for the life of me find what's causing this.
This only happens in a situation where I have a main page that has several IFrames, and it only happens when I have one particular IFrame (the one pointed to by the URL in the error message), and that IFrame is invisible at the time of loading.
I've narrowed it up to there, but I still can't find anything more specific...
The IFrame in question doesn't have 454 lines in its HTML, nor do any of the JS files referred by it.
I tried attaching VS to iexplore.exe as a debugger, and it breaks when the error occurs, but then tells me "There is no source code available for the current location"...
Any suggestions on how I can go about chasing this one?
UPDATE: I found this problem through brute-force, basically, commenting everything out and uncommenting randomly...
But the question still stands: what is the rational way to find where the error is, when IE reports the wrong line number / file?
IE's Javascript engine is disgusting when it comes to debugging. You can try enabling script debugging in the Advanced Options, and then if you have Visual Studio installed it will jump to the place of error... if you're lucky. Other times you don't get anything, especially if the code was eval()'ed.
Another thing about these line numbers is that it doesn't reflect which file the error is happening in. I've had cases where the line number was actually correct, but it was in a linked .js file, not the main file.
Try using the Microsoft Script Debugger or DebugBar (http://www.debugbar.com) which may give you some better IE6 debugging tools. They always help me with IE6.
Also, does this happen in any newer versions of IE or just in IE6?
It's virtually impossible to debug this without a live example, but one thing that often causes an "Invalid Argument" error in Internet Explorer is trying to set an incorrect value for a style property.
So something like:
document.getElementById("foo").style.borderWidth = bar + "px";
when "bar" has the value null, or undefined, or is the string "grandma", will cause it, as "grandmapx" isn't a valid value for the borderWidth style property.
IE9 has a browser mode.
Open up Developer Tools, then select the version you want to emulate in the console, reload the page with errors, and the console will show you line numbers and the correct file where the error is.
I run into this problem a lot too, and I've also resorted to commenting everything out until I find the problem. One thing that I find to be useful is to add a try/catch block to every javascript method. Sometimes I add an alert to tell what method the error came from. Still tedious, but easier than trial and error commenting. And if you add them every time you write a new method it saves a lot of time in the event errors like those occur.
function TestMethod()
{
try
{
//whatever
}
catch (ex)
{
ShowError(ex.description);
//alert("TestMethod");
}
}
A note to other readers: I recently had this "Invalid argument." error reported in IE7-9 and eventually found that it was down to the way I was using setTimeout/setInterval.
This is wrong, in IE:
var Thing = {};
Thing.myFunc = function() { ... };
setTimeout(Thing.myFunc, 1000);
Instead, wrap the callback in an anonymous function like so:
var Thing = {};
Thing.myFunc = function() { ... };
setTimeout(function() { Thing.myFunc(); }, 1000);
and no more "invalid argument" errors.
Another possibility:
I do a lot of dev between two computers, at home and at work, so I often email myself or download pages from the server to work on. Recently I realised that Vista has a habit of unilaterally applying blocks to certain files when they are downloaded in certain ways, without notifying me that it is doing this.
The result is that, for example, an HTML page wants to access the .js file in its header, but it doesn't have permission to access local files. In this case, it doesn't matter what you write in the .js file, the browser will never even read it, and an irksome Line: 0 error will result.
So before you comb your code for an error, check your HTML page's properties, and see if it hasn't been blocked by the OS....
Like NickFitz pointed out, styling was an issue with my code.
document.getElementById('sums<%= event.id %>').style.border='1px solid #3b3b3b;'
I removed the border style and my IE issues were gone.

Categories

Resources