REXX Tips & Tricks:Troubleshooting
his section contains hints for some REXX errors, symptoms, and messages. Note that a lot of hints in this section are captured from CompuServe messages.
In addition to the tips mentioned below I suggest everyone having problems with REXX programs should get the new Object-Oriented REXX. Object-Oriented REXX has much more descriptive error messages and the documentation is better than the normal REXX online documentation.
Another good source for Troubleshooting information is the Common REXX Pitfalls page on the home page of Quercus Systems (see Internet - Web Pages)
Note that the information related to various APARs is included in the sections General hints for REXX, REXXUTIL functions and Change the WPS with REXX. See those sections for additional information.
Here's a list of further sections in REXX Tips & Tricks with information about various errors:
- Errors in OS/2 commands
- CTRL-Break & OS/2 commands
- STDOUT / STDERR
- Using PIPEs
- The CMD command
- The COPY command
- Copying empty files
- The XCOPY command
- General REXX Errors
- DO loops
- The keyword instruction CALL
- The keyword instruction SIGNAL
- The function DIRECTORY()
- The function FILESPEC()
- The functions LINEIN() and PULL()
- The REXX API functions
- The function TIME()
- QUEUE names
- Object REXX Errors
- The function CHARS() in Object REXX
- The function LINEOUT() in Object REXX
- The function LINES() in Object REXX
- The function STREAM() in Object REXX
- The function VALUE() in Object REXX
- The Signal handling in Object REXX
- Errors in REXXUTIL functions
- The function SysCopyObject()
- The function SysCreateObject()
- The function SysFileSearch()
- The function SysIni()
- The function SysQueryClassList()
- The function SysSearchPath()
- WPS related Errors
- Format of the RC files for MAKEINI
- Creating shadows of drive objects
- Changing the LaunchPad
- WPS Object Setup strings (and the sub sections)
Contents
- 1 No light, no sound
- 2 RC = 1041 or RC = 1002
- 3 It runs, runs not, runs, runs not, ...
- 4 What the hell is he doing?
- 5 Haeaeh - Syntax error?
- 6 2 + 2 = 5
- 7 DLL loading failed
- 8 SYS1801
- 9 REX0003: Program is unreadable
- 10 1 +++ @REXX g + ? OS / 2 REXXSAA 6.00 12 Jul 1995
- 11 Error: Failure during initialization
- 12 SYS0008
- 13 SYS0008 - 2 -
- 14 REXX programs without an extension
- 15 SYS0192 or SYS0008 using PIPEs
- 16 SYS0005: Access is denied
- 17 SYS0317: The system cannot find message 32799 in message file OSO001.MSG
- 18 EXPOSE does not work as expected
No light, no sound
- Problem
- The call of a REXX program neither produces the expected result nor an error message.
- Hint
- Check if the file REX.MSG (normally in the directory C:\OS2\SYSTEM) is in a directory included in the environment variable DPATH. This file contains the error messages for the REXX Interpreter.
RC = 1041 or RC = 1002
- Problem
- The call of an OS/2 program leads to the error code SYS1041 or SYS1002, although the called OS/2 program is available through the environment variable PATH.
- Hint
- Check the value of the environment variable COMSPEC.
It runs, runs not, runs, runs not, ...
- Problem
- A REXX program works sometimes and sometimes not.
- Hint
- If the program uses file I/O, check if you're closing all opened files. The number of file handles is limited in an OS/2 session. (see MaxFH on how to increase the number of file handles; see lsof for getting a list of all open files)
Please note that the entry FILES=nn in the file CONFIG.SYS is only valid for DOS sessions!
What the hell is he doing?
- Problem
- The results of a REXX program aren't as expected.
- Hint
- Turn the NOVALUE condition on. (see SIGNAL)
Haeaeh - Syntax error?
- Problem
- The execution of a REXX program leads to mysterious syntax errors.
- Hint
- Check the file for unbalanced comment chars. A simple way to do that is: Use the find-and-replace-function of your editor to replace the string "/*" with "/*" and the string "*/" with "*/". The number of changes for both calls should be equal. If not, there's an unbalanced comment in your file.
- Another method to detect unbalanced comment chars: Use an editor with syntax highlighting.
See also: Using comments
2 + 2 = 5
- Problem
- The results of mathematical expressions aren't as expected.
- Hint
- Change the NUMERIC settings to a greater value.
DLL loading failed
- Problem
- The call of RxFuncAdd failed although the DLL to load is accessible through the LIBPATH.
- Hint
- For some DLLs the name of the DLL function to register (this is the third parameter for RxFuncAdd) is case-sensitive! This depends on how the DLL was linked.
- Use an ExeHdr tool or take a look at the DLL with a Hex-viewer to get the proper spelling for the name of the register function.
- Another cause for this error:
- Maybe the DLL needs some other DLLs - these DLLs must also be accessible through the LIBPATH.
- To check which other DLLs the DLL need, you can use the excellent program PMDLL. or IBM's chkdll32.exe.
See also: The REXX API functions
SYS1801
- Problem
- The execution of a REXX program leads to the error SYS1801 although REXX support is installed.
- Hint
- Maybe the EAs are corrupted. Try a CHKDSK /F on the drive where the REXX program resides.
REX0003: Program is unreadable
- Problem
- Calling a REXX cmd leads to the error message Program is unreadable.
- Hint
- This error is generated if a CMD file called with the CALL statement is locked or deleted by another process. You'll get this error also if the function name for a CALL statement is a directory name or a device name (e.g. call con, see Reserved directory & file names). The above is also true for function calls. (see also #REXX programs without an extension and #Error: Failure during initialization)
1 +++ @REXX g + ? OS / 2 REXXSAA 6.00 12 Jul 1995
- Problem
- The call of a REXX cmd leads to an error message like
1 +++ @REXX g + ? OS / 2 REXXSAA 6.00 12 Jul 1995 ( P ? + §? ?? REX0013: Error 13 running E:\DATEN\DFUE\DOWNLOAD\TEST\OREXXTRY.CMD, line 1: Invalid character in program
- Hint
- You tried to run a tokenized Object-Oriented REXX program under the normal REXX interpreter. You need Object-Oriented REXX to run this program (see also #"Compiling" REXX programs and #Error: Failure during initialization)
Error: Failure during initialization
- Problem
- The call of an EXE program containing REXX code leads to the error message
REX0003E: Error 3: Failure during initialization REX0200E: Error 3.1: Failure during initialization: File "%1" is unreadable
- Hint
- You tried to run a tokenized Classic REXX program under Object-Oriented REXX. Object-Oriented REXX cannot execute token images of REXX programs created with Classic REXX. EXEs with token images are created by some of the GUI environments for REXX or by #RxCLS - a REXX 'compiler' ($). You may try to load the Classic REXX interpreter prior to calling the REXX program causing this error (see #Using Classic REXX if Object REXX is the default REXX; see also #REX0003: Program is unreadable)
SYS0008
- Problem
- There seems to be a bug in REXX which leads to the error SYS0008 if you repeatedly call an OS/2 command in a REXX program. (see the #Example for the SYS0008 error)
- Hint
- To avoid this problem use equivalent REXX functions where possible. If there's no such REXX function, you can create a new session every # calls. (see the #Workaround for the SYS0008 error). Note that this is only a workaround - not a solution!
(see also #SYS0008 - 2 -)
Example for the SYS0008 error
/* example program to generate a SYS0008 error */ /* This program generates a SYS0008 error after about 90 rounds if */ /* the file TATA.TXT does not exist */ /* see also the Workaround */ "C:" "CD \" "MD C:\TOTO" "MD C:\TOTO\TOTO" "MD C:\TOTO\TOTO\TOTO" "CD C:\TOTO\TOTO\TOTO" CHEMIN = "TATA\TATA\TATA.TXT" do i = 1 to 100 /* this DIR command causes the SYS0008 error */ /* after about 40 to 80 rounds */ "DIR "CHEMIN if RC = 0 then say "OK" else say i end /* do i = 1 to 100 */ exit
Workaround for the SYS0008 error
/* workaround for the SYS0008 error */ /* get the current round count and session no. */ parse arg round sessionNo if round = "" then round = 1 /* initial value is 1 */ if sessionNo = "" then sessionNo = 1 /* initial value is 1 */ /* get the name of this program */ parse source . . thisProg if sessionNo = 1 then do /* do initialisations only once */ "C:" "CD \" "MD C:\TOTO" "MD C:\TOTO\TOTO" "MD C:\TOTO\TOTO\TOTO" "CD C:\TOTO\TOTO\TOTO" end /* if sessionNo = 1 then */ CHEMIN = "TATA\TATA\TATA.TXT" /* this is an endless loop! */ do i = round if i // 40 = 0 then do /* start a new session every 40 rounds */ /* You may use additional parameters or a private */ /* queue to pass global variables to the next */ /* pass */ "start /c /f " thisProg i+1 sessionNo+1 /* close this session */ "exit" end /* if i // 40 = 0 then */ /* execute the needed OS/2 commands */ "DIR "CHEMIN ">NUL" /* process the results here */ say "session: " || sessionNo || ", round " || i || " --> RC = "rc end /* do i = round */ exit
SYS0008 - 2 -
- Problem
- Passing a null string as a command (which is not a valid command) to the CMD interpreter will return the SYS0008 error message after the 32nd iteration.
Example:
/* example for the SYS0008 bug */ do i=1 to 33 /* the next stmt returns a */ /* null string to the CMD */ /* which leads to the */ /* SYS0008 error after the */ /* 32nd execution. */ Beep(220,250) say "i is " || i || ", rc is " || RC end /* do i=1 to 33 */
Note that you can replace the statement Beep(220,250) with every other statement returning a null string - even with a function defined in your REXX program!
This seems to be an OS/2 interpreter bug. Note that 4OS2 does handle this situation correctly.
- Hint
- Do not use a function returning a null string this way (see also SYS0008).
This bug seems to be fixed in WARP 4 Fixpak #5.
REXX programs without an extension
- Problem
- The REXX interpreter executes an external procedure from a file with any or without an extension and/or without the leading comment normally necessary for REXX programs.
- Hint
- There's a bug in the OS/2 WARP REXX interpreter which allows the use of files with any extension or without an extension for external REXX procedures. These files also don't need the leading comment.
- Note that if there's a directory with the name of the external REXX procedure prior to the REXX procedure in your PATH, REXX tries to "execute" the directory and fails with the error REX0003 - Program is unreadable.
- This bug was fixed in the WARP 3 FixPak #8 (Source: APAR PJ19105) - and is again there after WARP 3 FixPak #17. It's still there in WARP 4. And again fixed in Fixpak #6 for WARP 4.
SYS0192 or SYS0008 using PIPEs
- Problem
- An OS/2 command with two or more PIPEs (|) leads to the OS/2 error message SYS0192 or SYS0008.
- Hint
- The number of PIPEs in one command is limited in OS/2. See Using PIPEs for a workaround.
SYS0005: Access is denied
- Problem
- Trying to create a directory or file leads to the OS/2 error message SYS0005. although there's no file or directory with this name and you have write access to the drive.
- Hint
- Maybe you're using the name of a device driver for the file or directory to create. Check the list of the installed device driver - or use the code provided in Check if a name describes a device or a file to check if the name you're using is the name of an existing device. (see also Reserved directory & file names)
SYS0317: The system cannot find message 32799 in message file OSO001.MSG
- Problem
- Copying a file to a FAT-formatted media fails with the error message SYS0317:The system cannot find message 32799 in message file OSO001.MSG
- Hint
- This error occurs if OS/2 has problems with the EAs on the target drive. To solve the problem, you can try to do a CHKDSK drive /F (where drive is the drive specifier, e.g. C: or D:) on the target drive but that may not solve the problem in all cases.
A method that works in all cases is to remove the EAs from the source file (using EAUTIL sourceFile nul /s)
EXPOSE does not work as expected
- Problem
- You find that a variable used in the EXPOSE statement of a procedure is not visible in your routine.
- Hint
- There's a bug in the processing of the EXPOSE statement in Classic REXX (not in Object-Oriented REXX!):
- If you expose a stem variable directly in the EXPOSE statement and also in a variable list in parentheses the order of the parameter for the EXPOSE statement is important. Try the example below to see what I mean.
- To avoid this bug, you should always specify variable lists before variable names for EXPOSE statements
E.g. use
test: PROCEDURE expose (myVarList1) (myVarList2) myVar3 myVar4
instead of
test: PROCEDURE expose myVar3 myVar4 (myVarList1) (myVarList2)
(see also The keyword instruction EXPOSE)
/* sample code to show the bug in the processing of the EXPOSE */ /* statement in Classic REXX */ /* define some variable lists for the EXPOSE */ /* statement */ exposeList = 'test1. test2. test3.' exposeList1 = 'test1. testVar test2. test3.' /* define some variables for the EXPOSE */ /* statement */ testVar = 'Testing...' test1.0 = 2 test1.1 = 'T1_1' test1.2 = 'T1_2' test2.0 = 2 test2.1 = 'T2_1' test2.2 = 'T2_2' test3.0 = 2 test3.1 = 'T3_1' test3.2 = 'T3_2' /* show the values of the variables in the main */ /* procedure */ say 'Now in Main:' call ShowVariables /* now call the various subroutines with */ /* different EXPOSE statements. */ /* Note that all global variables should be */ /* available in all subroutines! */ call TestProc1 call TestProc2 call TestProc3 call TestProc4 return
TestProc1: PROCEDURE expose (exposeList) test2. test1. testVar say 'Now in TESTPROC1: PROCEDURE expose (exposeList) test2. test1. testVar' call ShowVariables return TestProc2: PROCEDURE expose test1. (exposeList) TestVar say 'Now in TESTPROC2: PROCEDURE expose test1. (exposeList) TestVar' call ShowVariables return TestProc3: PROCEDURE expose test2. (exposeList1) say 'Now in TESTPROC3: PROCEDURE expose test2. (exposeList1) ' call ShowVariables return TestProc4: PROCEDURE expose test1. (exposeList1) say 'Now in TESTPROC4: PROCEDURE expose test1. (exposeList1) test2. TestVar' call ShowVariables return /* sample routine to show the value of all global variables */ ShowVariables: if datatype( test1.0 ) = 'NUM' then do do i = 0 to test1.0 call CharOut, 'test1.' || i || ' is "' || test1.i || '" ' end say end else say 'test1.0 is "' || test1.0 || '" (= NOT DEFINED!!!)' if datatype( test2.0 ) = 'NUM' then do do i = 0 to test2.0 call CharOut, 'test2.' || i || ' is "' || test2.i || '" ' end say end else say 'test2.0 is "' || test2.0 || '" (= NOT DEFINED!!!)' if datatype( test3.0 ) = 'NUM' then do do i = 0 to test3.0 call CharOut, 'test3.' || i || ' is "' || test3.i || '" ' end say end else say 'test3.0 is "' || test3.0 || '" (= NOT DEFINED!!!)' say 'TestVar is "' || testVar || '"' return
Here is the result from the code above executed under Classic REXX:
Now in Main: test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "2" test3.1 is "T3_1" test3.2 is "T3_2" TestVar is "Testing..." Now in TESTPROC1: PROCEDURE expose (exposeList) test2. test1. testVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "2" test3.1 is "T3_1" test3.2 is "T3_2" TestVar is "Testing..." Now in TESTPROC2: PROCEDURE expose test1. (exposeList) TestVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "TEST2.0" (= NOT DEFINED!!!) test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "Testing..." Now in TESTPROC3: PROCEDURE expose test2. (exposeList1) test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "2" test2.1 is "T2_1" test2.2 is "T2_2" test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "Testing..." Now in TESTPROC4: PROCEDURE expose test1. (exposeList1) test2. TestVar test1.0 is "2" test1.1 is "T1_1" test1.2 is "T1_2" test2.0 is "TEST2.0" (= NOT DEFINED!!!) test3.0 is "TEST3.0" (= NOT DEFINED!!!) TestVar is "TESTVAR"