> > I'm seeing a seg fault due to extending a vector in the middle of > a vector iteration loop. This occurs during bootstrap on an > i686-pc-linux-gnu > system with the default vector length reduced to 2 and the vector length > and alloc fields set to unsigned short. > > It's very sensitive to the command line options, indeed the regular trick > of -save-temps and feeding the .i file into cc1 fails to elicit the fault. > > run -quiet -v -I. -I. -I../../gcc/gcc -I../../gcc/gcc/. > -I../../gcc/gcc/../include > -I../../gcc/gcc/../libcpp/include -iprefix > /home/nathan/egcs/HEAD/memory/gcc/stage1/../lib/gcc/i686-pc-linux-gnu/4.0.0/ > -isystem ./include -DIN_GCC -DHAVE_CONFIG_H ../../gcc/gcc/cfgloopmanip.c > -quiet > -dumpbase cfgloopmanip.c -mtune=pentiumpro -auxbase-strip cfgloopmanip.o > -g -O2 > -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic > -Wno-long-long -Wno-variadic-macros -Wold-style-definition -Werror -version > -fomit-frame-pointer -fno-common > > Here is the stack traceback, > > #0 0x081d8bb0 in VEC_edge_reserve (vec_=0x403da16c, alloc_=-1, > _loc_name=0x85eea2a "../../gcc/gcc/cfg.c", _loc_line=273, > _loc_function=0x85eea8e "unchecked_make_edge") at > ../../gcc/gcc/basic-block.h:177 > #1 0x081d8a20 in VEC_edge_safe_insert (vec_=0x403da16c, ix_=0, > obj_=0x409679d8, file_=0x85eea2a "../../gcc/gcc/cfg.c", > line_=273, function_=0x85eea8e "unchecked_make_edge", > _loc_name=0x85eea2a "../../gcc/gcc/cfg.c", _loc_line=273, > _loc_function=0x85eea8e "unchecked_make_edge") at > ../../gcc/gcc/basic-block.h:177 > #2 0x081d67a8 in unchecked_make_edge (src=0x403da15c, dst=0x40360a6c, > flags=1) at ../../gcc/gcc/cfg.c:273 > #3 0x081d6906 in cached_make_edge (edge_cache=0x0, src=0x403da15c, > dst=0x40360a6c, flags=1) at ../../gcc/gcc/cfg.c:321 > #4 0x081d6984 in make_edge (src=0x403da15c, dest=0x40360a6c, flags=1) at > ../../gcc/gcc/cfg.c:335 > #5 0x081ec42b in force_nonfallthru_and_redirect (e=0x409c9a68, > target=0x403ba488) at ../../gcc/gcc/cfgrtl.c:1136 > #6 0x081ec595 in rtl_redirect_edge_and_branch_force (e=0x409c9a68, > target=0x403ba488) at ../../gcc/gcc/cfgrtl.c:1198 > #7 0x084d1d54 in redirect_edge_and_branch_force (e=0x409c9a68, > dest=0x403ba488) at ../../gcc/gcc/cfghooks.c:296 > #8 0x081dc443 in try_forward_edges (mode=41, b=0x403da15c) at > ../../gcc/gcc/cfgcleanup.c:590 > #9 0x081df775 in try_optimize_cfg (mode=41) at > ../../gcc/gcc/cfgcleanup.c:1986 > #10 0x081df9b8 in cleanup_cfg (mode=41) at ../../gcc/gcc/cfgcleanup.c:2098 > #11 0x084d9235 in rest_of_handle_jump2 () at ../../gcc/gcc/passes.c:1437 > #12 0x084d963e in rest_of_compilation () at ../../gcc/gcc/passes.c:1651 > #13 0x080fd69d in execute_one_pass (pass=0x8673c80) at > ../../gcc/gcc/tree-optimize.c:503 > #14 0x080fd78a in execute_pass_list (pass=0x8673c80) at > ../../gcc/gcc/tree-optimize.c:538 > #15 0x080fda46 in tree_rest_of_compilation (fndecl=0x407895e4, nested_p=0 > '\0') at ../../gcc/gcc/tree-optimize.c:638 > #16 0x0806a450 in c_expand_body (fndecl=0x407895e4) at > ../../gcc/gcc/c-decl.c:6323 > #17 0x0850a24a in cgraph_expand_function (node=0x408095e4) at > ../../gcc/gcc/cgraphunit.c:1046 > #18 0x0850deee in cgraph_expand_all_functions () at > ../../gcc/gcc/cgraphunit.c:2728 > #19 0x0850e2cb in cgraph_optimize () at ../../gcc/gcc/cgraphunit.c:2839 > #20 0x0806cbe7 in c_write_global_declarations () at > ../../gcc/gcc/c-decl.c:7293 > #21 0x08497974 in compile_file () at ../../gcc/gcc/toplev.c:998 > #22 0x08499341 in do_compile () at ../../gcc/gcc/toplev.c:2069 > #23 0x084993a8 in toplev_main (argc=37, argv=0xbffff114) at > ../../gcc/gcc/toplev.c:2101 > #24 0x080d1e8a in main (argc=37, argv=0xbffff114) at ../../gcc/gcc/main.c:35 > > > As you'll see cleanup_cfg is looping over the edges of a block using > the edge iterators > for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); ) > { ...} > but in that loop b->succs is reallocated, so the iterator ei ends up with > a stale pointer. > > If edge vectors can be reallocated in such loops, then the iterators need > redesigning. It always has been possible to do so easilly, so I would guess we do it from time to time. In edge forwarding it is quite important for time complexity (ie we need to walk all edges together with possibly elliminating them in linear time). This is why it used for (e = b->succ; e; e = next) ... next = e->succ_next; other places that are mine will use same paradigm, so it is easy to grep for "next = e".
Honza > > nathan > -- > Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC > [EMAIL PROTECTED] :: http://www.planetfall.pwp.blueyonder.co.uk >