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

Reply via email to