On Mon, May 18, 2015 at 10:01 PM, mark maule <mark.maule@oracle.com> wrote:
I have a loop which hangs when compiled with -O2, but runs fine when
compiled with -O1. Not sure what information is required to get an answer,
so starting with the full src code. I have not attempted to reduce to a
simpler test case yet.
Attachments:
bs_destage.c - full source code
bs_destage.dis.O2 - gdb disassembly of bs_destageLoop()
bs_destage.dis+m.O2 - src annotated version of the above
The function in question is bs_destageSearch(). When I compile bs_destage.c
with -O2, it seems that the dgHandle condition at line 741 is being ignored,
leading to an infinite loop. I can see in the disassembly that dgHandle is
still in the code as a 16-bit value stored at 0x32(%rsp), and a running
32-bit copy stored at 0x1c(%rsp). I can also see that the 16 bit version at
0x32(%rsp) is being incremented at the end of the loop, but I don't see
anywhere in the code where either version of dgHandle is being used when
determining if the while() at 741 should be continued.
I'm not very familiar with the optimizations that are done in O2 vs O1, or
even what happens in these optimizations.
So, I'm wondering if this is a bug, or a subtle valid optimization that I
don't understand. Any help would be appreciated.
Note: changing the declaration of dgHandle to be volitile appears to modify
the code sufficiently that it looks like the dgHandle check is honored (have
not tested).
Thanks in advance for any help/advice.
The usual issue with this kind of behavior is out-of-bound accesses of
arrays in a loop
or invoking undefined behavior when signed integer operations wrap.
uint32_t outLun[ BS_CFG_DRIVE_GROUPS ];
and
while ( ( dgHandle < ( BS_CFG_DRIVE_GROUPS + 1 ) ) &&
...
dgDestageOut = bs_destageData.outLun[ dgHandle ];
looks like this might access outLun[BS_CFG_DRIVE_GROUPS] which is
out-of-bounds.
Richard.