让我们从最小的代码开始重现错误:
#include <cxxabi.h>
#include <iostream>
#include <regex>
int main()
{
std::string realname("My amazing string with trailing whitespace ");
std::string ret = std::regex_replace(
realname.data(), std::regex{"My amazing string with trailing whitespace ?"},
"std::string" );
std::cout << ret << std::endl;
}
如果用clang编译它:
clang++ -O2 -g -std=c++14 test.cpp -o crash
这会产生分段错误
使用-O1
或更少会有效,使用gcc可以在所有情况下使用,而不是传递char*
,但只是将realname
传递为std::string
也可以。
但原始代码只有char*
,因此我必须执行副本才能获得std::string
。
因此,让我们关注clang -O2
和char*
的版本。
我做了一些调试,它似乎在标准库正则表达式部分崩溃了。
更准确地说,在regex.tcc
行501中读取:
return _M_pregex == __rhs._M_pregex
&& _M_begin == __rhs._M_begin
&& _M_end == __rhs._M_end
&& _M_flags == __rhs._M_flags
&& _M_match[0] == __rhs._M_match[0];
当单步执行不会发生段错误的二进制文件时,它将按顺序执行这些检查并在_M_end == __rhs._M_end
之后停止,但是,在崩溃的二进制文件中,我们将看到它首先检查_M_match[0] == __rhs._M_match[0]
导致崩溃。
我很乐意得到一些意见,因为我不太确定我是否遗漏了一些东西......
但如果不是我会认为这是clang优化器中的错误,不是吗?
编辑:clang版本为clang version 5.0.0 (trunk 296300)
答案 0 :(得分:0)
对于噪音的道歉,在注意到我们系统上提供的clang5如上所述实际上不是发布版本我尝试使用发行版和clang3.9并且它有效。
在开发过程中一定是回归......
再次,对不起噪音!