Chapter Contents


SAS Macro Language: Reference

Debugging Techniques

If you cannot identify your problem in Troubleshooting Your Macros, you can use the techniques described in this section to pinpoint the location of the error.

Using System Options to Track Problems

The SAS system options MLOGIC, MPRINT, and SYMBOLGEN can help you track the macro code and SAS code generated by your macro. Messages generated by these options appear in the SAS log, prefixed by the name of the option responsible for the message.

Note:   Whenever you use the macro facility, use the following options: MACRO, MERROR, SERROR, and SOURCE. (While SOURCE is not a macro option, it is helpful to use this option when using the macro facility). In addition, if you are using autocall macros, use the MAUTOSOURCE option. See Table 13.8 for more system options associated with the macro facility.  [cautionend]

Although the following sections discuss each system option separately, you can, of course, combine them. However, each option can produce a significant amount of output, and too much information can be as confusing as too little. So, use only those options you think you might need and turn them off when you are done debugging.

Example of Tracing the Flow of Execution with MLOGIC

The MLOGIC system option traces the flow of execution of your macro, including the resolution of parameters, the scope of variables (global or local), the conditions of macro expressions being evaluated, the number of loop iterations, and the beginning and end of each macro execution. Use the MLOGIC option when you think a bug lies in the program logic (as opposed to simple syntax errors).

Note:   MLOGIC can produce a lot of output, so use it only when necessary, and turn it off when debugging is finished.  [cautionend]

In the following example, the macro FIRST calls the macro SECOND to evaluate an expression:

%macro second(param);
   %let a = %eval(&param);a
%mend second;

%macro first(exp);
   %if (%second(&exp) ge 0) %then
      %put **** result >= 0 ****;
      %put **** result < 0 ****;
%mend first;

options mlogic;

Submitting this example with option MLOGIC shows when each macro starts execution, the values of passed parameters, and the result of the expression evaluation.

MLOGIC(FIRST):  Beginning execution.
MLOGIC(FIRST):  Parameter EXP has value 1+2
MLOGIC(SECOND):  Beginning execution.
MLOGIC(SECOND):  Parameter PARAM has value 1+2
MLOGIC(SECOND):  %LET (variable name is A)
MLOGIC(SECOND):  Ending execution.
MLOGIC(FIRST):  %IF condition (%second(&exp) ge 0) is TRUE
MLOGIC(FIRST):  %PUT **** result >= 0 ****
MLOGIC(FIRST):  Ending execution.

Example of Examining the Generated SAS Statements with MPRINT

The MPRINT system option writes to the SAS log each SAS statement generated by a macro. Use the MPRINT option when you suspect your bug lies in code that is generated in a manner you did not expect.

For example, the following program generates a simple DATA step:

%macro second(param);
   %let a = %eval(&param);a
%mend second;

%macro first(exp);
   data _null_;
      put var=;
%mend first;

options mprint;

When you submit these statements with option MPRINT, these lines are written to the SAS log:



The MPRINT option shows you the generated text and identifies the macro that generated it.

Storing MPRINT Output in an External File

You can store text that is generated by the macro facility during macro execution in an external file. Printing the statements generated during macro execution to a file is useful for debugging macros when you want to test generated text in a later SAS session.

To use this feature, set both the MFILE and MPRINT system options on and also assign MPRINT as the fileref for the file to contain the output generated by the macro facility:

options mprint mfile;
filename mprint 'external-file';

The external file created by the MPRINT system option remains open until the SAS session terminates. The MPRINT text generated by the macro facility is written to the LOG window during the SAS session and to the external file when the session ends. The text consists of program statements generated during macro execution with macro variable references and macro expressions resolved. Only statements generated by the macro are stored in the external file. Any program statements outside the macro are not written to the external file. Each statement begins on a new line with one space separating words. The text is stored in the external file without the MPRINT(macroname): prefix, which is displayed in the LOG window.

If MPRINT is not assigned as a fileref or if the file cannot be accessed, warnings are written to the log and MFILE is turned off. To use the feature again, you must specify MFILE again.

By default, the MPRINT and MFILE options are off.

The following example uses the MPRINT and MFILE options to store generated text in the external file named TEMPOUT:

options mprint mfile;
filename mprint 'TEMPOUT';

%macro temp;
   data one;
      %do i=1 %to 3;
%mend temp;


The macro facility writes the following lines to the SAS log and creates the external file named TEMPOUT:

NOTE: The macro generated output from MPRINT will also be written 
      to external file '/u/local/abcdef/TEMPOUT' while OPTIONS 
      MPRINT and MFILE are set.

When the SAS session ends, the file TEMPOUT contains:


Note:   Using MPRINT to write code to an external file is a debugging tool only--it should not be used to create SAS code files for purposes other than debugging.  [cautionend]

Examining Macro Variable Resolution with SYMBOLGEN

The SYMBOLGEN system option tells you what each macro variable resolves to by writing messages to the SAS log. This option is especially useful in spotting quoting problems, where the macro variable resolves to something other than what you intended because of a special character.

For example, suppose you submit the following statements:

options symbolgen;

%let a1=dog;
%let b2=cat;
%let b=1;
%let c=2;
%let d=a;
%let e=b;
%put **** &&&d&b ****;
%put **** &&&e&c ****;

The SYMBOLGEN option writes these lines to the SAS log:

SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable D resolves to a
SYMBOLGEN:  Macro variable B resolves to 1
SYMBOLGEN:  Macro variable A1 resolves to dog
**** dog ****

SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable E resolves to b
SYMBOLGEN:  Macro variable C resolves to 2
SYMBOLGEN:  Macro variable B2 resolves to cat
**** cat ****

Reading the log provided by the SYMBOLGEN option is easier than examining the program statements to trace the indirect resolution. Notice that the SYMBOLGEN option traces each step of the macro variable resolution by the macro processor. When the resolution is complete, the %PUT statement writes the value to the SAS log.

When you use SYMBOLGEN to trace the values of macro variables that have been masked with a macro quoting function, you may see an additional message about the quoting being "stripped for printing." For example, suppose you submit the following statements, with SYMBOLGEN set to on:

%let nickname = %bquote(My name's O'Malley, but I'm called Bruce);
%put *** &nickname ***;

The SAS log contains the following after these statements have executed:

SYMBOLGEN:  Macro variable NICKNAME resolves to
                            My name's O'Malley, but I'm called Bruce
SYMBOLGEN:  Some characters in the above value which were
                           subject to macro quoting have been
                           unquoted for printing.
*** My name's O'Malley, but I'm called Bruce ***

You can ignore the unquoting message.

Using the %PUT Statement to Track Problems

Along with using the SYMBOLGEN system option to write the values of macro variables to the SAS log, you may find it useful to use the %PUT statement while developing and debugging your macros. When the macro is finished, you can delete or comment out the %PUT statements. Table 10.3 gives some occasions where you might find the %PUT statement helpful in debugging, and an example of each:

Example %PUT Statements Useful when Debugging Macros
Situation Example
show a macro variable's value %PUT ****&variable-name****;
check leading or trailing blanks in a variable's value %PUT ***&variable-name***;
check double-ampersand resolution, as during a loop %PUT ***variable-name&i = &&variable-name***;
check evaluation of a condition %PUT ***This condition was met.***;

As you recall, macro variables are stored in symbol tables. There is a global symbol table, which contains global macro variables, and a local symbol table, which contains local macro variables. During the debugging process, you may find it helpful on occasion to print these tables to examine the scope and values of a group of macro variables. To do so, use the %PUT statement with one of the following options:
_ALL_ describes all currently defined macro variables, regardless of scope. This includes user-generated global and local variables as well as automatic macro variables.
_AUTOMATIC_ describes all automatic macro variables. The scope is listed as AUTOMATIC. All automatic macro variables are global except SYSPBUFF.
_GLOBAL_ describes all user-generated global macro variables. The scope is listed as GLOBAL. Automatic macro variables are not listed.
_LOCAL_ describes user-generated local macro variables defined within the currently executing macro. The scope is listed as the name of the macro in which the macro variable is defined.
_USER_ describes all user-generated macro variables, regardless of scope. For global macro variables, the scope is GLOBAL; for local macro variables, the scope is the name of the macro.

The following example uses the %PUT statement with the argument _USER_ to examine the global and local variables available to the macro TOTINV. Notice the use of the user-generated macro variable TRACE to control when the %PUT statement writes values to the log.

%macro totinv(var);
   %global macvar;
   data inv;
      retain total 0;
      set sasuser.houses end=final;
      if final then call symput("macvar",put(total,dollar14.2));

   %if &trace = ON  %then
         %put *** Tracing macro scopes. ***;
         %put _USER_;
%mend totinv;

%let trace=ON;
%put *** TOTAL=&macvar ***;

When you submit these statements, the first %PUT statement in the macro TOTINV writes the message about tracing being on and then writes the scope and value of all user generated macro variables to the SAS log.

*** Tracing macro scopes. ***
GLOBAL MACVAR  $1,240,800.00
*** TOTAL= $1,240,800.00 ***

See Chapter 5 for a more detailed discussion of macro variable scope.

Chapter Contents



Top of Page

Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.