https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69779
Bug ID: 69779 Summary: [6 Regression] Invalid free in driver::finalize on s390x running libgccjit Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: driver Assignee: unassigned at gcc dot gnu.org Reporter: dmalcolm at gcc dot gnu.org Target Milestone: --- Host: s390x-ibm-linux-gnu Target: s390x-ibm-linux-gnu Build: s390x-ibm-linux-gnu I'm seeing crashes running "make check-jit" on s390x-ibm-linux-gnu: e.g. *** Error in `/home/dmalcolm/gcc-bugfixing/build/gcc/testsuite/jit/test-volatile.c.exe': free(): invalid pointer: 0x000003fffdf30568 *** The problem seems to be this line in driver::finalize: #4 0x000003fffcfe4582 in driver::finalize (this=<optimized out>) at ../../src/gcc/gcc.c:9901 9901 XDELETEVEC (specs); where specs == static_specs i.e. we have an attempt to free a statically-allocated array. specs is modified by this code in set_specs: 1871 /* See if the spec already exists. */ 1872 for (sl = specs; sl; sl = sl->next) 1873 if (name_len == sl->name_len && !strcmp (sl->name, name)) 1874 break; 1875 1876 if (!sl) 1877 { 1878 /* Not found - make it. */ 1879 sl = XNEW (struct spec_list); 1880 sl->name = xstrdup (name); 1881 sl->name_len = name_len; 1882 sl->ptr_spec = &sl->ptr; 1883 sl->alloc_p = 0; 1884 *(sl->ptr_spec) = ""; 1885 sl->next = specs; 1886 sl->default_ptr = NULL; 1887 specs = sl; 1888 } i.e. it only changes "specs" from static_specs if there's a set_spec for a name that isn't in the static specs. The cleanup code happens to work on x86_64 as we have two calls to set_spec that modify "specs": (1) It becomes static_specs in first call to set_spec, within "read_specs": #0 set_spec (name=0x662131 "asm", spec=0x6616e0 "%{m16|m32:--32} %{m16|m32|mx32:;:--64} %{mx32:--x32} %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}", user_p=false) at ../../src/gcc/gcc.c:1872 (2) but then becomes non-equal in 2nd call to set_spec, also within "read_specs" set_spec (name=0x664fd1 "cc1_cpu", spec=0x65cb90 "%{march=native:%>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}", user_p=false) at ../../src/gcc/gcc.c:1890 (and although there are many calls to set_spec, only those 2 modifiy "specs": the first one, and cc1_cpu) i.e. it only works for a host/target for which the "specs" file exists and has a name of a spec that isn't in static_specs. It fails on s390x since the specs file only has specs with the same names as those in static_specs. It looks like in driver::finalize that ought to be walking the list of dynamically-allocated spec_list instances, freeing them, until we reach static_specs. Am testing a patch for this.