GDB reverse execution question

Carl Love cel@us.ibm.com
Fri Jul 2 18:38:41 GMT 2021


GCC maintainers:

I am looking into some GDB regression test failures for reverse mode. 
The specific test I am currently looking at is
gdb/testsuite/gdb.reverse/step-reverse.exp.  I am running the test on a
Power 9 machine with the test compiled with two different versions of
the gcc compiler.

The test runs fine using the distro compiler /usr/bin/gcc  which is gcc
version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04).

The issue occurs with a more recent build I have gcc version 10.3.1.
where the test fails.

Both of the compilers generate the same instruction sequences but the
addresses of the assembly instructions differ slightly.  Note, the
tests are done with the default optimization for gcc.

Inintially the test executes "forward", with record enabled, thru a
couple of functions to the line in main with the label "FINISH TEST". 
The C code statement consists of five assembly instructions as shown
below where I have put in generic addresses 1 to 7 as the actuall
addresses differ slightly for the output of the two compilers:

 /* Test that "step" doesn't */                                                       
   callee();    /* STEP INTO THIS CALL */                                               
 1:   9bc:   c9 fe ff 4b     bl      884 <callee+0x8>                                        
                                                                                        
   /* Test "stepi" */                                                                   
   a[5] = a[3] - a[4]; /* FINISH TEST */     forward execution stops at this C code line       
 2:    ce 01 5f e9     lwa     r10,460(r31)   pc is here, step reverse   (distro compiler)
 3:    d2 01 3f e9     lwa     r9,464(r31)                                             
 4:    50 50 29 7d     subf    r9,r9,r10      New gcc compiler, reverse step from FINISH TEST   
                                               only gets to here not the previous       
                                               source code line                         
 5:    b4 07 29 7d     extsw   r9,r9                                                   
 6:    d4 01 3f 91     stw     r9,468(r31)    pc is here for the "newer gcc compiler"       

   callee();    /* STEPI TEST */                                                        
 7:    b1 fe ff 4b     bl      884 <callee+0x8>    

So as noted above, the distro test stops with PC at address 2 whereas
the newer gcc stops at address 6. Power used to issue groups of up to 4
instructions at a time.  Not sure that Power 9 still does that.  I am
still looking for the details on the instruction issuing on Power 9. 
But if it does still issue in groups, that could explain the difference
in the PC given the different instruction addresses.  I only mention
all this as it is something of note but I don't think is the real
problem.

The issue occurs when the test switches to reverse and then does a
step, in the reverse direction.  In the case of the distro compiler
which is at address 2, the step, in the reverse direction, stops in the
previous line of C code.  However, with the newer gcc the reverse step
from address 6 only gets to address 4 which is still in the "FINISH
TEST" C code line.  The gdb test fails because the step is not at the
"STEP INTO THIS CALL" C code line as is expected.

I have been reading the gdb code in gdb/reverse.c and gdb/record-full.c 
etc. Recording stores the register and memory changes for each executed
instruction.  What I can't find is anything that records the
association of instructions to C code lines.  So when gdb does a
reverse "step" how does it know how many assembly instructions to undo?
I believe gdb uses the debug info to figure out where the next
instruction.  Don't know where/how this is done in the forward
direction.  Again, where/how would gdb make the determination in the
reverse direction to decide where to stop?  I have not been able to
determine that in the code for doing reverse execution that I have been
studying.

The test fails because gdb doesn't unroll enough instructions to get to
the previous source line when the PC is at address 6.  I am wondering
if someone can help me understand how gdb determins where/how to stop
when doing a reverse step?  

Thanks for the help.

                           Carl Love



More information about the Gdb mailing list