On 02/11/2016 10:12 PM, David Malcolm wrote:
In r227188 I introduced driver::finalize () which resets
all state within gcc.c, allowing the driver code to embedded
inside libgccjit and run repeatedly in-process.

Running this on s390x revealed a bug in this cleanup:
I was cleaning up "specs" via:
                 XDELETEVEC (specs);
and this was crashing on s390x with:
   free(): invalid pointer: 0x000003fffdf30568 ***

Closer investigation revealed that specs == static_specs,
a statically allocated array.

What's happening is that set_specs sets "specs" to static_specs
the first time it's called, and any calls to set_specs () with
a name that isn't in static_specs cause a new spec_list node
to be dynamically-allocated and put at the front of the list; "specs"
then equals that.

All of my testing had been on x86_64, which inserts exactly one spec
with a name not in the static array, hence the:
                 XDELETEVEC (specs);
happened to work.

On s390x, the only names in the "specs" file are those in the static
array, so specs == static_specs, and the bogus cleanup code attempts
to free a statically-allocated array.

The following patch reworks this part of the cleanup, walking any list
of specs, freeing the dynamically-allocated nodes until the
statically-allocated ones are reached.

driver::finalize is only called by libgccjit, not by the main driver
program, so this should be relatively low-risk.

Verified directly by running under valgrind on x86_64 and s390x.

With the patch, jit.sum on s390x-ibm-linux-gnu (RHEL 7) goes from:
   # of expected passes            1799
   # of unexpected failures        61
   # of unresolved testcases       2
to:
   # of expected passes            8514

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu.

OK for trunk?

gcc/ChangeLog:
        PR driver/69779
        * gcc.c (driver::finalize): Fix cleanup of "specs".
Can't you just "free (specs->name) rather than messing with the cast?

OK with that twiddle, assuming it works.
jeff

Reply via email to