-
-
Save dancarlosgabriel/75631e5c8d83f3b2915a1666481bc9a3 to your computer and use it in GitHub Desktop.
The inspiration for this Gist came from a client. A piece of code had a long-standing problem where a variable was not initialized. Given the unpredictable nature of uninitialized made the topic hard to approach. This Gist shows how the IBM i Optimizing Translator can be used to find such problems within a dev or test environment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Subject: Using initAuto to find uninitialized variable problems in ILE code | |
-- Author: Scott Forstie | |
-- Date : June, 2023 | |
-- Features Used : This Gist uses SQL PL, INCLUDE, Change Program (CHGPGM) CL command, qsys2.joblog_info, qsys2.program_info, qsys2.qcmdexc, and QSYS2.BOUND_MODULE_INFO | |
-- | |
-- A) Programmers use declared variables and structures to facilitate program logic. | |
-- B) Programmers should always initialize or assign declared variables and structures to contain known and expected values. | |
-- C) Programmers sometime miss step B. | |
-- | |
-- This Gist shows how the IBM i Optimizing Translator can help. | |
-- ILE programs and service programs can be configured to use a supplied numeric value as the default value for any uninitialized automatic program storage. | |
-- | |
-- Licensed Internal Code options (LICOPT) control for initAuto: | |
-- ============================================================= | |
-- Initialize automatic storage to a sequence of bytes all having the specified value in binary representation. | |
-- If InitAuto is not specified, there is no automatic initialization. | |
-- When specifying the InitAuto LICOPT, it should be assigned an unsigned integer in the range 0-255. | |
-- Note: | |
-- 1) This control generates extra code and should only be used for error determination. | |
-- 2) LICOPT applies only to ILE code -- there is no OPM support of LICOPT | |
-- 3) LICOPT can be specified via many commands. This Gist will focus on CHGPGM. | |
-- | |
stop; | |
-- | |
-- Built an ILE C program that simply sends a message to the joblog. | |
-- The message text includes the value of the variable "the_length". | |
-- Note that "the_length" is NOT initialized or assigned a known value. | |
-- | |
cl:addlible qsysinc; | |
cl:CRTSRCPF FILE(COOLSTUFF/QCSRC); | |
cl:addpfm file(COOLSTUFF/qcsrc) mbr(PRINT_IT); | |
insert into COOLSTUFF.qcsrc(srcdta) values | |
('int main(int argc, char **argv) '), | |
('{'), | |
('#include "qp0ztrc.h" /* for Qp0zLprintf */'), | |
('int the_length;'), | |
('Qp0zLprintf("The string length is:%d or in hex:%08X\n", the_length, the_length);'), | |
('}'); | |
-- | |
-- Create the ILE module and Program | |
-- | |
cl: CRTCMOD MODULE(COOLSTUFF/PRINT_IT) SRCFILE(COOLSTUFF/QCSRC) DBGVIEW(*SOURCE); | |
cl: CRTPGM PGM(COOLSTUFF/PRINT_IT) MODULE(*PGM) ACTGRP(*CALLER) ; | |
stop; | |
-- | |
-- Call the program | |
-- | |
cl: call COOLSTUFF/PRINT_IT; | |
stop; | |
-- | |
-- Examine the message that was sent to the joblog: | |
-- | |
select message_text | |
from table ( | |
qsys2.joblog_info('*') | |
) | |
where from_procedure = 'Qp0zVLprintf' | |
order by message_timestamp desc | |
limit 1; | |
stop; | |
-- | |
-- Change Program (CHGPGM) | |
-- ======================= | |
-- https://www.ibm.com/docs/api/v1/content/ssw_ibm_i_75/cl/chgpgm.htm | |
-- | |
-- Change Service Program (CHGSRVPGM) | |
-- ================================== | |
-- https://www.ibm.com/docs/api/v1/content/ssw_ibm_i_75/cl/chgsrvpgm.htm | |
-- | |
-- The Licensed Internal Code options that are currently defined are found here: | |
-- ============================================================================= | |
-- https://www.ibm.com/docs/en/i/7.5?topic=options-currently-defined | |
-- (note: initAuto was not documented at the time this Gist was published, but was deemed safe and available for customer use) | |
-- | |
-- Change the program to have a controlled value for uninitialized automatic storage. | |
-- In this case, the decimal value 91 will be used. | |
-- | |
-- 91 == x'5B' == '01011011'B == the character '$' | |
-- | |
cl: CHGPGM PGM(COOLSTUFF/PRINT_IT) LICOPT('initAuto=91'); | |
stop; | |
-- | |
-- Call the program once more | |
-- | |
cl: call COOLSTUFF/PRINT_IT; | |
stop; | |
-- | |
-- Examine the message that was sent to the joblog: | |
-- Note that if you see ZEROS, its because you got lucky. The variable is uninitialized! | |
-- | |
select message_text | |
from table ( | |
qsys2.joblog_info('*') | |
) | |
where from_procedure = 'Qp0zVLprintf' | |
order by message_timestamp desc | |
limit 1; | |
stop; | |
-- | |
-- What does hex 5B look like in EBCDIC character form? | |
-- | |
values x'5B5B5B5B'; | |
-- | |
-- Returns: $$$$ | |
-- | |
stop; | |
-- | |
-- What is the decimal equivalent to hex 5B? | |
-- | |
values hex(1532713819); | |
-- | |
-- Returns: 5B5B5B5B | |
-- | |
stop; | |
-- | |
-- The BOUND_MODULE_INFO view returns information about modules bound into an ILE program or service program. | |
-- The Licensed Internal Code options that are in use by the module. Contains the null value if no LIC options were used for the module. | |
-- https://www.ibm.com/docs/en/i/7.5?topic=services-bound-module-info-view | |
-- | |
-- | |
-- Which programs have been configured to use initAuto? | |
-- | |
select BOUND_MODULE_LIBRARY, BOUND_MODULE, lic_options, PROGRAM_LIBRARY, PROGRAM_NAME, OBJECT_TYPE | |
from QSYS2.BOUND_MODULE_INFO | |
where PROGRAM_LIBRARY = 'COOLSTUFF' and | |
upper(lic_options) like '%INITAUTO%'; | |
stop; | |
-- | |
-- Remove the InitAuto setting | |
-- | |
cl: CHGPGM PGM(COOLSTUFF/PRINT_IT) LICOPT('*NONE'); | |
stop; | |
-- | |
-- Configure all ILE *PGMs in a library to use initAuto | |
-- | |
select qsys2.qcmdexc('QSYS/CHGPGM PGM(' concat program_library concat '/' concat program_name concat ') LICOPT(''initAuto=91'')') as chgpgm_result | |
from QSYS2.PROGRAM_INFO | |
where PROGRAM_LIBRARY = 'COOLSTUFF' and object_type = '*PGM' and program_type = 'ILE'; | |
stop; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment