Understanding the Synergy debugger

The Synergy DBL source-level debugger enables you to run your traditional Synergy programs in debug mode so you can control and examine the execution environment. The debugger supports line numbers, source display, breakpoints, watchpoints, examination by offset, .INCLUDEd routines, dimensioned variables, and named access to fields, including complete variable path specifications.

This topic contains the following information:

Creating a symbolic access table

If you want to be able to perform source displays and look up variables by their names, you must create a symbolic access table. If you don’t, you will not have access to the symbolic information when debugging. To create a symbolic access table,

On

Do this

Windows and UNIX

Use the -d or -qdebug option when you compile and the -d option when you link. For example:

dbl -d source_file
dblink -d input_file

OpenVMS

Use the /DEBUG option when you compile, and then link normally. For example:

dbl /debug source_fileor  dibol /debug source_file
dblink source_file

On OpenVMS, the main routine must also be compiled with the /DEBUG switch for the program to start up in debug mode.

Invoking the debugger

To invoke the debugger, enter the appropriate command for your operating system,where program is the name of your compiled and linked Synergy program:

On

Enter

Windows and UNIX

dbr -d program

or

dbr -rd port[:timeout] program

(See Debugging remotely on Windows and UNIX for more information about the second format.)

OpenVMS

run program

Your command line prompt is

DBG>

(or DblDbg> on OpenVMS systems) and you can enter any of the debugger commands described in Synergy debugger commands.

On OpenVMS, if system option #49 is set, the runtime does not enter the debugger when you run programs built with the /DEBUG compiler option.

If you’re running your program in the debugger and a fatal error is encountered, the debugger generates the fatal error message and its traceback and break at the line that caused the fatal error. This feature enables you to investigate the circumstances that surround the error.

Online help for the debugger is available by typing

help [command]

where command is the command for which you want more information. To see a list of commands, just type “help” by itelf.

Note

A system define called _DEBUG is defined when compiling with -d or -qdebug:1. By testing for _DEBUG using .IFDEF and .IFNDEF, you can conditionally include or exclude code based on whether or not a program is compiled in debug mode.

Using the debugger on Windows

When you are debugging a Synergy application on Windows, the debugger output appears in a separate window. Debugger commands can be entered in this window at the prompt.

You can specify the initial size and placement of the Synergy debugger window in the synergy.ini file using the initialization settings DBG_HEIGHT, DBG_WIDTH, DBG_X, and DBG_Y. If the window fits on the desktop, it appears without scroll bars. If the window is resized to be smaller than the originally created size, it displays scroll bars on the window borders, which you can then move with the mouse to view the rest of the screen.

You can specify the font used in the debugger window using the FONT_DEBUG initialization setting. Refer to Using fonts on Windows for the defaulting hierarchy used when FONT_DEBUG is not specified. We recommend using a fixed font for the debugger.

Important

If you move a source file and a .dbr file from Windows to UNIX or vice versa, you must move the files in binary mode if you want to view the source code correctly in the debugger. If you move the source file in ASCII mode (via FTP), the LF or CR-LF line terminators will not be preserved.

Indirect command file processing

You can control the debugger indirectly using a command file. If an “at” sign (@) is the first character on an input line, the remainder of the line is assumed to be the name of a text file that contains debug commands to be executed.

When you specify a command file, a new command file level is activated until the last line in the file is executed. If one of the lines executed is another indirect command file specification, another level is activated until the lines in that file are executed. Up to eight levels can be activated in the debugger.

The default filename extension for a command file is .cmd, and full Synergy DBL–style logical name translation occurs.

On OpenVMS, you can use the DBG$INPUT and DBG$OUTPUT logical names to redirect debugger input and output.

Initialization file processing

You can also control the debugger using an initialization file. If you set the environment variable DBG_INIT to the name of your initialization file, the debugger reads the file and executes the debugger commands within it.

The default filename extension for an initialization file is .cmd (.com on OpenVMS).

Specifying variables

A variable specification can be a simple variable, a variable path, or a field belonging to an object instance. In fact, any variable specification that is valid during compilation is valid in the debugger, except that you can only specify a maximum of 12 elements within a given path specification. Like the compiler, the debugger requires that each variable path be unique.

A variable specification has any of the following formats:

where term is any simple variable or path specification, routine is the name of a routine in the current calling chain, object is an object instance variable name, field is a field name, record is a record name, and group is a group name.

For example, the following are all valid variable specifications:

v(1)
v(1:3)
rout:v(2,5)
grp1.fld
test:grp1[2].grp2[8].fld
myclass.myfield
(myclass)x.myfield
ns1.ns2.myclass.myfield

To reference arguments, use

@-argnum

To reference an object instance’s field value, specify the object instance variable name and field name. For example,

x.myfield

To reference an object instance’s field value from an ancestor class, you can cast the object instance variable to any of the ancestors of the created class. Only one cast is allowed per EXAMINE command, but the object path can be enclosed in parentheses to clarify the object being cast. Use one of the following syntaxes:

(class_path)handle
(class_path)handle.field
(class_path)(handle_path).field
(class_path)(array_list[entry]).field

where class_path is namespace.class and handle_path is record.group.handle. For example,

(myclass)x.myfield

or

(myclass)(x.y).myfield

or

(myclass)(myarray[0]).myfield

To cast a boxed object, use one of the following syntaxes:

(@structure_path)handle
(@structure_path)handle.field
(@structure_path)(handle_path)
(@structure_path)(handle_path).field
(@boxed_type)handle
(@boxed_type)(handle_path)

where structure_path is namespace.structure; handle_path is record.group.handle; and boxed_type is a, d, or i.

You can reference a field value for the current object instance from within an instance method by supplying the field name, or you can specify the this keyword. For example,

this.myfield

The path for a static field in a class is made up of two parts: the class path and the field path. The class path is made up of namespace and class identifiers which may be abbreviated on the left side as long as the path is unique, but the specified identifiers must be an exact path without any missing identifiers. The field path must be a path to a static field in the specified class but may have unspecified identifiers as long as it is unique. When in a method, the static field paths may be specified without the class path as long as the static field is a member of the same class as the method. For example,

myclass.myfield

or

ns1.ns2.myclass.myfield

You cannot reference a complex path that includes an indexer, method call, or property.

Debugging remotely on Windows and UNIX

The Synergy DBL debugger can also run in a client/server configuration, where dbr acts as the debug server and the debug client is any program that is capable of acting as a Telnet client. Running the debugger remotely has several benefits:

Running the debugger remotely requires the following:

To run the debugger remotely, do the following:

1. (Recommended) Compile and link with the -d option.
2. Start the program to be debugged with dbr -rd on the command line:
dbr -rd port[:timeout] program

where port is the port number on which the debug server will listen as a Telnet server for the debug client (1024 to 65535, inclusive), timeout is the number of seconds the debug server will wait for a connection from the debug client (the default is 100), and program is the name of your compiled and linked Synergy program. If you include the timeout, there cannot be a space on either side of the colon. Make sure timeout is lower than your client connection timeout value.

Note

(Windows) If your program is a detached program or a service that is normally started with dbs or dbssvc, your environment may change, because dbr always reads the synergy.ini file, whereas dbs and dbssvc read it only when SFWINIPATH is set. We recommend that you use SFWINIPATH to point to the location of your synergy.ini file and thereby avoid potential problems. For more information on dbs and dbssvc, see Non-interactive runtimes.

3. Start a Telnet session and connect to the debug server. (The Telnet application may be on the same machine as the debug server or on a separate machine.) Specify the IP address or host name of the debug server (or localhost if you are on the same machine as the debug server) and the port number you specified with the -rd option.

Once a connection is established, the debug session displays in the Telnet session window on the debug client machine.

4. Debug your program. (Remember that your source files must be accessible by the debug server machine if you want to view source code within the debugger.)

The debug commands WINDBG (invoke the Toolkit window debugger) and ! (invoke a shell command) are not supported by the debug server. If either command is used, an error is generated.

Note

Most Telnet applications support paging and scrolling in the window. This provides a scrollable debug display and enables you to see more of what you are working on than in the normal Synergy debugger window.

5. Once debugging is complete, let the program finish running; the runtime will exit, and the Telnet session will close automatically. Optionally, you can close the session in one of the following ways:

For more information and specific instructions for debugging when xfServerPlus is involved, see Debugging your remote Synergy routines.

Timeouts or other failures are logged to a file named rd.log, which is created in the TEMP directory when the first entry in the file is logged. This file contains the process ID of the instance of the runtime that logged entries, the date and time entries were logged, and specific messages. If you are having a problem debugging remotely, check this file first.

Tip

When using remote debugging with xfServerPlus, we recommend that you explicitly set TEMP in the Synrc node in the Windows registry, or else rsynd will put the log file in a system-determined location (most likely somewhere in the C:\Users path).

Debugging remotely on OpenVMS

To set remote debugging,

1. Compile with the /DEBUG option.
2. Link the program as usual
3. Define the DBG_RMT logical.

Debugger warnings

When a program is running in debug mode, some warnings are output to the debug window so you can fix potential issues before they cause runtime errors that can break your production system:

file1 file2 duplicate common/gds/static rec record of differing size size1 - size2

Duplicate global common or global data sections exist with different sizes. This fatal error can occur if only part of an application is rebuilt when common and global data section definitions change. Ensure that global common and global data section initializations are defined in only one place via .INCLUDE, preferably in a base ELB/shared image.

Duplicate common/static rec/gds record in ELBs file1 file2 detected - duplicate ignored

Commons and global data sections should never be duplicated in a process. The name lookup algorithm for data variables may cause duplicates to be used concurrently, leading to unexpected program behavior. For example, if a variable called mycommon exists in two places, two different pieces of code may update different mycommon variables. Ensure that global common and global data section INITs are defined in only one place, preferably in a base ELB/shared image.

Casting invalid length length argument as Integer in routine routine line line#

You've passed a variable for ^I() that is not size 1, 2, 4, or 8. Integer data must be one of these lengths; correct your code to pass a variable of the correct size.

Pushing passed integer/object descriptor of declared type argument routine routine line line#

You've passed an integer or object to a routine parameter typed d or d., or to ^D() or ^F(). Fix the call in your code.