Ok so I hope this is a question that isn't to basic for you guys.
I know enough jQuery to get myself into trouble, meaning I can grab elements and do stuff with it, write my own little functions for interactivity and such. But then something doesn't go as expected, before I post questions to stackoverflow and get answers that make me slap myself in the forehead I would like to debug it myself and am sick of inserting alert(); into my code. In reading up on the subject there is mention of console.log();, console.info(); and the such but I can not find any resource that explains how to use these in real world scenarios for debugging.
Do any of you know of a good resource or tutorial (not afraid to read a book) that can explain how to use these functions for the layman. It seems that the tutorials and such I am finding are either way to advanced or just skim the surface and don't show you how to use them. I understand I can insert console.log(); and it will spit out information in the console for firebug or element inspector. But what if my hand baked function is doing something unexpected somewhere up the line, how do I find the problem as the browser parses the javascript.
Any help would be greatly appreciated as I feel learning this will help me understand what is going on in my code, so I can stop staring at the screen going “Why isn't this working, it worked in the jsfiddle!”
console.log() just takes whatever you pass to it and writes it to a console's log window. If you pass in an array, you'll be able to inspect the array's contents. Pass in an object, you can examine the object's attributes/methods. pass in a string, it'll log the string. Basically it's "document.write" but can intelligently take apart its arguments and write them out elsewhere.
It's useful to outputting occasional debugging information, but not particularly useful if you have a massive amount of debugging output.
To watch as a script's executing, you'd use a debugger instead, which allows you step through the code line-by-line. console.log's used when you need to display what some variable's contents were for later inspection, but do not want to interrupt execution.
Learn to use a javascript debugger. Venkman (for Firefox) or the Web Inspector (part of Chome & Safari) are excellent tools for debugging what's going on.
You can set breakpoints and interrogate the state of the machine as you're interacting with your script; step through parts of your code to make sure everything is working as planned, etc.
Here is an excellent write up from WebMonkey on JavaScript Debugging for Beginners. It's a great place to start.
I like to add these functions in the head.
window.log=function(){if(this.console){console.log(Array.prototype.slice.call(arguments));}};
jQuery.fn.log=function (msg){console.log("%s: %o", msg,this);return this;};
Now log won't break IE
I can enable it or disable it in one place
I can log inline
$(".classname").log(); //show an array of all elements with classname class
Essentially console.log() allows you to output variables in your javascript debugger of choice instead of flashing an alert() every time you want to inspect something... additionally, for more complex objects it will give you a tree view to inspect the object further instead of having to convert elements to strings like an alert().
Breakpoints and especially conditional breakpoints are your friends.
Also you can write small assert like function which will check values and throw exceptions if needed in debug version of site (some variable is set to true or url has some parameter)
Related
I want to debug a website that is built from millions of lines of js code, and I want to find the function that will receive a specific value as one of the arguments. Is it possible to break the execution when any function receive a specific value as one of the arguments?
You could add a conditional breakpoint in
Chrome's debugger
Firefox' debugger
Alternatively, if the browser of your choice does not have similar functionality, you could invoke the debugger statement conditionally (if you can modify the code):
if(value === "wanted") debugger;
however that only works if you know the functions that might receive a specific parameter
Is it possible to break the execution when any function receive a specific value as one of the arguments?
No, that's close to impossible. Adding a breakpoint to "any function" will probably slow down execution a lot, if it's even possible. Doing so programmatically might work somehow, though it seems like a lot of work for little benefit. If you know the value, you probably also know the source and can debug from there.
Which tool is used to discover what JS/jQuery is consuming too many resources or in infinite loop?
More specifically I have an issue with this template: http://pages.revox.io/dashboard/latest/html/
Opening that page on Firefox 46.0.1 freezes the page after a few minutes. I'm unable to discover which JS/jQuery is causing this freeze with Firebug since it seems to be a script that is simply consuming too many resources and not in a plain freezing never ending loop (which would trigger the "Script XYZ is taking too long to execute" message)
Firefox 46.0 for Ubuntu appears to have a pretty good debugger built into it.
Using the system monitor it's easy to see your page requires a fair amount of memory.
It's fairly easy to produce a call graph in Firefox if you go to Tools->Web Developer->Performance and record your page for a little while.
Once you've stopped the recording, just select the data in the menu on the left and Call-Tree on the top of the debug frame.
It presents a breakdown of which functions use the most processor time.
Looks to me like whatever the Gecko function is, it is just really expensive.
Also, the console points out some interesting things:
mutating the [[Prototype]] of an object will cause your code to run very slowly; instead create the object with the correct initial [[Prototype]] value using Object.create d3.v3.js:3:157
Use of getPreventDefault() is deprecated. Use defaultPrevented instead. html
Empty string passed to getElementById().
Maybe addressing the issues pointed out by the console will help your freezing issue.
We have a mid-size web-app evenly written in MVC.NET/WebAPI and Backbone.Marionette. So, it's fair to say we spend sizable amounts of time at the Chrome and Firebug debug consoles.
Whenever a bug creeps into the code, and we just can't pinpoint exactly were it's coming from, it spawns a familiar nightmare.
Place your breakpoint at some reasonable point (like a function header that looks suspicious)
Refresh the page
Pray that none of the descendants of the function call any jQuery
If indeed we've been pulled into the hole, slowly Step Into and Step Out Of jQuery functions until my desired function is back in scope
Don't forget to breakpoint along the way so that if I Over Step a function that finally pulls me back in, I can start over from that point
Don't panic
This just seems to me like a major speed-bump. Do I really care how jQuery parses a selector? How it maps a function to my variable? Maybe, but in the default case, I certainly don't. I'm just trying to get my variable through the method chain to see what comes out the other end. If something breaks, I probably care about why it broke, but more likely, I'd rather read up on its usage and implement it correctly. I don't care enough to track it through reams of jQuery code.
Now, I understand this is the nature of the browser-loaded-interpretative-language beast that JavaScript is. I'm starting to wonder though, if we've reached a certain maturity level where we can assume that the average developer bug does not require deep inspection of the "standard" (jQuery, Require, REST, you name it) libraries the script was built upon to be resolved.
Or more, precisely, to ASK A QUESTION, is there a debugger that lets me smoothly chart the functionality of my code, with as many callbacks as my code may have, without tangling me into code from "standard" libraries (assuming I tell the debugger what these libraries are)? Is there something out there smart enough to automatically navigate, say, jQuery code, and inject the focus back into my function, if my code gets pulled into the jQuery maze?
And ( please don't post this as Answer ;), but does anyone out there share my frustration, or am I missing something fundamental?
I am trying to figure out any and all ways to prevent CSS modification and DOM modification of specific elements. I understand this might not be completely possible or that a talented developer could get around it, however, I am not so concerned about people potentially getting around it, I just want to stop newbies. In particular those using jQuery. An example would be to delete certain properties on prototype objects etc..
But why you need/want this? If you want to "protect" your code, you can use some JavaScript minifier as Google Closure Compiler or YUI compressor. They will rewrite your script and it will be difficult to read by a human. Nowadays, with tools like Firebug and Grease Monkey it's almost impossible to do what you want.
Don't use CSS or JavaScript :p Depend completely on server side checks etc.
You cannot stop anyone from messing with your javascript or your objects in the page. The way the browser is designed, your code and objects in your page are simply not protected. Everything from bookmarklets to javascript entered at a console to browser plug-ins can mess with your page and code and variables. That is the architecture of a browser.
What you can do is make things a little more difficult such that a little more work is required for some things. Here are a couple of things you could do:
Obfuscating/compressing/minimizing your code will do things like remove comments, remove whitespace, remove some linebreaks, shorten variable names, etc... That does not prevent anyone from modifying things, but does make it more work to understand and figure out.
Putting variables inside closures and not using globals. This makes it harder to directly modify variables from outside of your scripts.
Keep all important data and secrets on your server. Use ajax calls to ask the server to carry out operations using that data or secrets such that the important information is never available in the browser client.
You cannot keep anyone from modifying the DOM. There simply are no protections against that. Your code can check the DOM and refuse to operate if the DOM has been messed with in non-standard ways. But, of course, the code would then be modified to remove that check too.
If you are looking for a jquery specific solution a crude approach will involve altering the jQuery ($) function and replacing it with a custom one that delegates to the original function only if the provided selector does not match the element you want to secure.
(function(){
jQueryOrig = jQuery;
window.jQuery = window.$ = function(){
if (jQueryOrig("#secure").is(arguments[0])) {
throw new Error("Security breach");
} else return jQueryOrig.apply(this, arguments);
}
}());
Of course people using direct DOM manipulation would not be affected.
Also, if you are actually including arbitrary third party code in your production code, you should take a look at Caja ( http://code.google.com/p/google-caja/ ), which limits users to a subset of javascript capabilities. There is a good explanation regarding Caja here : http://due-diligence.typepad.com/blog/2008/04/web-20-investor.html .
This is possible but requires that the JS file to always be loaded from your server. Using observers you can lock CSS properties and using the on DOM remove/add listeners you can lock it to a parent. This will be enough to discourage most modification.
You can actually go a step further and modify core javascript functions making it nearly impossible to modify the DOM without loading the JS file locally or through a proxy. Further security can be added by doing additional domain checks to make sure the JS file is loaded from where it is supposed to be loaded from.
You can make everything in Flash. In Chrome, there's even a bug that prevents users from opening a console if the flash element has focus (not sure how exactly this works, but you can see an example at http://www.twist-cube.com or http://www.gotmilk.com). Even if users do manage to get a console open (which isn't that hard...), still about all you can do is change the shape of the element.
I have a website that suddenly started to crash internet explorer.
The website loads and starts executing javascript but somewhere in there the machinery explodes. I don't even get a script error, it just crashes. I've tried to manually step through every single line of js with the built in debugger but then of course the problem doesn't occur.
If i choose to debug the application when it crashes i see the following message.
Unhandled exception at 0x6c5dedf5 in iexplore.exe: 0xC0000005: Access violation reading location 0x00000090.
The top 5 items in the call stack looks like this
VGX.dll!6c5dedf5()
[Frames below may be incorrect and/or missing, no symbols loaded for VGX.dll]
VGX.dll!6c594d70()
VGX.dll!6c594f63()
VGX.dll!6c595350()
VGX.dll!6c58f5e3()
mshtml.dll!6f88dd17()
VGX.dll seems to be part of the vml renderer and i am in fact using VML. I'm not suprised because i've had so many problems with vml, attributes has to be set in specific order, sometimes you cant set attributes when you have elements attached to the dom or vice versa (everything undocumented btw) but then the problems can usually be reproduced when debugging but not now :(
The problem also occurs in no plugin-mode.
Is there a better approach than trial and error to solve this?
Edit:
Adding a console outputting every suspect modification to the DOM made the problem only occur sometimes. (the console is also implemented in javascript on the same page, i'm able to see the output even after a crash as the window is still visible) Apparently it seems to be some kind of race condition.
I managed to track it down even further, and it seems to occur when you remove an object from the DOM too quickly after it's just been added. (most likely only for vml-elements with some special attribute, didn't try further) And it can't be fixed by adding a dead loop in front of removeChild(pretty bad solution anyway), the page has to be rendered by the browser once after the addChild before you can call removeChild. sigh
(old question but important one)
I had a very similar problem - including lots of complex VML (from Raphael), and it looked near-impossible to debug.
Actually, it turned out the simplest low-tech approach was the best. It's an obvious approach: I'm writing here because sometimes when faced with an intimidating problem the obvious, simple solutions are the last a person thinks of.
So, simple old-school debugging: Lots of alert("1");, alert("2"); etc before and after every remotely demanding or complex call in my code, giving super-simple reliable breakpoints that don't rely on any features (e.g. developer tools) that might themselves crash out. Then, just see which number alert you get to before it crashes - the problem must arise between that alert and the next one.
Add more alerts until you narrow it down to the exact line. In my case, it was actually nothing to do with the complex VML - it was a for loop that, for some reason was continuing infinitely only on IE7.
Stop using VML?
If you need stuff in IE that really can't be done by moving, scaling, cropping and replacing images, then consider using Flash, Silverlight or similar.
If your life depend on VML then read as much as possible about other peoples experience, that may ease the trial and error approach.
Its a null pointer dereference non exploitable crash
Make sure that your scripts are running after the DOMReady event occurs. IE is notorious for crashing when modifying the DOM before it is fully loaded.
In some instances IE might prematurely fire the DOMReady event. See more information on how to overcome this here and here.
Are you using JSONP in any form? Popular implementations like jQuery tend to try and clean up memory by deleting the script node from the DOM after it has run. I've seen that crash Internet Explorer in many cases. Never could figure out what other conditions needed to be around to cause that to crash. Too much stuff going on in my other pages.
Anyhow, if you're using jQuery.getJSON, check the following line in jquery source:
(line 5556 on jquery 1.4.3):
} else {
// Garbage collect
window[ jsonp ] = undefined;
try {
delete window[ jsonp ];
} catch( jsonpError ) {}
}
if ( head ) {
head.removeChild( script );
}
You can safely remove that, or conditionalize it to only happen in non-IE browsers.
Hopefully that helps.