This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/81929] New: exponential slowdown in undefined behavior sanitizer for streaming
- From: "patrick.a.moran at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Tue, 22 Aug 2017 19:32:50 +0000
- Subject: [Bug c++/81929] New: exponential slowdown in undefined behavior sanitizer for streaming
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81929
Bug ID: 81929
Summary: exponential slowdown in undefined behavior sanitizer
for streaming
Product: gcc
Version: 7.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: patrick.a.moran at gmail dot com
Target Milestone: ---
Created attachment 42028
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42028&action=edit
A reproduction of the issue described
I've attached a reproduction. The trigger for the behavior we identified is:
* To stream a number of ints (or other numeric types) into a
std::ostringstream
* To call .str() on that std::ostringstream
* To do all of the above in a single expression
* Build with -fsanitize=undefined
It seems that all the above conditions are necessary - the problem vanishes if
you:
* Split the same logic into multiple logical lines of code
* Call some member function other than .str() (like .rdbuf())
* Stream string literals instead of numeric types
* Compile without -fsanitize=undefined
The behavior we see is a compile-time that seems to grow as roughly 4^n, where
n is the number of ints being streamed in. On my box
10 numbers = 0.671s
11 numbers = 1.608s
12 numbers = 5.356s
13 numbers = 20.250s
14 numbers = 80.163s
15 numbers = 318.994s
Salient output from perf record / perf report:
# Overhead Command Shared Object Symbol
# ........ ............ .................................
........................................................................................................................................
#
59.95% cc1plus cc1plus [.]
walk_tree_1(tree_node**, tree_node* (*)(tree_node**, int*, void*), void*,
hash_set<tree_node*, default_hash_traits<tree_node*> >*, tree_node*
(*)(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*), void*,
hash_set<tree_node*, default_hash_traits<tree_node*> >*))
23.54% cc1plus cc1plus [.]
replace_placeholders_r(tree_node**, int*, void*)
14.87% cc1plus cc1plus [.]
cp_walk_subtrees(tree_node**, int*, tree_node* (*)(tree_node**, int*, void*),
void*, hash_set<tree_node*, default_hash_traits<tree_node*> >*)
0.07% cc1plus cc1plus [.]
push_to_top_level()
0.06% cc1plus [kernel.kallsyms] [k] clear_page_c_e
0.04% cc1plus cc1plus [.]
lookup_name_real(tree_node*, int, int, bool, int, int)