Previous 1 2 3 4 5 6 Next

Venkman offers windows, up into the internals of the SpiderMonkey JavaScript engine. Besides merely offering up this information, it allows great customizations of these windows. This page will try to showcase these windows, and how they may be used.

The Local Variables list

So far, we've only been looking at the Interactive Session, and the source code view, it's now time to look at what other kinds of information Venkman offers up. The "Local Variables" is a handy, at a glance panel, that offers up information about what kinda variables are available locally, plus various properties about these variables.

First, navigate Mozilla to the next file, venkman_example_4.html.

Second, in the Local Variables list, let's configure it, so it shows all properties. This is done by click the little icon in the upper right corner of the panel.

Venkman Local Variables panel
Figure 30. Making the Local Variables panel display more properties. Here the panel has been made free floating.

Simply check them all. Since currently, no code is running through the debugger, nothing is shown. Pause the debugger (Stop button), and reload the page, and the panel should look something like in the following figure.

Venkman Local Variables panel
Figure 31. Local Variables panel showing all the variables that exists in the "local" scope.

If you collapse the scope list, you'll note that there are two top elements, "scope" and "this". All the variables you can find under "scope", represent variables you can fetch under the current scope (duh). Variables under "this", are all properties that are attached to the current this reference.

At first the list might look mad, but remember, that the list is merely showing all the properties of the Window object, which is both the current this object, and the current scope. Scroll through the list, and you might recognize familiar entries such as document, location and so on.

What's interesting right now, isn't all these properties though. As you can see in the sourceview, our script looks something like this:

var a;
function testObj(a,b) {
    this.a = a;
    this.b = b;
}
a = 1;
var b = new Array(1,"a");
var c = 1.1;
var d = String.fromCharCode;
var e = new testObj(a,b);
document.write(e.b[1]);

Try stepping into the first line of JavaScript, and you should promptly note how the local variables list now also contains the variables declared in the script:

Venkman Local Variables panel
Figure 32. All the relevant variables highlighted in the Local Variables list.

Now, you might be wondering why they're ALL there, after all, you've only come to the first line, where only a is declared. But this merely a JavaScript trait, a variable declared anywhere in a function, is declared everywhere, but it's value remains "void" (or in more conventional JavaScript lingo, "unassigned", until it's assigned a value. The following snippet (from David Flanagan's JavaScript, The Definitive Guide, 4th Ed), should show that clearly:

var scope = "global";
function f() {
    alert(scope);       // Displays "undefined", not "global"
    var scope = "local";// Variable declared here, but defined everywhere
    alert(scope);       // Displays "local"
}
f();

Now that you know why ALL the variables show up, step through the first few lines of the script. You'll note that a changes from void to a value of 1.

Venkman Local Variables panel
Figure 33. a is assigned a value of 1, of type integer.

Step through the code a little bit more (just one time), until b is declared. You'll note that like a, it is assigned a value, but it changes into a little expandable point also:

Venkman Local Variables panel
Figure 34. b is assigned as an array. Note the implicit property, length

You'll note, that other then the obvious array content properties, b also contains the property length, which all arrays contain.

Step a few more times, into the function constructor testObj, and you'll notice that scope and this is suddenly emptied of most of their content.

Venkman Local Variables panel and Source code panel
Figure 35. Here, one can see how scope actually does change, depending on the context.

As you've entered into a function, you're on the first line. Here, you can see the scope, as containing the variable a and b, that were both passed. Further, you'll notice that the this keyword is empty. This is because this, in this context doesn't refer to the window, but instead to the current object (the object the function testObj is creating right now).

Try right clicking on a property, and select "Change value". You can then enter a new value. Try changing b's second value, from "a" to whatever you want:

Entering a new value
Figure 36. When entering a new value, make sure it's also valid JavaScript. Thus, if entering a string, use " or '. You can further reference other JavaScript variables or objects.

Stepping further, onto the end of the script, you should that Mozilla wrote whatever you entered into the prompt, to the page.

You'll note, that the various elements on the Local Variables list has different icons, and also, that each has a so called "Flag" field, that says funny things. Each icon, indicates what kinda value is stored in the variable, and the flags indicate different properties about the variable, such as how it was declared and so forth.

Flags

flag meaning
e Enumerable property
r Read only property (stuff declared using const )
p permanent property (cannot be deleted)
A Alias to another property (this property seems to be deprecated, so you won't see it)
a Argument to a function
v Declared with var
h Hinted, though I don't know what it means

Datatype icons

Icon Datatype
Void Void (undefined)
Bool Boolean
Integer Integer
Object Object
Null Null
String String
Double Double
Function Function

The Watches list

A panel similar to the Local Variables panel is the Watches panel, you can usually find behind the "Local Variables" panel. Here, you can enter various variables, and as you step through your code, it will update to reflect the value of that variable/property as it changes through the code. So in a way, it acts like the Local Variables panel, just without all the stuff you don't want to see.

You simply start by adding something to watch. For this demonstration, I've written venkman_example_watches.html, and I know it contains two variables, a and b, further, let's also add the more generic this and document, just to show it isn't just your own variables you can add.

Imagine, that whatever you put inside of Watches, gets eval'ed. So if you have a function, where there exists a variable x, going eval("x"), will return x's value. If it doesn't exist, an error will happen (though when generated by the Watches list, these errors don't cause any harm, so don't worry about that.)

Adding an expression to watch
Figure 37. Add an expression to the Watches list

Here, just add them without quotes or anything. After adding a, b, this and document, your list should look something like figure 38.

Watches list
Figure 38. Having added all the desired watches to the list, it should look something like this.

Note, that here you can also customize what columns you want to see, just like in the Local Variables panel. You might want to add the various columns, so you get as much info as possible. And don't worry about the value being "<no-available>". It's simply because the debugger isn't running. Put Venkman into paused mode, by clicking the stop button, and then go back to Mozilla, and reload the page, Venkman should come up instantly, and the Watches list should also change to reflect this. Try and do a single step into the script block.

Watches list
Figure 39. a and b have not yet been assigned, so they are merely void.

As we've seen before, this follows what we'd expect. this and document of course are valid references, and you can even expand them, and get everything there is to get in there. If you step a few times, down to line 12, the watches list should look like this:

Watches list
Figure 40. a and b have now been assigned a value.

Do a single step into the function foo. You'll notice that a and b swapped values, and if you look at the source, you'll see why. As I pass the variables, I pass them (a,b), but when I receive them in the function, I receive them (b,a), effectively switching them. This is just to illustrate, that the same variable name can have many values, depending on where you poll it.

Watches list
Figure 41. a and b are now reversed, compared to figure 40, simply because in the function call/definition, I "switched" them around.

That's basically all there is to using the Watches list. It's mostly handy for just keeping an eye on one variable, and see if it changes in a way you did not expect (such as global variables messing with each other.)

Various questions about the Watches list can be found in the Venkman FAQ. One of the interesting is, that if you expression appears in dark gray and bold font, it's because the value of the property/variable you're inspecting comes from the current objects prototype, and not from the object itself.

The Call Stack

The Call Stack panel, allows you to view the current call stack. The stack is the row of currently active functions. To see this effect, move to the next file venkman_example_5.html.

Do the usual, pausing Venkman, and reload Mozilla. The code is simple, it's pretty much just three functions, that call each other, one at a time. The script is rather contrived, but it's designed to show the idea behind the Call Stack. Start with stepping into the script block.

The Venkman Call stack
Figure 42. Venkman's call stack shows the stack of currently active functions.

The stack only shows __toplevel__, which is an internal JavaScript word for the top level of the script. Skip past the function declarations, down to the actual executing line document.write(f3(0));. Here, press "Step into", once, and you'll notice a another item being added to the stack.

The Venkman Call stack
Figure 43. The Call stack always puts the most recent function call at the top. Here, the function f3, is the currently active one.

Step a few more times, until the top function in the stack is f1.

The Venkman Call stack
Figure 44. Showing a full stack of function calls. The lower ones, waiting for the upper ones to return.

Now try to click one of the lower function names. You'll notice not only the source code panel switching to that function, but also the local variables panel changes to show variables in that function. Further, input entered into the interactive session is evaluated relative to that function/scope.

Try clicking on f3, the Local Variables should look something like this:

The Venkman Local Variables panel
Figure 45. Using the Call Stack to jump back in a call chain, and change a variable.

Right click on d, and change it's value from 1 to 2. Changing c has no effect, as it has already been passed to the function f2. But since d is yet to be subtracted, changing it will affect the scripts outcome.

After changing it, and pressing "Step into", you'll notice the Source Code skipping up to the function f2, and the top call to f1 is removed from the call stack. This is because using the call stack doesn't actually change where you are in the program, it merely let's you view the various parts of the chain that brought you to the top call. And if it's relevant, you may also change variables.

Pressing further "Step into", until the document.write call, you'll see that the script wrote "2". Had you not interrupted, using the call stack, it would have written "3". Of course, using the call stack to change d, or simply changing d, when you first came to it (by stepping), would have made no difference. Using the Call stack simply allows you to jump back and forth, in the execution chain.

This is all well, but you've not actually learned something that can be directed used for debugging, only in aiding of it. The next section is all about breakpoints, a major topic in debugging.

Previous 1 2 3 4 5 6 Next