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