This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

cse.c crash bounds overwrite by recent patch



Aha!  I finally got a core-dumping case from electric fence and now the
problem is "much" (hahaha) more obvious.  I don't know what's supposed
to be happening in here, but I am pretty sure it isn't this. :-)

 gen_tstsi_1 gen_tstsi gen_tsthi_1 gen_tsthi gen_tstqi_1 gen_tstqi gen_tstsf_cc gen_tstsf gen_tstdf_cc gen_tstdf gen_tstxf_cc gen_tstxf gen_cmpsi_1 gen_cmpsi gen_cmphi_1 gen_cmphi gen_cmpqi_1 gen_cmpqi gen_cmpxf gen_cmpdf gen_cmpsf gen_cmpxf_cc gen_cmpxf_ccfpeq gen_cmpdf_cc gen_cmpdf_ccfpeq
Breakpoint 4, cse_main (f=0x8065e208, nregs=35, after_loop=0, file=0x82a8550)
    at /play/egcs/gcc/cse.c:8520
8520      reg_tick = (int *) alloca (nregs * sizeof (int));
(gdb) next
8531      bzero ((char *) table, sizeof table);
(gdb) print reg_tick
$9 = (int *) 0x805f0f74

#
# regtick is an array of 35 ints starting at ..74.
#


(gdb) watch reg_tick
Hardware watchpoint 7: reg_tick
(gdb) cont
Continuing.

Breakpoint 5, new_basic_block () at /play/egcs/gcc/cse.c:800
800       bzero ((char *) reg_tick, max_reg * sizeof (int));
(gdb) print reg_tick
$10 = (int *) 0x805f0f74
(gdb) cont
Continuing.
Hardware watchpoint 7: reg_tick

Old value = (int *) 0x805f0f74
New value = (int *) 0x805f0f78
0x8152968 in insert_regs (x=0x8065ed50, classp=0x0, modified=0)
    at /play/egcs/gcc/cse.c:1117
1117          mention_regs (x);


#
# This is new in the mentioned patch.   Notice that the debugger 
# returned the 'wrong' line here.  It's actually 1117 that did the
# increment of reg_tick.   You can find this code in 'cvs diff 
# -D980924 -D980925 cse.c'
# Incrementing an array pointer of an alloca()'ed array seems a little
# funky to me, but sometimes you've gotta do what you've gotta do.
#

(gdb) cont
Continuing.

Breakpoint 5, new_basic_block () at /play/egcs/gcc/cse.c:800
800       bzero ((char *) reg_tick, max_reg * sizeof (int));
(gdb) print reg_tick
$11 = (int *) 0x805f0f78
(gdb) step

Program received signal SIGSEGV, Segmentation fault.
0x800198a1 in memset ()

#
# Unfortunately, new_basic_block doesn't know that reg_tick, the pointer
# to the base of the array of 35 ints, has just been incremented.   So it
# zeros 35 words into base+4 instead of base.    This is bad.
#

>From here, I suspect (ok, I hope :-) you're going to be slapping your
forehead and finding the right thing to do to be obvious.  Whether that
new code in insert_regs shouldn't be firing or the array needs to be
large enough to handle however many items we may shove in into the array
or the bzero needs to be told to cool it or something else completly is
something I'm not likely to figure out.

This presumably never shows up in quite so drastic a manner on gcc
bootstraps becuase alloca is always (unless you try really, really hard)
an intrinsic.

Thanx for the help.

RJL


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]