Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ app&;时出现Seg故障;使用-static libstdc++;_C++_Linux_Gcc_Shared Libraries_Libstdc++ - Fatal编程技术网

C++ app&;时出现Seg故障;使用-static libstdc++;

C++ app&;时出现Seg故障;使用-static libstdc++;,c++,linux,gcc,shared-libraries,libstdc++,C++,Linux,Gcc,Shared Libraries,Libstdc++,如果我用C++编写一个C++应用程序——静态LBSTDC++,它加载一个共享的LIB(通过DLOpenE),它也是用静态LIbSTDC++,然后在DLOpen.中应用App SEG错误。 但是--这只在某些设置中发生: GCC 4.7.4,32位:通过 GCC 4.8.3,32位:通过 GCC 4.8.4,64位:通过 GCC 4.9.2,64位:通过 GCC 4.9.3,32位:失败(除非指定了RTLD\u DEEPBIND) GCC 4.9.3,64位:通过 调查结果: 如果在为共享库

如果我用C++编写一个C++应用程序——静态LBSTDC++<代码>,它加载一个共享的LIB(通过DLOpenE),它也是用<代码>静态LIbSTDC++<代码>,然后在DLOpen.

中应用App SEG错误。 但是--这只在某些设置中发生:

  • GCC 4.7.4,32位:通过
  • GCC 4.8.3,32位:通过
  • GCC 4.8.4,64位:通过
  • GCC 4.9.2,64位:通过
  • GCC 4.9.3,32位:失败(除非指定了
    RTLD\u DEEPBIND
  • GCC 4.9.3,64位:通过
调查结果:
  • 如果在为共享库或应用程序构建时未使用
    -static libstdc++
    ,则它可以工作
  • 如果(
    RTLD_LAZY | RTLD_DEEPBIND
    )被传递给dlopen,它就会工作。因此,我怀疑问题与应用程序和So之间的符号混淆/重复有关
  • 有趣的是,如果我让代码先用(
    RTLD_LAZY | RTLD_DEEPBIND
    )加载.so,然后关闭它并仅用
    RTLD_LAZY
    重新加载,它也可以工作
重现步骤 代码: 函数.cpp 跑 回溯
$gdb-c./core./main
GNU gdb(gdb)7.9.1
版权所有(C)2015免费软件基金会。
许可证GPLv3+:GNU GPL版本3或更高版本
这是自由软件:您可以自由更改和重新发布它。
在法律允许的范围内,不存在任何担保。键入“显示复制”
和“显示保修”了解详细信息。
此GDB配置为“i686 linux”。
键入“显示配置”以获取配置详细信息。
有关错误报告说明,请参阅:
.
在线查找GDB手册和其他文档资源,网址为:
.
要获得帮助,请键入“帮助”。
键入“apropos word”以搜索与“word”相关的命令。。。
从./main…读取符号完成。
[新LWP 19846]
警告:无法加载LinuxGate.so.1的共享库符号。
您需要“设置solib搜索路径”还是“设置系统根”?
核心由“./main”生成。
程序以信号SIGSEGV终止,分段故障。
#0原子添加单个(uuu val=1,uuu mem=0x0)
位于/home/test/dev/3rdParty/gcc/build/i686 pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:74
74{*\uu mem+=\uu val;}
(gdb)英国电信
#0原子添加单个(uuu val=1,uuu mem=0x0)
位于/home/test/dev/3rdParty/gcc/build/i686 pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:74
#1 \uuuu原子\u添加\u分派(\uuuu val=1,\uuuu mem=0x0)
在/home/test/dev/3rdParty/gcc/build/i686 pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:98
#2 _M_添加_引用(此=0x0)
at/home/test/dev/3rdParty/gcc/build/i686 pc linux gnu/libstdc++-v3/include/bits/locale_classes.h:510
#3标准::语言环境::语言环境(此=0xb74f7ffc)
at/home/test/dev/3rdParty/gcc/gcc-4.9.3/libstdc++-v3/src/c++98/locale_init.cc:223
#基本流BUF中的4 0xb746f559(此=)
at/home/test/dev/3rdParty/gcc/build/i686 pc linux gnu/libstdc++-v3/include/streambuf:466
#5 stdio_sync_filebuf(uuu f=0xb76a2a20,this=)
at/home/test/dev/3rdParty/gcc/build/i686 pc linux gnu/libstdc++-v3/include/ext/stdio_sync_filebuf.h:77
#6 std::ios_base::Init::Init(this=0xb74f7a01)
at/home/test/dev/3rdParty/gcc/gcc-4.9.3/libstdc++-v3/src/c++98/ios_init.cc:85
#7 0xb7469419英寸静态初始化和销毁(初始化p=1,优先级=65535)
at/home/test/dev/3rdParty/build_toolchain/include/c++/4.9.3/iostream:74
#8 0xb7469456 in _GLOBAL__sub_I_functions.cpp(void)()at functions.cpp:12
#9 0xb772c25e英寸??()来自/lib/ld linux.so.2
#10 0xb772c35a英寸??()来自/lib/ld linux.so.2
#11 0xb7730622英寸??()来自/lib/ld linux.so.2
#12 0xb772c117英寸??()来自/lib/ld linux.so.2
#13 0xb772fdf4英寸??()来自/lib/ld linux.so.2
#14 0xb76edcae英寸??()来自/lib/libdl.so.2
#15 0xb772c117英寸??()来自/lib/ld linux.so.2
#16 0xb76ee3b6英寸??()来自/lib/libdl.so.2
#/lib/libdl.so.2中dlopen()中的17 0xb76edd61
#主管道中的18 0x0804e102(argc=1,argv=0xbfadc254)。cpp:18
奇怪的是,这似乎只在某些版本的GCC中失败,而且只适用于32位。我还没有试过GCC 5

我感谢你的想法/建议

如果在为共享库或应用程序构建时未使用-static libstdc+,则它可以工作

通常,您应该避免使用
-static libstdc++
,或者隐藏其所有符号以避免此类问题

因此,我怀疑问题与应用程序和So之间的符号混淆/重复有关

对。特别是,问题是一些符号是重复的,而另一些符号不是。出于这个原因,我们不得不使用独特的符号

如果我让代码先用(RTLD_LAZY | RTLD_DEEPBIND)加载.so,然后关闭它并仅用RTLD_LAZY重新加载,它也可以工作

这是因为
dlclose
在使用库时实际上不会卸载库。从
man dlclose

The function dlclose() decrements the reference count on the dynamic
library handle handle.  If the reference count drops to zero and no
other loaded libraries use symbols in it, then the dynamic library
is unloaded.

您应该能够通过在
dlclose
之后停止GDB中的程序并查看其
/proc/$PID/maps
——很可能会发现
libfunctions。因此
仍然存在于内存中。

所有好信息。一些后续问题:(1)鉴于这是一个复制符号的问题,为什么它可以与某些版本的GCC和相同版本的GCC配合使用,但使用64位构建?;(2) 由于示例程序实际上没有对加载的库执行任何操作(只需调用dlopen,然后调用dlclose),我想知道为什么它不会被卸载;(3) 有没有一种简单的方法可以隐藏libstdc++的所有符号?
#include <iostream>
#include <dlfcn.h>

int main(int argc, char * argv[])
{
  void * ph(NULL);

  if(argc == 2 && argv[1][0] == '1')
  {
     std::cout << "Calling dlopen with flags RTLD_LAZY | RTLD_DEEPBIND..." << std::flush;
     ph = dlopen("./libfunctions.so", RTLD_LAZY | RTLD_DEEPBIND);
     std::cout << "done.  Result: " << ph << std::endl;
     if(ph)
        dlclose(ph);
  }

  std::cout << "Calling dlopen with flags RTLD_LAZY..." << std::flush;
  ph = dlopen("./libfunctions.so", RTLD_LAZY);
  std::cout << "done.  Result: " << ph << std::endl;
  if(ph)
       dlclose(ph);

  return 0;
}
$ g++ -m32 -g -fPIC -c functions.cpp -o functions.o
$ g++ -m32 -g -fPIC -shared -Wl,-soname,libfunctions.so -static-libgcc -static-libstdc++ functions.o -o libfunctions.so
$ g++ -m32 -g -fPIC -static-libgcc -static-libstdc++ main.cpp -l dl -o main
$ ./main 
Calling dlopen with flags RTLD_LAZY...Segmentation fault (core dumped)
$ gdb -c ./core ./main
GNU gdb (GDB) 7.9.1
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...done.
[New LWP 19846]

warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?
Core was generated by `./main'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  __atomic_add_single (__val=1, __mem=0x0)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:74
74    { *__mem += __val; }
(gdb) bt
#0  __atomic_add_single (__val=1, __mem=0x0)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:74
#1  __atomic_add_dispatch (__val=1, __mem=0x0)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/ext/atomicity.h:98
#2  _M_add_reference (this=0x0)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/bits/locale_classes.h:510
#3  std::locale::locale (this=0xb74f7ffc <__gnu_internal::buf_cout_sync+28>)
    at /home/test/dev/3rdParty/gcc/gcc-4.9.3/libstdc++-v3/src/c++98/locale_init.cc:223
#4  0xb746f559 in basic_streambuf (this=<optimized out>)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/streambuf:466
#5  stdio_sync_filebuf (__f=0xb76a2a20 <_IO_2_1_stdout_>, this=<optimized out>)
    at /home/test/dev/3rdParty/gcc/build/i686-pc-linux-gnu/libstdc++-v3/include/ext/stdio_sync_filebuf.h:77
#6  std::ios_base::Init::Init (this=0xb74f7a01 <std::__ioinit>)
    at /home/test/dev/3rdParty/gcc/gcc-4.9.3/libstdc++-v3/src/c++98/ios_init.cc:85
#7  0xb7469419 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535)
    at /home/test/dev/3rdParty/build_toolchain/include/c++/4.9.3/iostream:74
#8  0xb7469456 in _GLOBAL__sub_I_functions.cpp(void) () at functions.cpp:12
#9  0xb772c25e in ?? () from /lib/ld-linux.so.2
#10 0xb772c35a in ?? () from /lib/ld-linux.so.2
#11 0xb7730622 in ?? () from /lib/ld-linux.so.2
#12 0xb772c117 in ?? () from /lib/ld-linux.so.2
#13 0xb772fdf4 in ?? () from /lib/ld-linux.so.2
#14 0xb76edcae in ?? () from /lib/libdl.so.2
#15 0xb772c117 in ?? () from /lib/ld-linux.so.2
#16 0xb76ee3b6 in ?? () from /lib/libdl.so.2
#17 0xb76edd61 in dlopen () from /lib/libdl.so.2
#18 0x0804e102 in main (argc=1, argv=0xbfadc254) at main.cpp:18
The function dlclose() decrements the reference count on the dynamic
library handle handle.  If the reference count drops to zero and no
other loaded libraries use symbols in it, then the dynamic library
is unloaded.