Now that you have a single breakpoint at
Interp::dispatch(), if you click Restart
again and press Return in the Debugger Console window,
the program stops at the first line of the
dispatch()function that contains executable code.
Because you have identified the problem of the argv[0] being passed to find() use a watch on argv:
Select an instance of argv in the Editor window.
Right-click and choose New Watch. The New Watch dialog box appears seeded with the selected text:
Click OK.
To open the Watches window, choose Window → Watches (Alt + Shift 2).
In the Watches window, expand argv.
Note that argv is uninitialized and because it is a local variable, argv might “inherit” random values left on the stack from previous calls. Could this be the cause of problems?
Click Step Over (F8)
twice until the green PC arrow points to
int argc = 0;.
Because argc is going to be an index into argv, create a watch for argc also. Note that argc is also currently uninitialized and might contain unwanted values.
Because you created the watch for argc after the watch for argv, it appears second in the Watches window.
To alphabetize the watch names, click the Name column header to sort the column. Note the sort triangle in the following illustration.:
Click Step Over (F8)
.
argc now shows its initialized value of 0 and is displayed in bold to signify that the value just changed.
The application is going to call strtok().
Click Step Over to step over the function, and observe, for example, by using balloon evaluation, that token is NULL.
The strtok() function helps divide a string, for example, into tokens delimited by one of the DELIMITERS. For more information, see the strtok(3) man page.
Click Step Over again to assign the token to argv. Then there is a call to strtok() in a loop.
As you step over, you do not enter the loop (there are no more tokens) and instead a NULL is assigned.
Step over that assignment too, to reach the threshold of the call to find where the sample program crashed.
To double check that the program crashes at this point, step over the call to find().
The Signal Caught alert box is displayed again.
Click Discard and Pause as before.
The first call to find() after stopping in Interp::dispatch() is indeed where things go wrong.
You can quickly get back to where you originally called find().
Click Make Caller Current
.
Toggle a line breakpoint at the call site of find().
Open the Breakpoints window and disable the Interp::dispatch() function breakpoint.
dbxtool should look like the following illustration:
The downward arrow indicates that two breakpoints are set on line 141 and that one of them is disabled.
Click Restart
and press Return in the Debugger Console
window.
The program returns in front of the call to find(). Note that the Restart button evokes restarting. When debugging, you restart much more often than initially starting.)
Where is the bug? Look at the watches again:
Note that argv[0] is NULL because the first call to strtok() returns NULL because the line was empty and had no tokens.
Fix this bug before proceeding with the remainder of this tutorial, if you like.
If you will be running the program under the debugger, you can patch the code in the debugger, as described in Using Breakpoint Scripts to Patch Your Code.
The developer of the example code should probably have tested for this condition and bypassed the rest of Interp::dispatch().