| More information & example:
Host: AlphaStation 200 4/100
OpenVMS: v6.2-1H1
Compiler: DEC PL/I v4.1-1
Submitter: Ed Walawender, MASCA, (206) 841-6027
Problem: A source file including callable FMS does not run properly when the
source file was compiled in the default /OPTIMIZE mode. Compiling
the source file in /NOOPTIMIZE allows the application to run. Linking
the object file with either /NATIVE or /NONATIVE produces the same
result.
Is the /OPTIMIZE qualifier otherwise reliable for application
development?
Compile command:
Compile command:
$ PLI /LIST /CHECK FMS_TEST , SYS$LIBRARY:PLI$STARTLET/LIB
Link command:
Link command:
$ LINK FMS_TEST
SYS$ERROR output:
SYS$ERROR output:
%PLI-F-ERROR, PL/I ERROR condition.
-SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=00000000,
PC=8043EE2C, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
Image Name Module Name Routine Name Line Number rel PC abs PC
DPLI$RTLSHR 0 0006867C 0015C67C
DPLI$RTLSHR 0 00051F28 00145F28
DPLI$RTLSHR 0 00051CB8 00145CB8
DPLI$RTLSHR 0 0006C758 00160758
----- above condition handler called with exception 0000000C:
%SYSTEM-F-ACCVIO, access violation, reason mask=00, virtual address=00000000,
PC=8043EE2C, PS=0000001B
----- end of exception message
0 8486C2BC 8486C2BC
0 8043EE2C 8043EE2C
FDVSHR FDV$PLIDIS RETURN_ARGS 984 00000A58 000A07D8
FDVSHR FDV$PLIDIS FDV$$PLIDISPATC 524 000003CC 000A014C
FDVSHR FDV$PLINTR FDV$GETAL 158 00003B48 00096838
FMS_TEST SCRAPRPT FORMS 407 000003A8 000303A8
FMS_TEST SCRAPRPT SCRAPRPT 416 00000088 00030088
0 84966170 84966170
Source file:
Source file:
ScrapRpt: PROCEDURE OPTIONS(MAIN);
DCL Oper Char(8) init(' ');
DCL Tday Char(6);
DCL (StartDate,NextDate,EndDate,BadDate) Char(6);
Forms: PROCEDURE(Tday);
%INCLUDE 'FMS$EXAMPLES:FDVDEFCAL.PLI';
DCL WorkSpace(3) Fixed Bin(31);
DCL TCA(3) Fixed Bin(31);
DCL Loc_Form(200) Fixed Bin(31);
DCL FMS_Status Fixed Bin(31);
DCL RMS_Status Fixed Bin(31);
DCL Size Fixed Bin;
DCL Term Fixed Bin(31);
DCL Tday Char(6);
DCL FieldVal Char(56);
CALL FDV$ATERM(TCA,12,2);
CALL FDV$STAT(FMS_Status,RMS_Status);
CALL FDV$SSRV(FMS_Status,RMS_Status);
CALL FDV$AWKSP(WorkSpace,900);
CALL FDV$LOPEN('INC$FMS:SITE',1);
CALL FDV$SSIGQ(0);
CALL FDV$SPADA(1);
CALL FDV$READ('Scrap',Loc_Form,900,Size);
CALL FDV$CDISP('Scrap');
CALL FDV$GETAL(FieldVal,Term);
CALL FDV$LCLOS;
CALL FDV$DWKSP(WorkSpace);
CALL FDV$DTERM(TCA);
End Forms;
Tday = '970122';
Call Forms(Tday);
End ScrapRpt;
Form definition file:
Form definition file:
! FMS Form Description Application Aid
! Version V2.4
FORM NAME='SCRAP'
AREA_TO_CLEAR=1:23
WIDTH=CURRENT
BACKGROUND=CURRENT
;
TEXT (1,1) 'Scrap Reports'
BOLD REVERSE
;
TEXT (1,20) 'Employee'
;
TEXT (1,39) 'Date'
;
TEXT (1,57) 'Time'
;
TEXT (2,1) 80' '&''
UNDERLINE
;
TEXT (4,35) 'Enter Dates'
;
TEXT (5,26) 'lqqqqqqqqqqqqqqqqqqqqqqqqqqqqk'
CHARACTER_SET=RULE
;
TEXT (6,26) 'x'
CHARACTER_SET=RULE
;
TEXT (6,55) 'x'
CHARACTER_SET=RULE
;
TEXT (7,26) 'x'
CHARACTER_SET=RULE
;
TEXT (7,31) 'Enter Starting Date'
;
TEXT (7,55) 'x'
CHARACTER_SET=RULE
;
TEXT (8,26) 'x'
CHARACTER_SET=RULE
;
TEXT (8,55) 'x'
CHARACTER_SET=RULE
;
TEXT (9,26) 'x'
CHARACTER_SET=RULE
;
TEXT (9,29) 'Month'
;
TEXT (9,38) 'Day'
;
TEXT (9,45) 'Year'
;
TEXT (9,55) 'x'
CHARACTER_SET=RULE
;
TEXT (10,26) 'x'
CHARACTER_SET=RULE
;
TEXT (10,55) 'x'
CHARACTER_SET=RULE
;
TEXT (11,26) 'x'
CHARACTER_SET=RULE
;
TEXT (11,32) 'Enter Ending Date'
;
TEXT (11,55) 'x'
CHARACTER_SET=RULE
;
TEXT (12,26) 'x'
CHARACTER_SET=RULE
;
TEXT (12,55) 'x'
CHARACTER_SET=RULE
;
TEXT (13,26) 'x'
CHARACTER_SET=RULE
;
TEXT (13,29) 'Month'
;
TEXT (13,38) 'Day'
;
TEXT (13,45) 'Year'
;
TEXT (13,55) 'x'
CHARACTER_SET=RULE
;
TEXT (14,26) 'x'
CHARACTER_SET=RULE
;
TEXT (14,55) 'x'
CHARACTER_SET=RULE
;
TEXT (15,26) 'mqqqqqqqqqqqqqqqqqqqqqqqqqqqqj'
CHARACTER_SET=RULE
;
TEXT (16,34) 'Choose Report'
;
TEXT (17,26) 'lqqqqqqqqqqqqqqqqqqqqqqqqqqqqk'
CHARACTER_SET=RULE
;
TEXT (18,26) 'x'
CHARACTER_SET=RULE
;
TEXT (18,55) 'x'
CHARACTER_SET=RULE
;
TEXT (19,26) 'mqqqqqqqqqqqqqqqqqqqqqqqqqqqqj'
CHARACTER_SET=RULE
;
TEXT (20,41) 'LOT_IDS '
BOLD
;
TEXT (22,1) 'RETURN OP_CODE(5) LOCATION &'
BOLD
;
TEXT (22,30) 'WORKAREA(6) EQUIPMENT(7) EMPLOYEE(8) PRODUCT(9) '
BOLD
;
TEXT (23,22) 'INCLUDE LOT_IDS(1) EXCLUDE LOT_IDS(2) '
BOLD
;
ATTRIBUTE_DEFAULTS FIELD
CLEAR_CHARACTER=' '
NOAUTOTAB BLANK_FILL NOBLINKING NOBOLD NOREVERSE
NOUNDERLINE NODISPLAY_ONLY ECHO NOFIXED_DECIMAL
LEFT_JUSTIFIED NOSUPERVISOR_ONLY NOSUPPRESS NOUPPERCASE
;
FIELD NAME='EMPNUM' (1,29)
PICTURE=6'X'
DISPLAY_ONLY BOLD
;
FIELD NAME='DATE' (1,44)
DATE_FIELD='99/99/99'
DISPLAY_ONLY BOLD
;
FIELD NAME='TIME' (1,62)
TIME_FIELD='99:99:99'
DISPLAY_ONLY BOLD
;
FIELD NAME='MON1' (9,35)
PICTURE=2'9'
HELP='Enter a 2 digit month, e.g., 02 for February'
AUTOTAB BOLD REVERSE
;
FIELD NAME='DAY1' (9,42)
PICTURE=2'9'
HELP='Enter a day'
AUTOTAB BOLD REVERSE
;
FIELD NAME='YEAR1' (9,50)
PICTURE=2'9'
HELP='Enter the last two digits in the year, e.g., 84 for 1984'
AUTOTAB BOLD REVERSE
;
FIELD NAME='MON2' (13,35)
PICTURE=2'9'
AUTOTAB BOLD REVERSE
;
FIELD NAME='DAY2' (13,42)
PICTURE=2'9'
AUTOTAB BOLD REVERSE
;
FIELD NAME='YEAR2' (13,50)
PICTURE=2'9'
BOLD REVERSE
;
FIELD NAME='RPT' (18,31)
PICTURE=19'X'
DISPLAY_ONLY BOLD
;
FIELD NAME='INEX' (20,33)
PICTURE=7'X'
DEFAULT='INCLUDE'
DISPLAY_ONLY BOLD
;
ORDER BEGIN_WITH = 1
NAME='EMPNUM'
NAME='DATE'
NAME='TIME'
NAME='MON1'
NAME='DAY1'
NAME='YEAR1'
NAME='MON2'
NAME='DAY2'
NAME='YEAR2'
NAME='RPT'
NAME='INEX'
;
END_OF_FORM NAME='SCRAP' ;
|
| I remember Ed from my CSC days. Did he let his support
contract expire? The CSC has STARS articles they could send
him, such as
FMS: Compiler Optimizer Produces Runtime Form Driver "ACCVIO"
(see below), which discussed this. If he wants to use
/OPTIMIZE he might try declaring the variables passed to
FDV$SSRV as STATIC.
Dan
FMS: Compiler Optimizer Produces Runtime Form Driver "ACCVIO"
Any party granted access to the following copyrighted information
(protected under Federal Copyright Laws), pursuant to a duly executed
Digital Service Agreement may, under the terms of such agreement copy
all or selected portions of this information for internal use and
distribution only. No other copying or distribution for any other
purpose is authorized.
Copyright (c) Digital Equipment Corporation 1989. All rights reserved
LAYERED PRODUCT: FMS, V2.4 OP/SYS: VMS, Version 5.1
SOURCE: Digital Customer Support Center
SYMPTOM:
A program that performs FMS status checking through a call to FDV$SSRV
later attempts to execute a form driver call, such as FDV$GETAL, which
generates an access violation before returning to the calling program.
However, if the program is compiled /NOOPTIMIZE (which in most programming
languages is not the default), there is no access violation and the call
executes successfully.
ANALYSIS:
The FDV$SSRV call establishes variables which receive FMS status codes from
the form driver after each form driver call. If those variables are not
accessed elsewhere in the program, the compiler optimizer may optimize them
away. As a result, the form driver does not have a valid address in which to
store the status codes. This means that at unexpected times, such as upon
completion of certain form driver calls, the form driver may attempt to
access an invalid virtual address, and as a result abort the program with
an access violation.
As an example, consider the following PASCAL program, which contains an
FDV$GETAL call. The expected behavior is that if the operator modifies the
contents of a field during input, the call should return a value of 3 into
the status variable established previously by FDV$SSRV. However, by default,
PASCAL compilation includes the /OPTIMIZE qualifier; as a result, after the
execution of the FDV$GETAL call this program will abort with an access
violation.
PROGRAM EXAMPLE:
[inherit('fms$examples:fdvdef')] PROGRAM x;
var
term_control_area : array[1..3] of integer;
term_control_area_size : integer := 12;
form_workspace : array[1..3] of integer;
form_workspace_size : integer := 12;
fms_status : integer;
rms_status : integer;
logical_unit : integer := 10;
fldval : packed array[1..50] of char;
fldtrm : integer;
begin
FDV$ATERM(TERM_CONTROL_AREA, TERM_CONTROL_AREA_SIZE, 2);
FDV$AWKSP(FORM_WORKSPACE, FORM_WORKSPACE_SIZE);
FDV$SSRV(FMS_STATUS, RMS_STATUS);
FDV$LOPEN('x.flb', LOGICAL_UNIT);
FDV$CDISP('x');
FDV$GETAL(FLDVAL, FLDTRM);
end.
SOLUTION:
A solution is to access the status variables in your source code, such as
by checking their contents after each form driver call (which is presumably
the reason for calling SSRV in the first place). By referring to these
variables elsewhere in the source code, the compiler will not optimize them
away, thus insuring that they will have valid addresses at run time.
Alternatively, the SSRV call can be removed and an alternate method of status
checking can be used in its place.
For example, modifying the above PASCAL program to include a status check
after the GETAL form driver call will eliminate the access violation, as
follows:
[inherit('fms$examples:fdvdef')] PROGRAM x(OUTPUT);
var
term_control_area : array[1..3] of integer;
term_control_area_size : integer := 12;
form_workspace : array[1..3] of integer;
form_workspace_size : integer := 12;
fms_status : integer;
rms_status : integer;
logical_unit : integer := 10;
fldval : packed array[1..50] of char;
fldtrm : integer;
begin
FDV$ATERM(TERM_CONTROL_AREA, TERM_CONTROL_AREA_SIZE, 2);
FDV$AWKSP(FORM_WORKSPACE, FORM_WORKSPACE_SIZE);
FDV$SSRV(FMS_STATUS, RMS_STATUS);
FDV$LOPEN('x.flb', LOGICAL_UNIT);
FDV$CDISP('x');
FDV$GETAL(FLDVAL, FLDTRM);
IF FMS_STATUS < 0 THEN
WRITELN('Error = ',FMS_STATUS);
end.
|