Dec 312017
OS/2 debugging tool. This DLL displays info on unexpected errors resulting from unexpected calls to OS/2 functions.
File ERRABORT.ZIP from The Programmer’s Corner in
Category OS/2 Files
OS/2 debugging tool. This DLL displays info on unexpected errors resulting from unexpected calls to OS/2 functions.
File Name File Size Zip Size Zip Type
DEBUG.DLL 16480 6688 deflated
DEBUG.LIB 1024 65 deflated
ERRABORT 938 429 deflated
ERRABORT.C 26609 8488 deflated
ERRABORT.DEF 119 113 deflated
ERRABORT.DOC 10400 3953 deflated
ERRABORT.OBJ 14148 6271 deflated
OS2LOCAL.H 579 334 deflated
TEST.C 3053 1434 deflated
TEST.EXE 8152 3054 deflated
TEST.OBJ 4816 1334 deflated
TESTDBG 243 171 deflated

Download File ERRABORT.ZIP Here

Contents of the ERRABORT.DOC file

errabort.c - A debugging tool for OS/2 programmers.


This DLL is to be called after first calling any OS/2 function and
testing for expected return codes. "Testing for expected return
codes" means, for example, testing for zero (successful completion)
IN EVERY CASE, and testing for errors that your program anticipates
and has code to handle, such as "File not found" when calling
'DosOpen ()'.

Any other error return presumably is one that your program did not
anticipate and cannot properly handle. In that case, a call to this
DLL will result in the display of an error message, and a termination
of your program. The error message includes your program's name,
the name of the function within your program that made the call to an
OS/2 function, the line number where the call to this program originated
(which should be the line immediately following the call to the OS/2
function that returned an unexpected error code), the name of the OS/2
function being called, the number of the error code, and a message
associated with the error code.

If you are not presently testing EVERY OS/2 function call's return
value, then you may be surprised by some of the error messages (and
program aborts) that calls to this program will give you. I have
found return codes that are not documented as being among those
returned by certain functions, for example. In other cases, return
codes that I anticipated (such as 'ERROR_FILE_NOT_FOUND' and
'ERROR_PATH_NOT_FOUND' from 'DosFindFirst ()') were NOT returned;
instead I got 'ERROR_NO_MORE_FILES' (it surprised me; maybe it
wouldn't surprise you).

Since this program is a DLL, it is certainly cheap enough to include
a call to it after every OS/2 call, at least during debugging. I
modify the ERRCHK macro (included as part of this package) to
conditionally generate code depending on the state of a global
debugging flag, which makes it easy to remove the calls.


Example output (produced by included program TEST.C):

Test routine for 'errabort ()' has just begun.

Unexpected error return 18 from OS/2 function "DosFindFirst ()".
"No more files"
Caller program: "test".
Caller function: "main".
Near line number: 32.


Package contents:
ERRABORT.C The complete source code to 'errabort ()'
ERRABORT The makefile for 'errabort ()'
ERRABORT.DEF Definition file to make a DLL
ERRABORT.OBJ My compiled version of ERRABORT.C
DEBUG.DLL The completed DLL containing 'errabort ()'
DEBUG.LIB The IMPLIB containing 'errabort ()'
TEST.C A program that illustrates how to use 'errabort ()'
TESTDBG The makefile for 'test ()'
TEST.OBJ My compiled version of TEST.C
TEST.EXE My linked version of TEST.C
OS2LOCAL.H '#include' file with function prototype and macros


Instructions for using 'errabort ()' with your own programs:

(It may be helpful to print a copy of TEST.C and follow along in it;
very experienced C and OS/2 programmers can probably get all they need
from just that code and the other sources alone, without reading this
section. However, don't be lured into doing that just to PROVE that
you are a very experienced C and OS/2 programmer ...)

You must '#include' the supplied file 'OS2LOCAL.H' in each program that
will call 'errabort ()'. You can of course rename OS2LOCAL.H to
whatever you like, or you can simply incorporate its contents into
your own usually-included local file. OS2LOCAL.H has the function
prototype for 'errabort ()' that will be needed by your program, and
it has the 'ERRCHK ()' macro that automates calling 'errabort ()'.

The 'ERRCHK ()' macro looks like this:

#define ERRCHK(os2name) if (usRC != 0) { \
errabort (pszProgramName, #os2name, \
pszFunctionName, __LINE__, usRC) ; \

You must have the following data elements defined in your program, using
the same data type and name (unless you change the macro):

PSZ pszProgramName ;
PSZ pszFunctionName ;

I declare 'pszProgramName' as a static global, initialized to my program's
name, just for safety; however, I then change it to point to 'argv [0]',
to get the actual execution name.

'pszFunctionName' is declared as a static variable within each function
that might call 'errabort ()', initialized to the name of the function.
'errabort ()' itself supplies '()' when it prints the error message, so
you can save a little static string space by omitting the parentheses.

'usRC' is used as the target of every call to an OS/2 system function,
to receive the return code. After calling the OS/2 function, test
'usRC' for the values that your program is set up to expect and handle,
then write 'ERRCHK (OS2FunctionName)' as the next statement. Note that
the 'ERRCHK' macro is defined in such a way that you can code it either
as if it is a macro, or as if it is a function call (that is, you can
include or omit the terminating semicolon).

The '__LINE__' preprocessor variable used by the macro may not be
available to you, depending on how old or how lousy your compiler is;
Microsoft C 5.1 has it, as did (I believe) 5.0. If it is not available
to you, you will have to change the macro and ERRABORT.C, an exercise
left to the reader.

You may also note that 'ERRCHK' does NOT call 'errabort ()' if 'usRC == 0';
thus, you can simply add the 'ERRCHK' macro after every one of your
existing OS/2 function calls, and it will be benign unless you have
an error that you had previously not known about.

Finally, you may wish to change 'ERRCHK' to do nothing at all unless you
have '#define'd some global debugging variable. In fact, the 'ERRCHK'
that I actually use looks more like this:

#if defined FULL_ERRCHK
#define ERRCHK(os2name) if (usRC != 0) { \
errabort (pszProgramName, #os2name, \
pszFunctionName, __LINE__, usRC) ; \
#define ERRCHK(os2name)
#endif /* #if defined FULL_ERRCHK */

This way, your MAKE file can control the cautiousness of your code, and
thus the quantity of code generated. In practice, though, I have tended
to let 'ERRCHK' generate the call even in "fully-debugged" programs,
because the overhead is really very small, and because I have never
yet been able to write a "fully-debugged" program that does more than
'HELLO.C' is capable of.

Experienced OS/2 programmers may also note that the ERRABORT.DEF module
definition file does not specify an ordinal number as part of the
'EXPORTS' statement. This was a deliberate choice on my part, because
doing so precludes using BIND to create a family-mode application.

(Yes, I sometimes do that, in spite of the fact that in family-mode you
lose all of the benefits that a DLL makes possible, the most obvious of
which is that 'errabort ()' in family mode makes every program you write a
total pig for memory and disk space. It is useful for debugging even
in that environment, though, and it is easily replaced with a routine
that omits the text; alternately, it can be removed altogether for that
mythical "fully-debugged" application, as described above.)

In actual practice, though, 'errabort ()' is just one member of a larger
DLL that I use, and it does have an ordinal in that larger library.
I hope that pointing this out doesn't cause any trauma for chronic
decision-avoiders ... especially since it took me three days to decide
whether to mention it or not ...


Instructions for use of supplied files:

Before you do anything at all, read the source files and the make files
carefully. I am posting this collection of stuff to BIX, and I know
that it is in good condition there. However, it is folly to simply
compile and execute ANYTHING you receive from any source outside your
direct control, without first studying it to verify that it is benign.
This particular program is extremely simple, but if you are unfamiliar
with OS/2 and therefore find that it is not simple for you, have
someone who is take a look at it. (Not someone who is simple; someone
who is familiar with OS/2. Of course, becoming familiar with OS/2 can
make you simple. It worked for me.)

First, examine the MAKE files very carefully, to be certain that you
are not going to write over some of your own important files. In
particular, note that the ERRABORT makefile will do a copy of its
DEBUG.DLL and DEBUG.LIB output to a directory on the C: drive. It
works fine on my system, but it is highly unlikely that it is correct
for yours.

After adjusting the MAKE files appropriately, simply do this:

make errabort
make testdbg
test (or 'cvp test' if you want to use CodeView)

(Note: the sources were created using Brief, and tabs are set at every
four spaces from 9 through 45. This may help you in either editing or
printing these sources.)


This program with all its associated materials is explicitly placed into
the public domain. Feel free to use it, modify it, or incorporate it
into your own programs, whether for your own use or for sale; in short,
enjoy. And if you have something of your own that is useful but was
equally tedious to produce, please share it with the rest of us.

If you have questions or comments about this program, I am:

Author: Wayne Kovsky BIX: wkovsky
Pinnacle Software CompuServe: 76164,3504
299 Village Street
Millis, MA 02054

 December 31, 2017  Add comments

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>