【问题标题】:Crash during program startup when linking against Boost regex library链接 Boost 正则表达式库时程序启动期间崩溃
【发布时间】:2013-03-14 14:21:29
【问题描述】:

我们的项目(在 C++ 中)需要链接到 boost regex,所以我们只需找到正确编译的 libboost_regex_1.45.0 并告诉 g++ 链接到它。编译成功,我们只需按预期获得正确的可执行文件。问题是,每次我们尝试运行可执行文件时,它都会在进入main() 例程之前崩溃。

使用gdb附加生成的core文件,backtrace命令显示__bultin_strlen期间存在分段错误,已解决为strlen@@GLBC_2.2.5

由于我们的可执行文件链接到多个动态库,readelf -s 被用来识别有问题的符号,它归结为libboost_regex。但是引用的符号已经存在于 RHEL6 系统文件夹 /lib64/libc.so 中。

问题是,我们如何才能让 boost 正则表达式正常工作?

  • 操作系统:RHEL6.2
  • GCC: 4.3.2 / libstdc++6.0.13
  • Boost 库由完全相同的工具集构建 - user-config.bjam 是自定义的

由于各种原因,静态链接对我们来说不是一个好的选择。

符号信息和ldd信息附在https://gist.github.com/skyscribe/5184622

【问题讨论】:

  • 你看过完整的回溯吗?没有正在运行的构造函数或静态初始化?
  • 首先确保用于构建程序的编译器版本与 boost_regex 匹配。您是否从源代码编译了 boost,或者您是否安装了预编译版本?
  • @JoachimPileborg 不,回溯只是指向 boost 正则表达式库 - 一些 RAII 特定于 Boost 库的详细名称空间的东西,与应用程序逻辑无关。只要链接了这个库,即使是一个非常简单的 hello world 程序也可能崩溃。不过,其他库也可以正常工作,例如 libboost_thread,它不引用像 xxx@@GLIBC_2.2.5 这样的符号
  • 请逐字发布回溯,以及ldd /path/to/libboost_regex.so的输出。
  • 请显示文件 test.cpp 的第 28 行(及其周围的行)。这就是崩溃的根源,在您的 main 函数中。

标签: c++ linux boost linker


【解决方案1】:

从 gdb 回溯中,我们看到带有参数 \"http:\\\\/\\\\/localhostr.com\\\\/files\\\\/.+?\"std::char_traits<char>::length 方法正在触发分段错误。 g++ 4.3.2 引入了新的Stack Smashing Protection 功能,这可能会干扰 strlen 长度计算。

使用最近的 g++ 编译器重新编译/重新链接您的代码,看看您是否解决了这个错误。此示例代码不会重现此类错误:

user@workstation ~
$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-pc-cygwin/4.5.3/lto-wrapper.exe
Target: i686-pc-cygwin
Configured with: /gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3/configure --srcdir=/gnu/gcc/releases/respins/4.5.3-3/gcc4-4.5.3-3/src/gcc-4.5.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdir=/usr/lib --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --datarootdir=/usr/share --docdir=/usr/share/doc/gcc4 -C --datadir=/usr/share --infodir=/usr/share/info --mandir=/usr/share/man -v --with-gmp=/usr --with-mpfr=/usr --enable-bootstrap --enable-version-specific-runtime-libs --libexecdir=/usr/lib --enable-static --enable-shared --enable-shared-libgcc --disable-__cxa_atexit --with-gnu-ld --with-gnu-as --with-dwarf2 --disable-sjlj-exceptions --enable-languages=ada,c,c++,fortran,java,lto,objc,obj-c++ --enable-graphite --enable-lto --enable-java-awt=gtk --disable-symvers --enable-libjava --program-suffix=-4 --enable-libgomp --enable-libssp --enable-libada --enable-threads=posix --with-arch=i686 --with-tune=generic --enable-libgcj-sublibs CC=gcc-4 CXX=g++-4 CC_FOR_TARGET=gcc-4 CXX_FOR_TARGET=g++-4 GNATMAKE_FOR_TARGET=gnatmake GNATBIND_FOR_TARGET=gnatbind --with-ecj-jar=/usr/share/java/ecj.jar
Thread model: posix
gcc version 4.5.3 (GCC)

user@workstation ~
$ cat test.cc
#include <iostream>
#include <string>

int main(int argc, char *argv[]) {
  char * a = "\"http:\\\\/\\\\/localhostr.com\\\\/files\\\\/.+?\"";
  int t =  std::char_traits<char>::length (a);
  std::cout << t << std::endl;
}

user@workstation ~
$ g++ -g test.cc
test.cc: In function ‘int main(int, char**)’:
test.cc:6:14: warning: deprecated conversion from string constant to ‘char*’

user@workstation ~
$ gdb a.exe
Reading symbols from /home/user/a.exe...done.
(gdb) b std::char_traits<char>::length
Breakpoint 1 at 0x4017f6: file /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/char_traits.h, line 263.
(gdb) r
Starting program: /home/user/a.exe
[New Thread 764.0x5e4]
[New Thread 764.0x100c]

Breakpoint 1, std::char_traits<char>::length (__s=0x402080 "\"http:\\\\/\\\\/localhostr.com\\\\/files\\\\/.+?\"") at /usr/lib/gcc/i686-pc-cygwin/4.5.3/include/c++/bits/char_traits.h:263
263           { return __builtin_strlen(__s); }
(gdb) c
Continuing.
41
[Inferior 1 (process 764) exited normally]
(gdb)

【讨论】:

  • 不要以为这是同一个问题——因为第三方库对 GCC 版本的依赖,对我来说更换 GCC 编译器版本是有风险的。无论如何感谢您的评论。
猜你喜欢
  • 1970-01-01
  • 2014-11-28
  • 2013-07-09
  • 1970-01-01
  • 2020-06-17
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多