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
