Originally posted by: BasilTK
Problem:
Clients are facing issues when trying to use the Watch Breakpoint functionality of the IBM Debugger while debugging a COBOL for AIX program. The issue is that the Watch Breakpoint never triggers when it is supposed too.
Description:
Let me begin by briefly describing what Watch Breakpoints are: Watch breakpoints are breakpoints that users can set in the IBM Debugger to monitor changes in the data at a specific memory address.
Watch Breakpoints are triggered when execution changes data in that specific memory address that's being monitored.
I'll take the following COBOL test case as an example:
$ cat test.cbl
IDENTIFICATION DIVISION.
PROGRAM-ID. 'TEST'.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
DATA DIVISION.
WORKING-STORAGE SECTION.
*========================
01 STRUCTURE1.
02 MOB1 PIC S9(9) COMP-3 value 999999999.
02 MSCHL13 PIC X(24).
02 MSCHL14 PIC S9(15) COMP-3.
02 MSCHL14R REDEFINES MSCHL14
PIC X(8).
01 FILLER.
02 FILLER PIC X(5).
02 MSCHL1R PIC S9(15) COMP-3 .
*========================
PROCEDURE DIVISION.
MOVE 6 TO MOB1.
MOVE 88 TO MSCHL1R.
MOVE LOW-VALUE TO MSCHL14R.
GOBACK.
$
For the above test case, you can set a Watch Breakpoint on "MSCHL1R", but will notice that the breakpoint won't get triggered when '88' is moved into MSCHL1R.
Reason:
The reason why the debugger does not trigger the Watch Breakpoint in the above example is because MSCHL1R is an 8 byte variable, but it is not aligned on an 8 byte boundary. This is currently documented in the IBM Debugger documentation shipped with the COBOL for AIX compiler:
https://www.ibm.com/support/knowledgecenter/en/SS6SGM_5.1.0/com.ibm.debug.power.doc/topics/tbpbkpts.html
The above link mentions that: "Watch breakpoints can be added by entering a variable name in the wizard. The variable can be 1, 2, 4, or 8 bytes long. Watch breakpoints that are 2, 4, or 8 bytes long must be aligned on 2-, 4-, or 8- byte boundaries respectively. An auto breakpoint determines the size to monitor based on the size of the variable. The AIX hardware only permits one watchpoint (older AIX hardware may not permit watch breakpoints at all)."
Solution:
A source code change is required to ensure that the FILLER padding for MSCHL1R is on an 8 byte aligned boundary.
In the testcase, we have:
01 FILLER.
02 FILLER PIC X(5).
02 MSCHL1R PIC S9(15) COMP-3 .
where MSCHL1R is an 8 byte variable, but it is not aligned on an 8 byte boundary (Steps on how to find the alignment is mentioned in the "Side Notes" section below).
Therefore a watch breakpoint on it will not work correctly as is; because the use of FILLER may change the alignment of the variable in memory.
In order to make the above variable aligned on an 8 byte boundary, we need to add an extra "02 FILLER PIC X(7)" padding as shown below:
01 FILLER.
02 FILLER PIC X(5).
02 FILLER PIC X(7).
02 MSCHL1R PIC S9(15) COMP-3 .
After setting the appropriate padding, the Watch Breakpoint will now be triggered when '88' is moved into MSCHL1R.
Hope this helps!
Side Note:
How to find the alignment of a variable via the IBM Debugger ?
1) Load your COBOL executable in the IBM debugger
2) Select the 'MSCHL1R' variable and right click on it
3) Select the 'Monitor Memory -> 1 Hex and Character' option
4) You will then see a 'Memory' pane in the debugger showing the memory address of 'MSCHL1R'. The Memory pane shows which address MSCHL1R resides on.
In my screenshot below you will see something like this ie MSCHL1R: 0x20011470 (red box as shown in the screen shot below)
5) Since MSCHL1R is a 8 byte variable, the address you obtain for 'MSCHL1R ' needs to be on a 8 byte aligned memory location for the Watch Breakpoint to work.
In my example for MSCHL1R:
a) In Hex: 0x20011470 MOD 8 = 0
or
b) In Decimal: 536941680 / 8 = 0
