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®rtested 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