Cross-Debugging

Introduction

The SAS/C Debugger provides the capability of debugging programs in a cross-development environment. To debug a load module that was compiled with the SAS/C or C++ cross-platform compiler, you simply run the program with the =debug runtime option, just like any other SAS/C or C++ load module.

The debugger provides access to information from several different types of files, which may be resident on either the UNIX host or the target mainframe, including:

When developing an application in a cross-development environment, the files used by the debugger, with the exception of the load module, may reside on the host workstation. In order for the debugger to access files that reside on the workstation, a distributed file system must be used to establish a client/server relationship between the target mainframe and the host workstation. The distributed file system used in the SAS/C cross-development environment is the Network File System (NFS) described in Appendix A, "Installing and Administering the NFS Client" on page 83 and SAS Technical Report C-113, SAS/C Connectivity Support Library, Release 1.00. Using NFS, the debugger, running on the mainframe under MVS or CMS, has direct access to the source, include, and debugger files that reside on the host workstation.

If the debugger's default file searching mechanism does not meet your needs, you can change or augment the search mechanism with the debugger's set search command.

The set search command is used to specify filename templates. Filename templates are used to specify the identity and location of the source, include, or debugger files associated with the load module being debugged. Multiple filename templates can be defined for each type of file. As a result, the debugger can search for a file by more than one name or in multiple locations. Each template is saved in a search list, and each search list is associated with a specific type of file.

Filename templates are character strings which are similar to the patterns used in a C printf statement. Each filename template may contain conversion specifiers and characters. A conversion specifier is a character or a string preceded by a percent character. The conversion specifier is either replaced by its associated string or specifies the format of the conversion specifier that follows it. The resulting string is used as the name of the file to be opened. If a file with the resulting name cannot be opened, the next filename template in the search list is processed until either a file is opened or there are no more filename templates in the search list for that type of file.

This is a very powerful technique that allows you to direct the debugger to files that have moved or even changed names or file systems. This chapter explains how to use the set search and set cache commands to define filename templates and establish search lists.

Figure 3 illustrates the relationship between the files used by the SAS/C Debugger in
the cross-development environment.

FIGURE 3 Debugging in a Cross-Development Environment(Figure)

Using the SAS/C Debugger in a Cross-Development Environment

To debug a program in the cross-development environment, you should perform the following steps:

  1. Compile the program on the host workstation, using the -g option to specify generation of a debugger file.
  2. Create a load module for your program that resides on the target mainframe.
  3. Use the NFSLOGIN command to access the NFS server network from the mainframe. See "Logging on to the NFS Network" on page 91 for more information.
  4. Mount the workstation's file system from your mainframe client using one of the methods described in "Accessing Remote File Systems" on page 92.
  5. Invoke the debugger, using set search commands in the debugger PROFILE to specify search lists for the source, include, and debugger files.
Note: The debugger uses standard fopen calls to access these files. If you encounter difficulty accessing files, the problem may be caused by your remote file mount, and the failure to properly match the mount point and the templates in the debugger's search lists.
If you do not use the set search command to specify search lists, the debugger resorts to its default search mechanism, using the filenames contained in the object and debugger files to locate files. By default, the debugger uses the path: filename style prefix with workstation filenames. The path: prefix is described in Appendix A on page 83.

The next section explains how to use the debugger's set command to specify search lists and a cache location for the debugger file. You should refer to the SAS/C Debugger User's Guide and Reference, Third Edition for additional information about the SAS/C Debugger.

Using the Debugger's set Command

The SAS/C Debugger's set command provides two subcommands: set search and set cache. The set search command is used to specify a search list consisting of one or more filename templates. Each filename template specifies a location used by the debugger to search for source, include, or debugger files associated with the load module being debugged. The debugger traverses the search list, looking for the file specified by each filename template.

The set cache command is used in cross-development environments that support a distributed file system, primarily to improve the debuggers performance when accessing debugger files. The benefit is especially noticeable when debugger files are large. This command uses a filename template to specify the primary location to save and search for debugger files. In a typical cross-debugging session, this location would be on the mainframe.

Note: Frequently, file access problems are caused by an improper mount to the remote file system. If you encounter difficulty with either the set search or the set cache subcommands, refer to "Accessing Remote File Systems" on page 92.

Locating the Debugger File

Load modules that have been generated from objects compiled by the SAS/C compiler contain filename information for the debugger file. The format of this filename information depends on the host that performed the compilation and the file system the debugger file was created in. When debugging a program compiled by the SAS/C Cross-Platform Compiler, the debugger will look for the debugger file in the following locations in the order listed:

  1. Any cache location, as specified by the set cache command.
  2. Any locations in the debug search list, as specified by the set search debug command.
  3. The original file name the compiler used to open the file when it was created.
  4. The file name the compiler used to open the file when it was created with the SAS/C filename style prefix path:.
The debugger first checks to see if a cache location has been specified. The set cache command uses a filename template to specify a location for the debugger file. For example, the following form of in the set cache command could be used to specify a cache location in the CMS file system:

 'SET CACHE DEBUG = "%sname dbg370"'
If the debugger file is found in the cache location, that file is opened. If the debugger file is not found in the cache location or the module has been recompiled since the debugger file in the cache location was last copied, the debugger continues to search for the file by performing the remaining steps in the search order. If the debugger file is found, it is then copied to the specified cache location and the new cache file is used.

If no cache location was specified or a debugger file is not found in the cache location, the debugger will attempt to find the debugger file using any filename templates defined in the debug search list. On MVS systems, the debugger has a default search list for debugger files which, is equivalent to the command:

 set search debug = "//ddn:DBGLIB(%sname)"
Note: You can create an empty debug search list with a set search debug command of the form: set search debug = "".

On CMS systems, no default templates are defined for the debug search list, so you will probably want to define one or more templates. The following form of the set search command can be used to specify an new search list for the debugger file:

 'SET SEARCH DEBUG = "path:obj/%l%sname.dbg370"'
If the debugger file is not found using the debug search list, then the debugger will attempt to open the file by the name the compiler used when it created the file.

Finally, the debugger will attempt to open a file with the name the compiler used when it created the file and the SAS/C filename style prefix path:.

Locating Source Files

The debugger file contains filename information for the source and alternate source files used to compile your program. The debugger will look for the source file in the following locations in the order listed:

  1. Any locations in the source search list, as specified by the set search source command.
  2. The original file name the compiler used to open the file when it was created.
  3. The file name the compiler used to open the file when it was created with the SAS/C filename
    style prefix path:.
On MVS systems, the debugger uses a default search list for source files, which is equivalent to the following command:

 set search source = "//ddn:DBGSRC(%sname)"
If a file is not found using one of the templates in the source search list the debugger attempts to open the file by the name the compiler used for the file. Finally, the debugger will attempt to open a file with the name the compiler used when it created the file, prefixed by the SAS/C filename style prefix path:.

The source search list is not checked for source files that have been altered by a #line preprocessor statement that specified a file name. Instead, the separate altsource search list is used.

You can use the following forms of the set search command to specify a new source search list to be used to locate these files:

 set search source = "template1" "template2"...
 set search altsource = "template1" "template2"...

Locating include Files

The debugger file also contains filename information for the system include and user include files used to compile your program. The different types of include files each have a separate search list. The debugger will look for an include file in the following locations in the order listed:

  1. Any locations in the associated search list, as specified by the set search systeminclude command or the set search userinclude command.
  2. The original file name the compiler used to open the file when it was created.
  3. The file name the compiler used to open the file when it was created with the SAS/C filename
    style prefix path:.
You can use the following forms of the set search command to specify a new search
list to be used to locate these files:

 set search systeminclude = "template1" "template2"...
 set search userinclude = "template1" "template2"...

Debugger Performance Considerations

A distributed file system makes it possible to develop your applications in a cross-development environment. In a distributed file system, programs can read or write files directly in a file system on a remote machine. The Network File System (NFS) client support provided by the SAS/C Connectivity Support Library allows the SAS/C Debugger to access files that do not reside on the mainframe at all. Additional information can be found in Appendix B, "Using the NFS Client" on page 91.

The main performance issue to consider when debugging in a cross-development environment is the time required by the debugger, which runs on the mainframe, to access files residing on the host workstation. In general, if you can reduce the number of times files that reside on the workstation are accessed by the debugger, performance will be improved.

One method of improving debugger performance is to use the set search command to direct the debugger to access files residing on the mainframe whenever possible. For example, when developing in a cross-development environment, it is likely that identical copies of the system include files will reside on both the host workstation and the target mainframe. You should use the set search systeminclude command to direct the debugger to use the system include files located on the target mainframe.

Another way to improve performance is to specify a debugger Source Window buffer that is large enough to hold the entire source file. This allows the debugger to keep the entire source file in mainframe memory for the time that the compilation is being debugged. Switching compilations causes the file to be flushed. As a guideline, the amount of memory needed to hold one source line is equal to the length of the line, after stripping trailing blanks, plus three bytes. Refer to documentation for the Config Window and the window memory command in the SAS/C Debugger User's Guide and Reference, Third Edition for more information about debugger window buffers.

Even though your source, include, and debugger files may reside on the host
workstation, on systems that do not enjoy the advantages of a distributed file system, or if your situation requires you to minimize network traffic, it may be advantageous to use a file transfer mechanism, such as FTP, to copy some of these files to the target mainframe. For example, if you are debugging an application composed of many source files and you are only actively developing the code in one or two of those files, the performance of the debugger will be improved if the source files that will not require frequent changes and re-compilation reside on the target mainframe as well as the host workstation.

Similarly, you may use the set cache command to establish a cache location for your
debugger file if you feel this appropriate for the application being debugged.

set Command Reference

The SAS/C Debugger's set command is best used in the debugger PROFILE to specify search lists for source, include, and debugger files, as well as a cache location for your debugger file. However, the set command may also be issued on the command line. The following reference section describes both the set search subcommand and the set cache subcommand.

set

Controls file access.

ABBREVIATION

se{t}

FORMAT

set subcommand subcommand-arguments

DESCRIPTION

The set command has two subcommands: search and cache. The set search command is used to control the search templates that are used to access debugger and source files, and the set cache command is used to specify a cache location for debugger files. The set cache command also uses a template to specify this location.

The set search and set cache subcommands are described in the following paragraphs.

search SUBCOMMAND

The search subcommand is used to establish a search list, to control tracing, add, or remove templates from a search list. The search subcommand has the following forms:

TABLE 22. search Subcommand Formats

---------------------------------------------------------------------
| Format  | Example                                                 |
=====================================================================
| 1       | set search file-tag =|+|- "template1" ["template2"...]  |
---------------------------------------------------------------------
| 2       | set search file-tag =                                   |
---------------------------------------------------------------------
| 3       | set search file-tag |* ?                                |
---------------------------------------------------------------------
| 4       | set search file-tag |* trace on|trace off               |
---------------------------------------------------------------------

The file-tag argument specifies the type of file that a template applies to and can be any of the following:

TABLE 23. file-tag Values

--------------------------------------------------------------------------
| Type of file   | Description                                           |
==========================================================================
| debug          | specifies that the template is for debugger files.    |
--------------------------------------------------------------------------
| source         | specifies that the template is for source files.      |
--------------------------------------------------------------------------
| altsource      | specifies that the template is for alternate source   |
|                | files. (An alternate source file refers to source     |
|                | code altered by a #line preprocessor statement        |
|                | that specifies a filename.)                           |
--------------------------------------------------------------------------
| systeminclude  | specifies that the template is for system include     |
|                | files.                                                |
--------------------------------------------------------------------------
| userinclude    | specifies that the template is for user include       |
|                | files.                                                |
--------------------------------------------------------------------------

Format 1: This format of the set command specifies a search list for the type of files designated by file-tag. Each search list consists of one or more templates that are used by the debugger to locate debugger or source file types.

The =|+|- argument is used as follows:

TABLE 24. set command Operations

------------------------------------------------------------------------
| Argument  | Description                                              |
========================================================================
| =         | sets the search list equal to the specified templates.   |
------------------------------------------------------------------------
| +         | appends the specified templates to the search list.      |
------------------------------------------------------------------------
| -         | removes all occurrences of the specified templates       |
|           | from the search list.                                    |
------------------------------------------------------------------------

The template arguments define the search list. Each template argument uses one or more of the following conversion specifiers to define a template used by the debugger to generate filenames:

TABLE 25. template Arguments

--------------------------------------------------------------------------------
| Value              | Description                                             |
================================================================================
| %lower or %l       | causes the replacement text for the conversion          |
|                    | specifier following the %lower to be converted          |
|                    | to lowercase. The character after the %lower or         |
|                    | %l must be the start of another conversion              |
|                    | specifier.                                              |
--------------------------------------------------------------------------------
| %upper or %u       | causes the replacement text for the conversion          |
|                    | specifier following the %upper to be converted          |
|                    | to uppercase. The character after the %upper or         |
|                    | %u must be the start of another conversion              |
|                    | specifier.                                              |
--------------------------------------------------------------------------------
| %sname or %s       | is replaced by the section name of the program          |
|                    | being debugged. (The section name must have             |
|                    | been specified when the program was compiled.)          |
|                    | The section name is always uppercase, if a              |
|                    | lowercase version is required, prefix the %sname        |
|                    | or %s specification with %lower.                        |
--------------------------------------------------------------------------------
| %fullname          | is replaced by the entire filename stored in the        |
|                    | object or debugger files. The format of the             |
|                    | filename is implementation dependent and this           |
|                    | conversion specifier should not be used unless          |
|                    | you have complete knowledge of the filename             |
|                    | stored in the object or debugger files. This            |
|                    | conversion specifier is most useful for alternate       |
|                    | source files, where it will be replaced by the          |
|                    | complete filename that appears in the #line             |
|                    | statement.                                              |
--------------------------------------------------------------------------------
| %leafname or %lf   | is replaced by the portion of the filename stored       |
|                    | in the object or debugger files after the last slash,   |
|                    | if present. If there is no slash, it is the entire      |
|                    | filename stored in the object or debugger files.        |
--------------------------------------------------------------------------------
| %basename or %b    | is replaced by the portion of %leafname that is         |
|                    | before the last dot. If there is not a dot in           |
|                    | %leafname, then %basename is the same as                |
|                    | %leafname.                                              |
--------------------------------------------------------------------------------
| %extension or %e   | is replaced by the portion of %leafname that is         |
|                    | after the last dot. If there is not a dot in            |
|                    | %leafname, then %extension is set to a null             |
|                    | string.                                                 |
--------------------------------------------------------------------------------

You can include a percent character (%) in a template by specifying two percent characters in a row (%%).

The filenames generated by the application of the conversion specifiers in the template are passed to the fopen function, which opens the appropriate file for the debugger to access. If these files are located on a remote host, the SAS/C Connectivity Support Library is used to establish an NFS connection between the local and remote host.

For example, to use SAS/C Connectivity Support Library to access files on a UNIX workstation, the following template could be specified:

 "path:dbgfiledir/%leafname"
If %leafname consists of a base and an extension, a functionally equivalent template could be specified as follows:

 "path:dbgfiledir/%basename.%extension"
A similar template could be specified to access files on MVS. For example, the following template would access a PDS member that matches %basename:

 "dsn:userid.proj4.h(%basename)"
Format 2: The second form of the set search command is used to remove all of the search templates associated with a file-tag. It specifies a null search list.

Format 3: The question mark (?) character is used to display the search list associated with a file-tag. An asterisk (*) can be used as a wildcard character in place of a specific file-tag argument. Specifying set search * ? will display the search lists for all debugger and source files, including the cache location, if it was specified with a set cache command.

Format 4: The final form of the set search subcommand is used to turn tracing on or off. When tracing is turned on, the debugger displays a message each time it attempts to open a file, possibly using a filename generated by a template. The message displays the name of the file the debugger was looking for and whether or not the search was successful.

An asterisk (*) can be used as a wildcard character in place of a specific file-tag argument. If an asterisk is specified for the file-tag, tracing will be affected (either turned on or turned off) for debug, source, altsource, systeminclude, and userinclude files.

cache SUBCOMMAND

The set cache command is used to specify a cache location for the debugger file. (In a cross- development environment, the original debugger file may be located on the host workstation and the cache location will be on the target mainframe.) A cache location is specified to provide faster access to debugging information.

The format for the set cache subcommand is as follows:

Format: set cache debug = "template"

Notice that debug is the only valid type of file for the set cache subcommand.

The template argument is described in the previous section and is used to specify the cache location. When debugging a program, the debugger first looks for the debugger file in the cache location. If the debugger finds a current version of the debugger file in the cache location, then the debugger uses the file. If a debugger file is not found in the cache location, or if the debugger file in the cache location is not current, then the current debugger file is copied to the cache location. However, if the cache file is not a valid debugger file, it will not be overwritten by the debugger.

EXAMPLES

 set search userinclude = "path:/usr/c/headers/%leafname"
specifies a search list for user include files. When the debugger looks for source code that was included from a user include file located on a host workstation, this template is used to generate a filename and open the file on the workstation.

 set search source = "hfs:/home/cxx/src/%leafname"
specifies a search list for source files in the MVS OpenEdition hierarchical file system (HFS). The hfs: filename style prefix instructs the debugger to look for the file in the HFS file system and open the file if it is found.

 set search userinclude + "dsn:userid.c.headers(%basename)"
specifies a template that is appended to the search list for user include files that was established in the previous example. This template generates an MVS dsn: style filename that is searched if the user include file is not found on the workstation.

 set search userinclude trace on  
turns tracing on for user include files. Whenever the debugger searches for a user include file, a message will be displayed telling you the name of the file searched for and if the search was successful or not.

 set search userinclude ? 
displays the search template list used to generate filenames for user include file searches.

 set search userinclude =  
resets the search template list for user include files to null.

 set cache debug = "dsn:userid.cache.db(%sname)" 
specifies an MVS data set used to cache the debugger file on the target mainframe.

 set cache debug = "cms:%sname dbg370" 
specifies the location of a CMS file used to cache the debugger file on a target mainframe.

SYSTEM DEPENDENCIES

The filenames generated by the search templates are dependent upon the names the compiler used to open the files originally, which are operating system dependent.

COMMAND CAN BE ISSUED FROM

debugger start-up file yes

command line yes

configuration file no

Source window prefix none

SCOPE

The set command is not affected by changes in scope.

RETURN CODES SET

Successful: 0

Unsuccessful: 1