On 9/6/20 1:24 PM, Sergei Trofimovich wrote:
From: Sergei Trofimovich <siarh...@google.com>

Before the change gcc did not stream correctly TOPN counters
if counters belonged to a non-local shared object.

As a result zero-section optimization generated TOPN sections
in a form not recognizable by '__gcov_merge_topn'.

The problem happens because in a case of multiple shared objects
'__gcov_merge_topn' function is present in address space multiple
times (once per each object).

The fix is to never rely on function address and predicate on TOPN
counter types.

Hello.

Thank you for the analysis! I think it's the correct fix and it's probably
similar to what we used to see for indirect_call_tuple.

@Alexander: Am I right?

Thanks,
Martin


libgcc/ChangeLog:

        PR gcov-profile/96913
        * libgcov-driver.c (write_one_data): Avoid function pointer
        comparison in TOP streaming decision.
---
  libgcc/libgcov-driver.c | 7 ++++++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index 58914268d4e..86a6b5ad68a 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -424,10 +424,15 @@ write_one_data (const struct gcov_info *gi_ptr,
n_counts = ci_ptr->num; - if (gi_ptr->merge[t_ix] == __gcov_merge_topn)
+         /* Do not zero-compress top counters because:
+          * - __gcv_merge_topn does not handle such sections
+          * - GCOV_COUNTER_V_INDIR contains non-zero keys
+          */
+         if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR)
            write_top_counters (ci_ptr, t_ix, n_counts);
          else
            {
+
              /* Do not stream when all counters are zero.  */
              int all_zeros = 1;
              for (unsigned i = 0; i < n_counts; i++)


Reply via email to