This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch 3.3/3.4/3.5] Fix PR bootstrap/14671
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- To: mark at codesourcery dot com (Mark Mitchell)
- Cc: gcc-patches at gcc dot gnu dot org, gdr at integrable-solutions dot net
- Date: Sun, 18 Apr 2004 16:17:40 -0400 (EDT)
- Subject: Re: [patch 3.3/3.4/3.5] Fix PR bootstrap/14671
> >Yes. I didn't determine exactly where this occurs but I believe it
> >happens in init_alias_analysis. It uses VARRAY_RTX_INIT and VARRAY_GROW.
> >If I read the code correctly, uses_ggc is 1 for a RTX element. As a result,
> >the varray will be allocated using ggc_alloc_cleared.
> >
> >
> That sounds highly plausible. I'd still like to have a more definitive
> understanding. The reason I'm concerned is that introducing GC contexts
> is expensive, and there might be other similar problems elsewhere. I'd
> like to have a walk-through of what goes wrong so that we can think
> about it carefully.
Here's some more information:
This is the rtx that gets poisoned:
(gdb) p debug_rtx (reg_known_value[294])
(plus:DI (reg/f:DI 3 %r3)
(const_int 272 [0x110]))
(gdb) p reg_known_value[294]
$3 = 0x800003fffe830600
As far as I can tell, rtx's for stack variables are never "registered".
By this, I mean that ggc_mark_roots will not mark the above rtx. We
have the following code in ggc_collect:
clear_marks ();
ggc_mark_roots ();
poison_pages ();
When loop_optimize calls ggc_collect and the conditions are right
for a collect, clear_marks clears the mark for the object at
reg_known_value[294]. ggc_mark_roots doesn't remark it. As a
result, the object is poisoned. A pointer to the poisoned objected
is passed to memrefs_conflict_p (the x rtx is (const_int 0)).
I had thought since the failure occurs in stage 3 that there had
to be a miscompilation in stage 2. However, the stage 1 compiler
behaves identically except that we don't get the segfault in
memrefs_conflict_p. In both cases, we have the following rtx
in the y argument:
(gdb) p y
$8 = 0x800003fffe830600
(gdb) p *y
$9 = {code = -23131, mode = 165, jump = 1, call = 0, unchanging = 1,
volatil = 0, in_struct = 0, used = 1, integrated = 0, frame_related = 1,
u = {fld = {{rtint = -1515870811, rtuint = 2779096485,
rtstr = 0xa5a5a5a5a5a5a5a5 <Error reading address 0xa5a5a5a5a5a5a5a5: Bad address>, rtx = 0xa5a5a5a5a5a5a5a5, rtvec = 0xa5a5a5a5a5a5a5a5,
rttype = 2779096485, rt_addr_diff_vec_flags = {min_align = 165,
base_after_vec = 1, min_after_vec = 0, max_after_vec = 1,
min_after_base = 0, max_after_base = 0, offset_unsigned = 1,
scale = 165}, rt_cselib = 0xa5a5a5a5a5a5a5a5,
rtbit = 0xa5a5a5a5a5a5a5a5, rttree = 0xa5a5a5a5a5a5a5a5,
bb = 0xa5a5a5a5a5a5a5a5, rtmem = 0xa5a5a5a5a5a5a5a5,
rtreg = 0xa5a5a5a5a5a5a5a5}}, hwint = {-6510615555426900571}}}
The define for CONSTANT_P is:
#define CONSTANT_P(X) \
(GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ \
|| GET_CODE (X) == CONST_VECTOR \
|| GET_CODE (X) == CONSTANT_P_RTX)
and
extern const enum rtx_class rtx_class[NUM_RTX_CODE];
#define GET_RTX_CLASS(CODE) (rtx_class[(int) (CODE)])
The segfault occurs because we have an out-of-range index for the
array rtx_class:
0x40000000000b2374 <memrefs_conflict_p+532>: ldw,s r20(,r19),r21
(gdb) printf "0x%lx\n",$r19
0x4000000000408c20
(gdb) printf "0x%lx\n",$r20
0xa5a5
(gdb) p *((int *)(0x4000000000408c20 + 4 * 0xa5a5))
Error accessing memory address 0x40000000004322b4: Bad address.
It's just the size of the data section in stage1 that prevents
the segfault.
Ok, so the proposed patch will prevent loop_optimize from poisoning
stuff it shouldn't. However, there are a whole bunch of calls to
ggc_collect in passes.c. I suspect that we should push and pop
the context there instead. If we do that, maybe we don't need the
push and pop in cse.c. We probably still want the push and pop
in tree-optimize to preserve local variables in the nested case.
Dave
--
J. David Anglin dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6602)