Hello. As reported in mentioned PR, we segfault in gcov tool when one uses -a. It's caused by fact that vectors blocks and block_lists have indices kept in sync and as one removes an element from blocks via: blocked.erase (it);
Then calling recursively the same function breaks the synchronization. The patch was originally written by Joshua (adding him to CC). If I'm correct calling: - unblock (u, blocked, block_lists); does not make sense as we've already removed 'u'. Plus one needs to put content of block_lists[index] to a separate vector in order to not to break iteration. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. And fixed the problem reported in opensuse bugzilla (mentioned in the GCC bugzilla PR). Ready to be installed? Martin gcc/ChangeLog: 2017-07-26 Martin Liska <mli...@suse.cz> PR gcov-profile/81561 * gcov.c (unblock): Make unblocking safe as we need to preserve index correspondence of blocks and block_lists. --- gcc/gcov.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
>From a31295c91c57fd3338e47eba1f513fcb1c37d8d2 Mon Sep 17 00:00:00 2001 From: marxin <mli...@suse.cz> Date: Wed, 26 Jul 2017 14:21:52 +0200 Subject: [PATCH] Fix segfault in gcov.c (PR gcov-profile/81561). gcc/ChangeLog: 2017-07-26 Martin Liska <mli...@suse.cz> PR gcov-profile/81561 * gcov.c (unblock): Make unblocking safe as we need to preserve index correspondence of blocks and block_lists. --- gcc/gcov.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gcc/gcov.c b/gcc/gcov.c index e324cadad82..c56bac20278 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -539,13 +539,13 @@ unblock (const block_t *u, block_vector_t &blocked, unsigned index = it - blocked.begin (); blocked.erase (it); - for (block_vector_t::iterator it2 = block_lists[index].begin (); - it2 != block_lists[index].end (); it2++) - unblock (*it2, blocked, block_lists); - for (unsigned j = 0; j < block_lists[index].size (); j++) - unblock (u, blocked, block_lists); + block_vector_t to_unblock (block_lists[index]); block_lists.erase (block_lists.begin () + index); + + for (block_vector_t::iterator it = to_unblock.begin (); + it != to_unblock.end (); it++) + unblock (*it, blocked, block_lists); } /* Find circuit going to block V, PATH is provisional seen cycle. -- 2.13.3