https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68446
--- Comment #3 from David Malcolm <dmalcolm at gcc dot gnu.org> --- (In reply to Martin Liška from comment #2) > Hi David. > > I've just verified that the invalid free is presented since introduction of > driver::finalize in r227188. > > This is valgrind report coming from r230263 (one revision before the > suspected): [...snip...] FWIW I'm not seeing that invalid free with trunk. After a lot of stepping through trunk in gdb, the root cause is that: obstack_free (obstack, NULL); leaves an obstack in an uninitialized state and hence a reinitialization is required, but is missing. libiberty/obstacks.texi has: Note that if @var{object} is a null pointer, the result is an *uninitialized* obstack. [my emphasis] To free all memory in an obstack but leave it valid for further allocation, call @code{obstack_free} with the address of the first object allocated on the obstack: @smallexample obstack_free (obstack_ptr, first_object_allocated_ptr); @end smallexample In particular, obstack_free (ob, NULL) doesn't unset chunk. What was happening is that after any call to: obstack_free (opts_obstack, NULL); e.g. the one in toplev::finalize, all of the chunks used by opts_obstack are returned to memory_block_pool's m_blocks linked-list of 64KB free chunks, and they get reused by other obstacks e.g. for bitmaps. However, given that opts_obstack never gets reinitialized, opts_obstack.chunks points at a freed chunk. On the 2nd iteration of a jit testcase, it gets used to allocate copies of the options, but this out of a chunk that's being used by a different memory_block_pool user, so chaos ensues: we have 64KB chunks of memory being erroneously shared between different memory-pool users. If I remove the logic to lazily initialize opts_obstacks, and instead have it initialize it each time, then all jit test cases successfully run to completion (5 iterations): # of expected passes 6392 # of unexpected failures 1 FAIL: jit.dg/test-threads.c, initial compilation with the exception of an unrelated issue building test-threads.c.exe. I'm working on a patch for this (including poisoning memory block pool chunks when returned to the linked list, and poisoning obstacks when freed with NULL). Martin: can you tell me any more context on why r230264 was necessary? Discussion seems to be here: https://gcc.gnu.org/ml/gcc-patches/2015-11/msg01471.html