If I was in a code walk-through of someone else’s code and found the bug that I just found in my code, I would say “that is some bad programming”. So, I’ll admit it – I’m a bad programmer! 😉
A long time ago, I created a nice logging framework (C code) for Capitalware’s products. I build it so that it would work on ALL platforms. i.e. AIX, HP-UX, IBM i (OS/400), Linux, Solaris, Windows and z/OS. I created it with various log modes: Quiet, Normal, Verbose and Debug.
For the log mode of verbose or debug, the output includes both the source filename (i.e. __FILE__) and source line number (i.e. __LINE__). If you’ve developed C code for awhile, you are probably aware of these C preprocessors.
My logging framework is made up of layers. The “application code” is 2 layers removed from the real logging code (just setting the mood).
For Linux, Unix and Windows, the __FILE__ preprocessor is just the path and file name. For IBM i and z/OS, it is the same concept except the source does not have a file extension and the member is surrounded by bracket. i.e. For z/OS, __FILE__ would be ‘ABC.TEST.C(XYZ)’ where “XYZ” is the source member.
For Linux, Unix and Windows, everything is fine. The code simply finds the last path delimiter (i.e. ‘\’ or ‘/’) and then sets the pointer to be +1 of the address (it points at the first of byte of the filename).
For IBM i and z/OS, the code finds the first bracket and sets the pointer to be +1 of the address. Next, it then finds the last bracket and as a quick and dirty thing that C programmers do, I just changed the right bracket “)” to a NULL. i.e. *p = ‘\0’;
Everything has worked fine for years (many, many years). Someone just deployed a beta of MQCCI for z/OS to their z/OS 2.2.0 LPAR and whenever they turned on debugging, the code would crash with:
+CSQX111E +MQQM CSQXDISP User channel exit error, TCB=007B1318 227 reason=0C4000-00000004 +CSQX599E +MQQM CSQXRESP Channel ORT.TO.HOST.MQCCI ended abnormally CSQY291E CSQXDMPS SDUMPX FAILED, RC=00000B08,MQQM,ABN= 0C4-00000004,LOC=MQCCI .????????+00852 +CSQX111E +MQQM CSQXDISP User channel exit error, TCB=007B1088 304 reason=0C4000-00000004 +CSQX599E +MQQM CSQXRESP Channel ORT.TO.HOST.MQCCI ended abnormally
When I ran MQCCI for z/OS on my LPAR and turned on debugging, everything worked as expected. 🙁
The “????????+00852” gave me a clue. I reviewed the compile map and that hex address (852) was located somewhere in my logging framework. I spent hours and hours trying to find something, anything that would explain the 0C4 (accessing wrong/invalid storage). Then it occurred to me, the pointer that was passed into the logging framework did not point to a copy of the value of “__FILE__” but the actual value of “__FILE__”. Hence, I was modifying a constant which clearly now on the newer z/OS LPAR is read-only storage. That is why my program crashed with an 0C4. 🙁
Hence, I’m a bad programmer!!! You got to call it like it is. 😉
Sooooooooooooooooooo. I need to do builds of all Capitalware products (commercial and ‘Licensed as Free’) for IBM i and z/OS platforms ASAP.
Regards,
Roger Lacroix
Capitalware Inc.