Debugging Commands


Useful debugging statements, such as trace, debug, breakpoint, cond_debug and cond_breakpoint, can help you detect and isolate errors in your program logic.

First, consider the error message:

    ===================================================

    Violated assertion at:

    File: /class/sce/rcpp/Resolve_Foundation/Integer/Integer.cpp
    Line #: 104
    Operation: Mod

    Violated assertion is:
    Integer modulus > 0
     ===================================================
This is a violated assertion message, which means that somewhere your program has invoked some operation whose contract involves a precondition that must be satisfied before it can be invoked, and that this precondition was not satisfied at the time your program invoked the operation. The message here indicates that the violation occured in the precondition for an operation called "Mod", and that the violated assertion -- i.e., the condition which should have been true before invoking the operation, but which was not true -- is "Integer modulus > 0". Now examine the program. The only arithmetic operation apparently performed in the program is the "mod" operation (the mod operator, which in Resolve/C++ is known internally as "Mod", hence the source of the error message) in the body of the Greatest_Common_Divisor function.

Certainly you intended and expected that the "Integer modulus" (i.e., j) should have been greater than zero, but apparently it was not. Perhaps the value of j was corrupted somehow, and this is why the error occured. Kill the *shell* buffer, using the "Delete Buffer *shell*" command under the File menu, to return to the source code buffer.

You are going to add a debugging statement right at the beginning of the Greatest_Common_Divisor function (before the if-statement) to make sure the values of j and k are correct.

The information before the violated assertion message is called a stack trace. It tells you the series of calls that led to the call where there was a violated assertion. In this case, the main program called Greatest_Common_Divisor, which then called operator% (which is the C++ name for the modulus operator), which then called Mod, which is where the error occurred. There is a lot of extraneous information here, but sometimes this will help you by telling you what calls were pending -- i.e., had been made but had not yet returned -- a the time of the violated assertion.
 
  • As shown in the following picture, add this statement right before the if-statement that checks whether j is 0:

  • debug ("Before the if statement. j = " << j << ", k = " << k);


  • Now build the program again and run it once more. 
  • Enter 5 and 10 as the values of the two numbers again.
  • The following statement is printed before the violated assertion occurs:

        Euclid.cpp (68): Greatest_Common_Divisor
        Before the if statement. j = 5, k = 10
    This output is produced by the debug statement you just put into Euclid.cpp. Note that the values of j and k are correct, i.e., what you should expect.

    The most common type of violated assertion when doing arithmetic is division by zero. Here k is being divided by j (as part of the mod operation) in the recursive call to the Greatest_Common_Divisor function. How could the value of j have become zero? This must have occured after the debug statement was executed the first time, but before the recursive call and before the debug statement could be executed again. Again, please curb your urge to go ahead and fix the problem. Instead plow ahead and learn more about the Resolve/C++ debugging commands.

    It is useful to place a conditional breakpoint that stops the program execution before the recursive call only if the value of j is zero.
     
  • Add this line right before the recursive call inside of the Greatest_Common_Divisor body:

  • cond_breakpoint ((j == 0), "Before recursive call. k = " << k);

    The parentheses around "j == 0" are not necessary, but some people find them helpful to visually separate the condition under which the program will pause from the message it will emit when it does pause. In any case, your program should now look like the picture below. This added line should print the value of k when j has become zero. 

  • Now build and run the program again. 

  • Enter 5 and 10 as the two numbers. 
  • Note that the following is printed:

        Please input an integer: 5
        Please input another integer: 10
    
        Euclid.cpp (66): Greatest_Common_Divisor
        Before the if statement. j = 5, k = 10
    
        Euclid.cpp (74): Greatest_Common_Divisor
        Before recursive call. k = 10
    
        Exit [x] or continue [default]?
    Thus j did become zero before the recursive call. Press Enter to continue. The violated assertion is reported again.

    What caused j to become zero after the debug statement, but before the conditional breakpoint? Obviously, the assignment sets j to 0 in the previous line! This statement should now be removed. What knuckleheads put that there, anyway?
     
  • Remove the line which contains j = 0; 
  • Rebuild the project. 
  • The program should now produce the following output:

        Please input an integer: 5
        Please input another integer: 10
    
        Euclid.cpp (66): Greatest_Common_Divisor
        Before the if statement.  j = 5, k = 10
    
        Euclid.cpp (66): Greatest_Common_Divisor
        Before the if statement.  j = 0, k = 5
            
        GCD = 5
        
        Process shell finished
    Notice that GCD = 5 which is the correct value of the greatest common divisor of 5 and 10. Also note that the program execution did not stop at the breakpoint this time because the condition associated with the breakpoint was never satisfied.

    We have only illustrated the debug and cond_breakpoint debugging statements here.  Information about trace, breakpoint, and cond_debug can be found on the Resolve/C++ FAQ (Frequently Asked Questions) page in the answer to the general concepts question: "What debugging support is available?".

    Because your program seems to be running correctly, you may now delete your conditional breakpoint and debugging statements from your program file.



     
    Previous Table of Contents Continue


    Last modified: Fri Dec 15 16:39:20 EST 2006