This reading has some information and links to videos showing how to use the Chrome Debugger. Other debuggers work very similarly.
Concepts¶
The debugger does a few things for us. It allows us to
- look at the values of local variables and function arguments
- step line-by-line through the code
- follow a function call into the called function, stepping through that line-by-line
- skip function calls where we aren't interested in the function being called, while continuing to step through the code
- see the sequence of function calls that got us to a particular place (the call stack)
- execute code in a run-time context with the current local variables and arguments
If we have a lot of code (like with coffeerun), we usually don't want to step through all of it, starting at the beginning. Besides, with event-handling code, there often isn't a single beginning: any event handler could be a "beginning".
So, to tell the debugger that we want to stop at a particular line, we set a breakpoint at that line. Then we run our code as usual. When the browser gets to the breakpoint, it will pause the execution there. We can then:
- look at values
- start stepping
- continue to the "next" breakpoint
We can set as many breakpoints as we want.
Enough preamble. Let's dive in and see a few examples, before we get to the example from Chapter 8
Ordinary Code¶
Try using the debugger on this example Here's the code that we'll be stepping through:
function foo(a,b) {
let x = a+b;
let y = a-b;
return bar(x,y);
}
function bar(c,d) {
let m = Math.sqrt(c);
let n = Math.pow(d,3);
return baz(m,n);
}
function baz(e,f) {
let p = e+f;
let q = e-f;
return p*q;
}
function start() {
console.log(foo(1,3));
}
I'll set a breakpoint at the "deepest" part of this code, and we can examine all the values up and down the stack.
Then I'll clear that breakpoint and set another at the beginning of the code, and demonstrate stepping through the code.
There is a video showing this on the videos page.
OOP Code¶
Object-oriented code isn't really much different, except that when we
examine values, we can also examine values in the object, via the
local "variable" this
.
I'll use the debugger on this OOP example Here's the code that we'll be stepping through:
// this is our OOP bank account code
class Account {
constructor (init) {
this.balance = init;
}
deposit (amount) {
this.balance += amount;
}
withdrawal (amount) {
if( this.balance >= amount ) {
this.balance -= amount;
} else {
throw new Error("Insufficient funds");
}
}
}
var harry = new Account(1000);
var ron = new Account(2);
var hermione = new Account(200);
I'll set a breakpoint in one of the methods and invoke the method.
This is shown in the video mentioned above on the videos page.
Chapter 8¶
We can replicate the bug with the function bugSetup
that I implemented
for us, to avoid a bit of typing. We'll look at the definition first:
function bugSetup() {
var truck = new App.Truck('bug',new App.DataStore());
truck.createOrder({ emailAddress: 'm@bond.com',
coffee: 'earl grey'});
truck.createOrder({ emailAddress: 'dr@no.com',
coffee: 'decaf'});
truck.createOrder({ emailAddress: 'me@goldfinger.com',
coffee: 'double mocha'});
return truck;
}
This code just creates a truck and creates some orders so that there is something to print.
Using the Chrome Debugger¶
To trigger the bug, visit one of these. Both open in a new tab.
- coffeerun with modules and bug. This is my re-write of coffeerun, using ES6 classes and modules.
- coffeerun app with the bug. This is the original coffeerun, implemented in ES5
In both, I've put the bugSetup code so that you can easily re-create the bug.
Then, we will try the following method invocations:
var b = bugSetup();
b.printOrders_buggy();
b.printOrders_closure();
b.printOrders_bind();
b.printOrders();
There's a video of using the Chrome debugger on our videos page.
Debugging Steps:
- Set a breakpoint at the line of the error
- show that
esc
opens/closes the drawer - run
myTruck.printOrders_buggy()
again - try pieces of the code, like
id
,this.db.get(id)
and so forth in the console - click up/down the call stack and try them again
- resume execution
- remove the breakpoint
- re-run the code to make sure the breakpoints are gone
Chrome seems to remember the breakpoints forever. I've had Chrome jump into the debugger when I'd set the breakpoint the previous semester. It's pretty easy to remove the breakpoints and resume the code, but it can be confusing to end up in the debugger when you didn't expect to.