Date: Thu, 3 Jul 2008 14:55:16 +0000
Reply-To: iw1junk@COMCAST.NET
Sender: "SAS(r) Discussion" <SAS-L@LISTSERV.UGA.EDU>
From: Ian Whitlock <iw1junk@COMCAST.NET>
Subject: Re: Debug a macro code, locate where the NOTE is at?
Summary: Character counting is questionable.
#iw-value=1
Data _null_,
Academically interesting, but do you care to try it on
%macro p (n) ;
%local i ;
%do i = 1 %to &n ;
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
%end ;
z = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
%mend p ;
%macro q(m,n) ;
%local i ;
data w ;
%do i = 1 %to &m ;
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
%end ;
%p(&n)
y = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
run ;
%mend ;
options mprint ;
%q(3,6)
The log
188 %q(3,6)
MPRINT(Q): data w ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1 ;
MPRINT(P): z = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
MPRINT(Q): y = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
MPRINT(Q): run ;
NOTE: Missing values were generated as a result of performing an
operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 9:25 1 at 13:11
OOPs, with a slight modification to make the counting easier I
generated.
232 %q(3,6)
MPRINT(Q): data wwwwwwwwwwwwwwwwwwwwwww wwwwwwwww ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(Q): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 10000 ;
MPRINT(P): z = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
MPRINT(Q): y = . * xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ;
MPRINT(Q): run ;
NOTE: Missing values were generated as a result of performing an
operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
1 at 9:25 1 at 13:11
Note that the line and column numbers are consistent, but the number
of characters is not. I am also wondering how I know when a new block
begins.
Ian Whitlock
=============
Date: Thu, 3 Jul 2008 08:20:13 -0500
Reply-To: "data _null_," <datanull@GMAIL.COM>
Sender: "SAS(r) Discussion"
From: "data _null_," <datanull@GMAIL.COM>
Subject: Re: Debug a macro code, locate where the NOTE is at?
Comments: To: iw1junk@comcast.net
In-Reply-To:
<070320080209.9757.486C34C2000D96610000261D220073483005029A06CE9907@co
mcast.net>
Content-Type: text/plain; charset=ISO-8859-1
It is possible to determine the location the (Line):(Column) message
is referring to directly from the log but it requires counting and is
far more difficult than the MFILE method. I can't find the SUG paper
where I learned this but if I ever find it again I will post the
reference. Consider the following LOG.
1813 Data test;
1814 set sashelp.class;
1815 x = . * weight;
1816 run;
NOTE: Missing values were generated as a result of performing an
operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
19 at 1815:10
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.TEST has 19 observations and 6 variables.
1817
1818
1819 %macro test(data=sashelp.class);
1820 Data test;
1821 set &data;
1822 x = . * weight;
1823 run;
1824 %if 0 %then;
1825 Data test;
1826 set &data;
1827 z=.+weight;
1828 run;
1829 %mend test;
1830 options mprint;
1831 %test();
MPRINT(TEST): Data test;
MPRINT(TEST): set sashelp.class;
MPRINT(TEST): x = . * weight;
MPRINT(TEST): run;
NOTE: Missing values were generated as a result of performing an
operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
19 at 1:42
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.TEST has 19 observations and 6 variables.
MPRINT(TEST): Data test;
MPRINT(TEST): set sashelp.class;
MPRINT(TEST): z=.+weight;
MPRINT(TEST): run;
NOTE: Missing values were generated as a result of performing an
operation on missing values.
Each place is given by: (Number of times) at (Line):(Column).
19 at 3:51
NOTE: There were 19 observations read from the data set SASHELP.CLASS.
NOTE: The data set WORK.TEST has 19 observations and 6 variables.
1832 run;
The first open code data step tells us where the offending location is
1815:10 easy no MPRINTing. Then we do similar from macro we learn
that the offending line it 1:42. This refers to "code block" 1
character number 42. (view with fixed font)
1 1
1234567890123456789012345
MPRINT(TEST): Data test; 13
MPRINT(TEST): set sashelp.class; 21
MPRINT(TEST): x = . * weight; 8
MPRINT(TEST): run; ----
42
Then we have macro %IF followed by similar and learn the offending
line is 3:51, code block 3 (the %IF was code block 2) column 51 which
is character number including the characters in code block 2.
1 1
1234567890123456789012345
%if 0 %then; 12
MPRINT(TEST): Data test; 13
MPRINT(TEST): set sashelp.class; 21
MPRINT(TEST): z=.+weight; 5
MPRINT(TEST): run; ----
51
I don't have the counting exactly right, but you get the idea..
I found this all somewhat fascinating given the I had never seen it
documented and wonder how the author learned it. The action is
different when the program is run in batch.
On 7/2/08, Ian Whitlock <iw1junk@comcast.net> wrote:
> Summary: Debugging Macro with MFILE
> #iw-value=2
>
> In SAS version 5 or 6 they dropped trying to maintain line numbers
> in the log for the MPRINT option. The solution to getting line
> numbers is to use the MFILE option with MPRINT. In this case the
> mprint output ready to execute is written to a file with the
fileref,
> MPRINT. The catch is that any code not generated by macro will be
> left out.
>
> Let's look at a simple example.
>
> %macro q ;
> data w ;
> length y $ 5 ;
> set w ;
> y = x ;
> run ;
> %mend q ;
>
> data w ;
> x = 1 ;
> run ;
>
> %q
>
> The DATA step generated by %Q contains a conversion message so we
can
> get that code into a file for execution but the creating DATA step
> will be missing. The simple solution is wrap everything in a macro.
>
> %macro debug ;
>
> %macro q ;
> data w ;
> length y $ 5 ;
> set w ;
> y = x ;
> run ;
> %mend q ;
>
> data w ;
> x = 1 ;
> run ;
>
> %q
>
> %mend debug ;
>
> (This is one case I generally overlook the crime of compiling a
macro
> in a macro execution since it is only for the purpose of debugging.)
>
> Now add
>
> options mprint mfile ;
> filename mprint temp ;
> %look
>
> %inc mprint /source2 ;
>
> The code executes twice so you want to think about doing this with
> very large and expensive runs. The other problem is that the error
> in the first run, under %LOOK, may cause SAS to not execute the
> include file. In this case you need a permanent file and do the
> execution in a separate job. However, for this vexing problem of
> which line causes conversion, that is not the case.
>
> The relevant log is
>
> 27 +data w ;
> 28 +length y $ 5 ;
> 29 +set w ;
> 30 +y = x ;
> 31 +run ;
>
> NOTE: Numeric values have been converted to character values at
the
> places given by: (Line):(Column).
> 30:5
>
> So know we know the crime was committed by
>
> y = x ;
>
> at line number 30.
>
> If one plans a program for testing of independent modules, this sort
> of thing can be very easy to do even with very large and complex
> programs.
>
> If you need more it is described in "Macro Bugs - How to Create,
Avoid
> and Destroy Them" at www2.sas.com/proceedings/sugi30/252-30.pdf
>
> Ian Whitlock
> ================
> Date: Wed, 2 Jul 2008 12:46:35 -0400
> Reply-To: SUBSCRIBE SAS-L Dan <deniseyu001@GMAIL.COM>
> Sender: "SAS(r) Discussion"
> From: SUBSCRIBE SAS-L Dan <deniseyu001@GMAIL.COM>
> Subject: Debug a macro code, locate where the NOTE is at?
>
> Hi. SaSlers:
>
> I have a very complex macro code passed to me. I have something like
> this:
>
> NOTE: Numeric values have been converted to character values at the
> places given by: (Line):(Column). 1086:13 1086:64 NOTE: Character
> values have been converted to numeric values at the places given by:
> (Line):(Column). 1086:6 1086:28
>
> It seems that the log only has the line number ending on 574.
>
> It is not my program. I am not sure what options would take out line
> number in LOG. I do not know what options to pin point the
problematic
> place inside macro.
>
> Thanks for your help.
>
> Dan
>