Hi,
For the following test case:

#include <regex>
#include <string>
#include <iostream>
int main()
{
  std::string s="hello";
  std::regex re("h.*");
  std::cout << std::regex_match(s,re) << std::endl;
  return 0;
}

Compiling with -O2 -fauto-profile=<gcov> --param auto-profile-bbs=0 results in:

tr.cxx:4:118: internal compiler error: Segmentation fault
    4 | int main(){ std::string s="hello"; std::regex re("h.*"); std::cout << 
std::regex_match(s,re) << std::endl; return 0; }
      |                                                                         
                                             ^
0x29e0877 internal_error(char const*, ...)
        ../../gcc/gcc/diagnostic-global-context.cc:787
0x1488763 crash_signal
        ../../gcc/gcc/toplev.cc:325
0x2653ce4 autofdo::scale_bb_profile()
        ../../gcc/gcc/auto-profile.cc:4061
0x265b517 afdo_annotate_cfg
        ../../gcc/gcc/auto-profile.cc:4509
0x265b517 auto_profile
        ../../gcc/gcc/auto-profile.cc:4677
0x265b517 execute
        ../../gcc/gcc/auto-profile.cc:4850

That happens in scale_bb_profile at following place:
  const function_instance *s
      = afdo_source_profile->get_function_instance_by_decl
          (current_function_decl);

The issue is that get_function_instance_by_decl will return NULL if 
DECL_SOURCE_FILE for current_function_decl,
doesn't match with the filename stored in afdo_string_table

For above case,
current_function_decl is 
_ZNSt15_Deque_iteratorINSt8__detail9_StateSeqINSt7__cxx1112regex_traitsIcEEEERS5_PS5_EmmEv,
DECL_SOURCE_FILE is stl_deque.h
and s->file_name() corresponds to stl_tree.h

and get_function_instance_by_decl thus returns NULL.

In afdo_annotate_cfg, the workaround for that is to iterate over all filenames 
to avoid dropping profile for that function if it has mismatched filename:

  /* FIXME: This is a workaround for sourcefile tracking, if afdo_string_table
     ends up with empty filename or incorrect filename for the function and
     should be removed once issues with sourcefile tracking get fixed.  */
  if (s == NULL)
    for (unsigned i = 0; i < afdo_string_table->filenames ().length (); i++)
      {
        s = afdo_source_profile->get_function_instance_by_decl 
(current_function_decl, afdo_string_table->filenames()[i]);
        if (s)
          break;
      }


The attached patch passes the function_instance found in afdo_annotate_cfg to 
scale_bb_profile, instead of recomputing it, which fixes the segfault.

Bootstrap+test in progress.
Is this patch OK to commit if testing passes ?

Thanks,
Prathamesh




auto-profile.cc: Fix segfault in scale_bb_profile.

The rationale for this change is that DECL_SOURCE_FILE may not match
with filename in afdo_string table for current_function_decl
causing get_function_instance_by_decl to return NULL and thus resulting
in segfault. The patch fixes that by passing function_instance computed in
afdo_annotate_cfg to sample_bb_profile instead of recomputing it.

gcc/ChangeLog
        * auto-profile.cc (scale_bb_profile): New parameter function_instance.
        (afdo_annotate_cfg): Pass s to scale_bb_profile.

diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
index 6aa5166c748..386752da4e7 100644
--- a/gcc/auto-profile.cc
+++ b/gcc/auto-profile.cc
@@ -4050,12 +4050,8 @@ determine_scale (vec <scale> *scales, profile_count 
max_count,
 /* Scale profile of the whole function to approximately match auto-profile.  */
 
 bool
-scale_bb_profile ()
+scale_bb_profile (const function_instance *s)
 {
-  const function_instance *s
-      = afdo_source_profile->get_function_instance_by_decl
-         (current_function_decl);
-
   /* In the first pass only store non-zero counts.  */
   gcov_type head_count = s->head_count () * autofdo::afdo_count_scale;
   hash_set <basic_block> zero_bbs;
@@ -4505,7 +4501,7 @@ afdo_annotate_cfg (void)
 
   if (!param_auto_profile_bbs)
     {
-      if (scale_bb_profile ())
+      if (scale_bb_profile (s))
        return;
     }
   else

Reply via email to