4

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

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

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

问题是,我们如何才能让 boost regex 正常工作?

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

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

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

4

1 回答 1

0

从 gdb 回溯中,我们看到std::char_traits<char>::length带参数的方法\"http:\\\\/\\\\/localhostr.com\\\\/files\\\\/.+?\"正在触发分段错误。g++ 4.3.2 引入了新的堆栈粉碎保护功能,这可能会干扰 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)
于 2013-03-25T02:11:12.303 回答