This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug jit/68446] jit testsuite failures seen inside dwarf2out.c:gen_producer_string
- From: "dmalcolm at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 12 Jan 2016 15:25:17 +0000
- Subject: [Bug jit/68446] jit testsuite failures seen inside dwarf2out.c:gen_producer_string
- Auto-submitted: auto-generated
- References: <bug-68446-4 at http dot gcc dot gnu dot org/bugzilla/>
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