Oracle® Solaris Studio 12.4: dbxtool Tutorial

Exit Print View

Updated: October 2014
 
 

Using Watches and Stepping

Now that you have a single breakpoint at Interp::dispatch(), if you click Restart image:Restart button again and press Return in the Debugger Console window, the program stops at the first line of the dispatch()function that contains executable code.

image:Editor window with execution stopped at line 122

    Because you have identified the problem of the argv[0] being passed to find() use a watch on argv:

  1. Select an instance of argv in the Editor window.

  2. Right-click and choose New Watch. The New Watch dialog box appears seeded with the selected text:

    image:New Watch dialog box
  3. Click OK.

  4. To open the Watches window, choose Window → Watches (Alt + Shift 2).

  5. In the Watches window, expand argv.

    image:Watches window with argv expanded

    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?

  6. Click Step Over (F8) image:Step Over button twice until the green PC arrow points to int argc = 0;.

  7. 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.

  8. To alphabetize the watch names, click the Name column header to sort the column. Note the sort triangle in the following illustration.:

    image:Watches window with sorted watches
  9. Click Step Over (F8) image:Step Over button .

    argc now shows its initialized value of 0 and is displayed in bold to signify that the value just changed.

    image:Watches window with argc value in bold

    The application is going to call strtok().

  10. 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.

  11. 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.

  12. Step over that assignment too, to reach the threshold of the call to find where the sample program crashed.

  13. To double check that the program crashes at this point, step over the call to find().

    The Signal Caught alert box is displayed again.

    image:Signal Caught alert box
  14. 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().

    1. Click Make Caller Current image:Make Caller Current button .

    2. Toggle a line breakpoint at the call site of find().

    3. Open the Breakpoints window and disable the Interp::dispatch() function breakpoint.

      dbxtool should look like the following illustration:

      image:Editor window showing two breakpoints                                                   with one disabled
    4. The downward arrow indicates that two breakpoints are set on line 141 and that one of them is disabled.

  15. Click Restart image:Run button 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.)


    Tip  -  If you rebuild your program, for example after discovering and fixing bugs, you need not exit dbxtool and restart it. When you click the Restart button, dbx detects that the program (or any of its constituents) has been recompiled, and reloads it. Therefore, consider keeping dbxtool on your desktop, perhaps minimized, and ready to use on your debugging problems.
  16. Where is the bug? Look at the watches again:

    image:Watches window

    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().