Recording Control Flow in Debug Instrumentation

You can configure the debug instrumentation to automatically record procedure flow as your program calls subroutines and then returns back to main code. The available control flow statements that can be recorded are:

- call
- callwithin
- execute
- farcall
- farcallwithin
- goto
- returnerror
- return
- shortcall
- stop

If you are using the Instrumentation Log window, this feature can be enabled from the Control Flow icon in the upper right corner. Clicking on this icon brings up a popup menu:

Use this menu to tell Panorama which control flow operations you want recorded.

Keep in mind that if you record all of these statements, your log may contain more information than you really want to look at. In fact, recording all of these may slow down Panorama operation as it takes time to record each item.

The instrumentation log not only shows code in your own databases that are triggered, but code in Panorama itself. Much of Panorama is written in Panorama code, so it can be educational to enable recording of control flow statements and then start clicking on things in Panorama to see what is being called within Panorama. For example you’ll see lots of action if you open the Find/Select dialog and click a few buttons.

    -[ExecuteStatement run] findselectdialog
    -[ExecuteStatement run] windowglobal «_HotKeys»
    -[ExecuteStatement run] rtn           settrigger "Key.ESCAPE"         resume {}         if error             global dlgStack             dlgStac
    -[ExecuteStatement run] rtn              global dlgStack             define dlgStack,""             local s             let cb=tagparameter(arra
    -[ExecuteStatement run] rtn              global dlgStack             define dlgStack,""             local s,cb             let cb=tagparameter(a
    -[CallStatement run] initializeDimensions (in _FindSelectLib)
    -[CallStatement run] adjustQueryHeight (in _FindSelectLib)
    -[CallStatement run] makeQueryRows (in _FindSelectLib)
    -[CallStatement run] deleteAllQueryRows (in _FindSelectLib)
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q0field,q0operator,q0operand1,q0operand2     q0field="" q0operator="" q0operand1="" q0operand2=""
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q1field,q1operator,q1operand1,q1operand2     q1field="" q1operator="" q1operand1="" q1operand2=""
    -[ExecuteStatement run]          showvariables q1field,q1operator,q1operand1,q1operand2
    -[CallStatement run] makeQueryFormula (in _FindSelectLib)
    -[CallStatement run] editQueryRow (in _FindSelectLib)
    PopupButtonObject RUN CODE --> call queryFieldChanged,1
    -[CallStatement run] queryFieldChanged (in _FindSelectLib)
    -[CallStatement run] initializeDimensions (in _FindSelectLib)
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q1field,q1operator,q1operand1,q1operand2     q1field="" q1operator="" q1operand1="" q1operand2=""
    -[ExecuteStatement run]          showvariables q1field,q1operator,q1operand1,q1operand2
    -[CallStatement run] makeQueryFormula (in _FindSelectLib)
    -[CallStatement run] editQueryRow (in _FindSelectLib)
    TextDisplayObject RUN CODE --> call queryRowInsert,1
    -[CallStatement run] queryRowInsert (in _FindSelectLib)
    -[CallStatement run] initializeDimensions (in _FindSelectLib)
    -[CallStatement run] adjustQueryHeight (in _FindSelectLib)
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q2field,q2operator,q2operand1,q2operand2     q2field="" q2operator="" q2operand1="" q2operand2=""
    -[ExecuteStatement run]          showvariables q2field,q2operator,q2operand1,q2operand2
    -[CallStatement run] makeQueryFormula (in _FindSelectLib)
    -[CallStatement run] editQueryRow (in _FindSelectLib)
    PopupButtonObject RUN CODE --> call queryFieldChanged,2
    -[CallStatement run] queryFieldChanged (in _FindSelectLib)
    -[CallStatement run] initializeDimensions (in _FindSelectLib)
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q2field,q2operator,q2operand1,q2operand2     q2field="" q2operator="" q2operand1="" q2operand2=""
    -[ExecuteStatement run]          showvariables q2field,q2operator,q2operand1,q2operand2
    -[CallStatement run] makeQueryFormula (in _FindSelectLib)
    -[CallStatement run] editQueryRow (in _FindSelectLib)
    PopupButtonObject RUN CODE --> call queryOperatorChanged,2
    -[CallStatement run] queryOperatorChanged (in _FindSelectLib)
    -[CallStatement run] initializeDimensions (in _FindSelectLib)
    -[CallStatement run] makeQueryRow (in _FindSelectLib)
    -[ExecuteStatement run]      fileglobal q2field,q2operator,q2operand1,q2operand2     q2field="" q2operator="" q2operand1="" q2operand2=""
    -[ExecuteStatement run]          showvariables q2field,q2operator,q2operand1,q2operand2
    -[CallStatement run] makeQueryFormula (in _FindSelectLib)
    -[CallStatement run] editQueryRow (in _FindSelectLib)

(Note: Some code built into Panorama is protected and will not be recorded.)

#### Enabling Control Flow Recording with the Instrumentation Panel

If you are not using the Instrumentation Log window (see [Debug Instrumentation Monitoring using an External Program]), you can still enable control flow recording using the Instrumentation panel of the Preferences window. First, click on Objective-C Classes at the bottom of the list on the left, then choose the control flow statements you want to record in the log.

Click again to disable recording.

See Also

- Client/Server Debug Instrumentation -- using instrumentation with Panorama X server and clients.
- Coding with Debug Instrumentation -- modifying your code to generate debug instrumentation output.
- Crash Proof Debug Instrumentation Monitoring -- real time crash-proof instrumentation monitoring
- Customizing Debug Instrumentation Coverage -- specifying what code is being debugged at the moment.
- Debug Instrumentation -- conditional logging of the internal state of Panorama program code.
- Debug Instrumentation Log Window -- dynamically monitor debug instrumentation output as your program runs.
- Debug Instrumentation Monitoring using an External Program -- monitoring debug instrumentation with an external program (Terminal.app, BBEdit.app).
- Debug Instrumentation Text File -- configuring and accessing the debug instrumentation log (text) file.
- info("runningunderterminal") -- returns the name of the terminal program if Panorama was launched under one, otherwise it returns empty text.
- labelize( -- returns the value of a field or variable along with a label. This saves typing when you need to display fields or variables when logging and debugging.
- labelizeformula( -- returns the value of a formula along with the formula itself as a label.
- labelizeinfo( -- returns the value of an info( function, along with the function itself as a label.
- labelizepattern( -- formats a text value using a label and a pattern.
- Recording Code Triggers in Debug Instrumentation -- the code triggers option automatically tracks whenever any code is triggered, whether from a menu, a button, or implicitly (for example when data is entered).
- setzlog -- turns instrumentation coverage on or off for a specific procedure (or all procedures within a database).
- zlog -- outputs a message to the instrumentation log (if instrumentation is enabled).
- zlogalways -- unconditionally outputs a message to the instrumentation log.
- zlogcoverage -- allows instrumentation coverage to be turned on or off within a procedure.
- zlogdictionary -- outputs a data dictionary to the instrumentation log (if instrumentation is enabled).
- zlogging( -- returns true if zlogging is enabled for the current database and procedure, otherwise false.

History

Version | Status | Notes
10.2 | New | New in this version.