微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 MariaDB c++ 连接器和正则表达式时发生段错误

如何解决使用 MariaDB c++ 连接器和正则表达式时发生段错误

我正在构建一个简单的实用程序,用于查询 MysqL 数据库,并使用正则表达式来隔离表数据中的字符串。

我正在使用 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(...) 线。添加后它仍然可以很好地编译,但是在执行调用时 段错误

我使用了 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 ?? ()

这是段错误后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>,__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>,__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,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)

这有帮助吗?

标记

解决方法

海湾合作委员会 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

我们看到这个崩溃发生在一些全局内部(大概是1)MariaDB连接器正在初始化,同时使用GCC-4.9.4 版本的 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++ 构建 MariaDB -7.3.1 将解决问题。

理论上libstdc++的GCC版本应该是向下兼容的,但是验证C++中的ABI兼容性非常困难,并且犯了很多错误。此外,g++4.9.4 是古老的

另一种可能的解决方案是使用 clang 使用 libc++ 构建应用程序——这将避免任何符号冲突的可能性2


1 您可以通过执行以下 GDB 命令来验证帧 #13 是否真的来自 MariaDB:frame 13info symbol $pc

2要实现这一点,您可能需要明确告诉clang使用libc++,因为它可能默认使用{{1 }}。使用 libstdc++ 来确定。文档 here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。