Debug Methods

Home • Gallery • Tutorials • Download • Purchase • Site Map
 

Debug Methods Support

Software development can be fun and rewarding. However, when things go wrong, it can be quite frustrating, to say the least. To compound the problem, you have access to none of the features available in most software development environments like the ability to set breakpoints, step through your code, examine variables, etc. Unfortunately, the primary mechanism to debug your program is the print statement! 

The Fractal Science Kit fractal generator print statements come in several flavors:

void Debug.Alert(<FormatString> [, <Arg>, ...])
void Debug.Error(<FormatString> [, <Arg>, ...])
void Debug.Print(<FormatString> [, <Arg>, ...])
void Debug.PrintString(<FormatString> [, <Arg>, ...])
void Debug.PrintSymbols(<SymbolList>)
void Debug.PrintArray(<Array>)
void Debug.PrintEnum(<EnumType>, <EnumValue>)
void Debug.PrintProxy(<FunctionProxy>)

Each of these methods prints to the Error/Debug Window. Debug.Print takes a format string and a set of arguments, it then formats the arguments using the given format information, and prints the resulting string. The format string can contain tokens like {0}, {1}, where the number in the braces is a 0-based index into the list of arguments. The value of the argument will replace the token in the resulting string. These tokens allow additional modifiers as well. For example, {0:f6} prints the first argument in fixed point format with 6 digits to the right of the decimal point. If you need to include a double-quote character (") in the format string you must precede it with a backslash character (\) as in \" so the double-quote is not taken as the closing quote of the format string.

Example:

Debug.Print("v[{0}] = {1:f6}", index, v[index])

Debug.Alert is identical to Debug.Print except that it additionally displays the Error/Debug Window if not already displayed and can be used to generate error messages.

Debug.Error is identical to Debug.Alert except that it additionally generates a runtime error causing the program processing to termanate..

Debug.PringString is identical to Debug.Print except that it does not print a newline character at the end of the string so you can append additional information on the same output line.

Debug.PrintSymbols takes a comma (,) separated list of non-array variables, and prints their name and value, 1 per line. If you call Debug.PrintSymbols with no arguments, it prints all non-array symbols in the active symbol table. Inline functions/methods have their own symbol table.

Example:

Debug.PrintSymbols(z, zprev1, zprev2)

This prints the symbols z, zprev1, and zprev2.

Example:

Debug.PrintSymbols()

This prints the all the symbols in the active symbol table. If this method is called from within an inline function/method, it prints the symbols in the symbol table associated with the inline function/method.

While on the subject of inline functions/methods it should also be noted that during optimization, some function/method arguments may be substituted directly into the function/method symbol table. This makes calling these inline functions/methods very fast since there is virtually no overhead associated with passing these arguments. However, this has the unexpected effect of mislabeling these arguments when passed to Debug.PrintSymbols.

Example:

macros:
 
  Complex Shift(p) {
    Debug.PrintSymbols(p)
    return p+1
  }
 
global:

  x = 999
  y = Shift(x)
  z = Shift(x+1)

The above Debug.PrintSymbols(p) prints x=999 in the 1st call to Shift rather than the expected p=999. This is because, during optimization, the symbol x is substituted directly into the symbol table for the function Shift and the formal argument name is lost. This is small price to pay for the increase in performance. The 2nd call to the function Shift with the argument x+1 will print the expected p=1000 since the argument is an expression and not a symbol and so no symbol table substitution takes place in this case.

Debug.PrintArray takes a single array and prints the array name and items. If the array has more than 100 items only first and last 50 are printed.

Example:

Debug.PrintArray(v[])

Debug.PrintEnum and Debug.PrintProxy print an enum item name or a function proxy name respectively.

Example:

global:

  Debug.PrintString("Shape = ")
  Debug.PrintEnum(ShapeTypes, Shape)
  Debug.PrintString(", F = ")
  Debug.PrintProxy(F)
  Debug.Print("") ' print carriage return

properties:
 
  #include ShapeTypes
 
  option Shape {
    type = ShapeTypes
    caption = "Shape"
    default = ShapeTypes.Circle
  }
  #include ComplexFunctions
 
  option F {
    Type = ComplexFunctions
    caption = "F"
    default = Pow2
  }

This example prints the enum item name associated with the value of Shape and the function proxy for the value of F. Like Debug.PrintString, the methods Debug.PrintEnum and Debug.PrintProxy do not print a newline character at the end of the string so you can append additional information on the same output line.

Finally, a word of advice: when you develop your software, start small, grow slowly, and test often. That is, the best way to avoid the unsettling situation where you have absolutely no clue as to the cause of a problem is to develop the program in small, incremental steps, so the location of the problem, at least, is contained to a small number of lines of code.

 

Copyright © 2004-2019 Ross Hilbert
All rights reserved