From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 33DEB3858C01; Thu, 28 Sep 2023 13:26:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 33DEB3858C01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1695907564; bh=4geIsKW/fbT7nwnBfHwqgXG/MjiuXgHZ0LbDUbY03rE=; h=From:To:Subject:Date:From; b=C65Vij9gkOOj8G67rJT2P6vTg9gK3UPWNSrBsFYqS1tMPhXnDiNcKVdQeAH1qFkaf EKTHh6tqSZ7ljjShSH8dX8faWrpJCKXW+oeuaEuRP3v0LSyTiVrVE4jfOGVWYcfaTG Kjdk5BkasPtp40agyjh8fDULPiS9dj4uVn1jry9k= From: "slyfox at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug other/111629] New: [14 Regression] ggc_common_finalize() corrupts global memory outsuide GTY(()) objects Date: Thu, 28 Sep 2023 13:26:02 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: other X-Bugzilla-Version: 14.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: slyfox at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D111629 Bug ID: 111629 Summary: [14 Regression] ggc_common_finalize() corrupts global memory outsuide GTY(()) objects Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: other Assignee: unassigned at gcc dot gnu.org Reporter: slyfox at gcc dot gnu.org Target Milestone: --- Initially I observed the bug as a gcc profiled bootstrap failure on r14-4300-g1fab05a885a308: $ ~/dev/git/gcc/configure --disable-multilib --enable-languages=3Dc,c++ 'CC= =3Dgcc -O2 -ggdb3' 'CXX=3Dg++ -O2 -ggdb3' $ make profiledbootstrap configure: error: uint64_t or int64_t not found $ touch a.c && /tmp/gb/./prev-gcc/xg++ -B/tmp/gb/./prev-gcc/ -c a.c xg++: internal compiler error: Segmentation fault signal terminated program cc1plus While it look slike a profile-related problem I think it's just a coinciden= ce: it's a side-effect of gcov globals corruption exposed by `ggc_common_finalize()`. `ggc_common_finalize()` is supposed to memset() GTY(()) globals, but its slightly out of bounds and corrupts gcov. Debugging: $ gdb --args /tmp/gb/./prev-gcc/cc1plus -quiet -v -iprefix /tmp/gb/prev-gcc/../lib/gcc/x86_64-pc-linux-gnu/14.0.0/ -isystem /tmp/gb/./prev-gcc/include -isystem /tmp/gb/./prev-gcc/include-fixed -D_GNU_SOURCE a.c -quiet -dumpbase a.c -dumpbase-ext .c -mtune=3Dgeneric -march=3Dx86-64 -version -o /run/user/1000/ccA6Gln1.s (gdb) run ... Program received signal SIGSEGV, Segmentation fault. 0x000000000442ab26 in gcov_do_dump (list=3D0x5cab0e0, run_counted=3D0, mode= =3D0) at /home/slyfox/dev/git/gcc/libgcc/libgcov-driver.c:690 690 for (unsigned i =3D 0; i < cinfo->num; i++) (gdb) list 685 for (unsigned f_ix =3D 0; (unsigned)f_ix !=3D gi_ptr->n_functio= ns; f_ix++) 686 { 687 const struct gcov_ctr_info *cinfo 688 =3D &gi_ptr->functions[f_ix]->ctrs[GCOV_COUNTER_ARCS]; (gdb) p gi_ptr->functions[f_ix] $1 =3D (const gcov_fn_info * const) 0x0 =3D=3D=3D This is a corruption: `gi_ptr->functions[f_ix]` are gcov.* global counters.=20=20 =3D=3D=3D They are never expected to be zero. Looking up place of corrupti= on: (gdb) p &gi_ptr->functions[f_ix] $2 =3D (const gcov_fn_info * const *) 0x50c1540 (gdb) watch -l *(void**)0x50c1540 Hardware watchpoint 1: -location *(void**)0x50c1540 (gdb) run The program being debugged has been started already. Start it from the beginning? (y or n) y Hardware watchpoint 1: -location *(void**)0x50c1540 Old value =3D (void *) 0x50c4080 <__gcov_._ZN10hash_tableI18subsumption_hasherLb0E11xcallocatorE26find_empty= _slot_for_expandEj> New value =3D (void *) 0x50c4000 __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:328 328 ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such fi= le or directory. (gdb) bt #0 __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:328 #1 0x0000000001933651 in ggc_common_finalize () at /home/slyfox/dev/git/gcc/gcc/ggc-common.cc:1312 #2 0x00000000020d7cf1 in toplev::finalize (this=3Dthis@entry=3D0x7fffffffa= ece) at /home/slyfox/dev/git/gcc/gcc/toplev.cc:2354 #3 0x0000000000c640b6 in main (argc=3D, argv=3D0x7fffffffaf= f8) at /home/slyfox/dev/git/gcc/gcc/main.cc:42 (gdb) fr 1 #1 0x0000000001933651 in ggc_common_finalize () at /home/slyfox/dev/git/gcc/gcc/ggc-common.cc:1312 1312 memset (rti->base, 0, rti->stride * rti->nelt); (gdb) list 1307 for (rti =3D *rt; rti->base !=3D NULL; rti++) 1308 memset (rti->base, 0, rti->stride * rti->nelt); 1309 1310 for (rt =3D gt_ggc_rtab; *rt; rt++) 1311 for (rti =3D *rt; rti->base !=3D NULL; rti++) 1312 memset (rti->base, 0, rti->stride * rti->nelt); 1313 1314 for (rt =3D gt_pch_scalar_rtab; *rt; rt++) 1315 for (rti =3D *rt; rti->base !=3D NULL; rti++) 1316 memset (rti->base, 0, rti->stride * rti->nelt); =3D=3D=3D What ggc are we destroying? (gdb) p *rt $3 =3D (const ggc_root_tab * const) 0x448e320 (gdb) p rti - *rt $4 =3D 5 Fifth element of gt_ggc_r_gt_cp_tree_h: >From prev-gcc/gt-cp-tree.h: /* Structures for the easy way to mark roots. In an array, terminated by having base =3D=3D NULL. */ struct ggc_root_tab { void *base; size_t nelt; size_t stride; gt_pointer_walker cb; gt_pointer_walker pchw; }; EXPORTED_CONST struct ggc_root_tab gt_ggc_r_gt_cp_tree_h[] =3D { ... { // 4 &ovl_op_info[0][0].identifier, 1 * (2) * (OVL_OP_MAX), sizeof (ovl_op_info[0][0]), >_ggc_mx_tree_node, >_pch_nx_tree_node }, { // 5 &ovl_op_info[0][0].name, 1 * (2) * (OVL_OP_MAX), sizeof (ovl_op_info[0][0]), (gt_pointer_walker) >_ggc_m_S, (gt_pointer_walker) >_pch_n_S }, { //6 &ovl_op_info[0][0].mangled_name, 1 * (2) * (OVL_OP_MAX), sizeof (ovl_op_info[0][0]), (gt_pointer_walker) >_ggc_m_S, (gt_pointer_walker) >_pch_n_S }, =3D=3D=3D Note how 'base' points not at the beginning of the whole 'ovl_op_info[0][0])' but at the GTY()) field itself within the struct: struct GTY(()) ovl_op_info_t { /* The IDENTIFIER_NODE for the operator. */ tree identifier; /* The name of the operator. */ const char *name; /* The mangled name of the operator. */ const char *mangled_name; /* The (regular) tree code. */ enum tree_code tree_code : 16; /* The (compressed) operator code. */ enum ovl_op_code ovl_op_code : 8; /* The ovl_op_flags of the operator */ unsigned flags : 8; }; /* Overloaded operator info indexed by ass_op_p & ovl_op_code. */ extern GTY(()) ovl_op_info_t ovl_op_info[2][OVL_OP_MAX]; =3D=3D=3D Done. I think `ggc_common_finalize()`'s intent is to memset() the whole struct, b= ut it has no pointer to that struct. Sounds about right? What would be the best fix here? Just zero out pointers? Sounds a bit risky, but might be fine? Compiler version: $ /tmp/gb/./prev-gcc/xg++ -B/tmp/gb/./prev-gcc/ -v Reading specs from /tmp/gb/./prev-gcc/specs COLLECT_GCC=3D/tmp/gb/./prev-gcc/xg++ COLLECT_LTO_WRAPPER=3D/tmp/gb/./prev-gcc/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: /home/slyfox/dev/git/gcc/configure --disable-multilib --enable-languages=3Dc,c++ CC=3D'gcc -O2 -ggdb3' CXX=3D'g++ -O2 -ggdb3' Thread model: posix Supported LTO compression algorithms: zlib gcc version 14.0.0 20230926 (experimental) (GCC)=