세그먼트 장애는 MariaDB c++ 커넥터와 regex를 사용할 때 발생합니다.
mysql 데이터베이스를 쿼리하고 regex를 사용하여 테이블 데이터의 문자열을 분리하는 간단한 유틸리티 프로그램을 만들고 있습니다.
MariaDB c++/connector와 최신 버전의 MariaDB를 사용하고 있습니다.이 코드는 MariaDB 웹사이트에서 복사한 것입니다.문제를 설명하기 위해 소프트웨어를 단순화했습니다.아래를 참조해 주세요.
// g++ -o mariadb_connect mariadb_connect.cpp -lmariadbcpp
// From https://mariadb.com/docs/clients/connector-cpp/
// with three additional lines that cause segfault
#include <iostream>
#include <mariadb/conncpp.hpp>
#include <regex> // <-- Added to the example
int main()
{
try
{
// Instantiate Driver
sql::Driver* driver = sql::mariadb::get_driver_instance();
// Configure Connection
// The URL or TCP connection string format is
// ``jdbc:mariadb://host:port/database``.
sql::SQLString url("jdbc:mariadb://localhost:3306/??????");
// Use a properties map for the user name and password
sql::Properties properties({
{"user", "???????"},
{"password", "????????"}
});
// Establish Connection
// Use a smart pointer for extra safety
std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
// Use Connection
std::cout << "Using the connection" << std::endl; // <-- Added
std::regex regexp("(faststatic.com)(.*)"); // <-- Added (Causes segfault)
// Close Connection
conn->close();
}
// Catch Exceptions
catch (sql::SQLException& e)
{
std::cout << "Error Connecting to MariaDB Platform: "
<< e.what() << std::endl;
// Exit (Failed)
return 1;
}
// Exit (Success)
return 0;
}
(--프라이빗 데이터에 사용)
Amazon Linux 2 AMI를 실행하는 AWS EC2 인스턴스에서 g++로 컴파일됩니다.
std::regex regexp(...) 행을 추가할 때까지 정상적으로 컴파일되어 실행됩니다.추가해도 컴파일은 정상적으로 진행되지만 실행 시 segfault가 호출됩니다.
브레이크 포인트를 main으로 설정하고 다음 출력을 제공하는 gdb를 사용했습니다.
(gdb) b main
Breakpoint 1 at 0x40404b: file mariadb_connect.cpp, line 15.
(gdb) run
Starting program: /home/msellers/proj/preload_images/spike/mariadb_connect
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x000000000064a588 in ?? ()
segfault 이후의 gdb bt 명령어의 출력을 다음에 나타냅니다.
(gdb) bt
#0 0x000000000064a588 in ?? ()
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
#2 0x00000000004084a1 in std::__detail::_Scanner<char>::_M_advance (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:80
#3 0x00007ffff7c3e060 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (this=this@entry=0x7fffffffe000, token=std::__detail::_ScannerBase::_S_token_subexpr_begin) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:541
#4 0x00007ffff7c513a2 in std::__detail::_Compiler<std::regex_traits<char> >::_M_match_token (token=std::__detail::_ScannerBase::_S_token_subexpr_begin, this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:316
#5 std::__detail::_Compiler<std::regex_traits<char> >::_M_atom (this=this@entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:326
#6 0x00007ffff7c515b0 in std::__detail::_Compiler<std::regex_traits<char> >::_M_term (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:136
#7 std::__detail::_Compiler<std::regex_traits<char> >::_M_alternative (this=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:118
#8 0x00007ffff7c51809 in std::__detail::_Compiler<std::regex_traits<char> >::_M_disjunction (this=this@entry=0x7fffffffe000) at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:97
#9 0x00007ffff7c51e18 in std::__detail::_Compiler<std::regex_traits<char> >::_Compiler (this=0x7fffffffe000, __b=<optimized out>, __e=<optimized out>, __traits=..., __flags=<optimized out>)
at /usr/local/include/c++/4.9.4/bits/regex_compiler.tcc:82
#10 0x00007ffff7c5222d in std::__detail::__compile_nfa<std::regex_traits<char> > (__first=<optimized out>, __last=<optimized out>, __traits=..., __flags=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex_compiler.h:158
#11 0x00007ffff7c524da in std::basic_regex<char, std::regex_traits<char> >::basic_regex<char const*> (__f=<optimized out>, __last=<optimized out>, __first=<optimized out>, this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>)
at /usr/local/include/c++/4.9.4/bits/regex.h:540
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
#14 _GLOBAL__sub_I_UrlParser.cpp(void) () at /home/buildbot/src/src/UrlParser.cpp:444
#15 0x00007ffff7de7dc2 in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7fffffffe2b8, env=env@entry=0x7fffffffe2c8) at dl-init.c:72
#16 0x00007ffff7de7eb6 in call_init (env=0x7fffffffe2c8, argv=0x7fffffffe2b8, argc=1, l=<optimized out>) at dl-init.c:119
#17 _dl_init (main_map=0x7ffff7ffe130, argc=1, argv=0x7fffffffe2b8, env=0x7fffffffe2c8) at dl-init.c:120
#18 0x00007ffff7dd9f2a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#19 0x0000000000000001 in ?? ()
#20 0x00007fffffffe520 in ?? ()
#21 0x0000000000000000 in ?? ()
(gdb)
이게 도움이 되나요?
마크.
GCC 버전 7.3.1
역추적에서는 GCC-7 regexp 구현에서 크래시가 발생하고 있음을 알 수 있습니다.
#1 0x0000000000409155 in std::__detail::_Scanner<char>::_M_scan_normal (this=0x7fffffffe018) at /usr/include/c++/7/bits/regex_scanner.tcc:119
또, 이 크래시는, GCC-4.9.4 버전을 사용하고 있을 때에, 글로벌한 내부(아마도1)의 MariaDB 커넥터가 초기화되고 있는 것을 알 수 있습니다.libstdc++
:
#12 std::basic_regex<char, std::regex_traits<char> >::basic_regex (this=0x7ffff7dc2a40 <sql::mariadb::UrlParser::URL_PARAMETER>, __p=<optimized out>, __f=<optimized out>) at /usr/local/include/c++/4.9.4/bits/regex.h:452
#13 0x00007ffff7c331ee in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at /home/buildbot/src/src/UrlParser.cpp:34
이 4.9.4와 7.3.1의 불일치가 크래시의 원인일 가능성이 매우 높으며, g++-4.9.4로 앱을 구축하거나 g++-7.3.1로 MariaDB를 구축하면 문제가 해결됩니다.
이론상으로는 GCC 버전libstdc++
하위 호환성이 있어야 하지만 ABI 호환성을 확인합니다.C++
꽤 힘들고 많은 실수가 있었습니다.또한 g++4.9.4는 고대어입니다.
또 하나의 가능한 해결책은 어플리케이션을 구축하는 것입니다.clang
사용.libc++
--이것에 의해서, 심볼의2 경합이 발생하지 않게 됩니다.
1 프레임이 다음과 같은지 여부를 확인할 수 있습니다.#13
는 다음 GDB 명령어를 실행하여 MariaDB에서 가져옵니다.frame 13
,info symbol $pc
.
2 그러기 위해서는, 다음과 같이 명시적으로 말할 필요가 있습니다.clang
사용하다libc++
디폴트로는 를 사용하는 경우가 있기 때문에libstdc++
.사용하다clang++ -stdlib=libc++ ...
확실히.매뉴얼은 이쪽입니다.
언급URL : https://stackoverflow.com/questions/68258440/segfault-occurs-when-using-mariadb-c-connector-and-regex
'source' 카테고리의 다른 글
IntelliJ에서의 RegEx 백레퍼런스 (0) | 2023.01.19 |
---|---|
JPA 및 최대 절전 모드로 UTC 시간대에 날짜/시간 및 타임스탬프를 저장하는 방법 (0) | 2023.01.19 |
mysqld: dir를 데이터로 변경할 수 없습니다.서버가 기동하지 않는다 (0) | 2023.01.19 |
php에서는 0은 비어 있는 것으로 취급됩니까? (0) | 2023.01.19 |
MariaDB 서버가 600초 후 클라이언트 접속 타임아웃 (0) | 2023.01.19 |