使用 -O1 优化标志编译项目时共享库崩溃
Shared library crash when project compiled with -O1 optimization flag
问题:
我正在将新的共享库连接到项目。它加载了运行时动态链接。
这个新的共享库正在调用另一个共享库。
如果项目是用-O0
标志编译的 - 一切正常。
如果项目是用-O1
标志编译的 - 这个新库调用的库将获得
无效的free((/delete/delete[]/realloc((
崩溃总是与std::string
、basic_string
或std::basic_stringbuf
有关。
被啄了什么:
Valgrind在崩溃前在应用程序中没有出现任何问题。
我尝试:
- 将库从运行时动态链接更改为加载时动态链接
- 检查 lib 是否使用与我的相同的 gcc 编译 (
4.4.7
( - 似乎是这样,至少 grep 在 .so 文件中找到了 GCC 4.4.7。
回溯
从Valgrind运行:核心转储堆栈具有各种底部,但上部通常如下所示:
==46601== Invalid free() / delete / delete[] / realloc()
==46601== at 0x4C287CA: operator delete(void*) (vg_replace_malloc.c:507)
==46601== by 0xF5BE9A6: std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::overflow(int) (in /usr/lib64/libstdc++.so.6.0.13)
==46601== by 0xF5C2AB4: std::basic_streambuf<char, std::char_traits<char> >::xsputn(char const*, long) (in /usr/lib64/libstdc++.so.6.0.13)
==46601== by 0xF5A8C7F: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib64/libstdc++.so.6.0.13)
==46601== by 0xF5A8E25: std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (in /usr/lib64/libstdc++.so.6.0.13)
==46601== by 0xF5BC43D: std::ostream& std::ostream::_M_insert<long>(long) (in /usr/lib64/libstdc++.so.6.0.13)
.......
==46601== Address 0xf81a2c0 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE"
==46601== Invalid free() / delete / delete[] / realloc()
==46601== at 0x4C287CA: operator delete(void*) (vg_replace_malloc.c:507)
==46601== by 0xF5C4564: std::string::assign(std::string const&) (in /usr/lib64/libstdc++.so.6.0.13)
==46601== by 0x21632E52: operator= (basic_string.h:511)
==46601== by 0x21632E52: str (sstream:129)
==46601== by 0x21632E52: str (sstream:557)
.........
==46601== Address 0xf81a2c0 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE"
==46601== Invalid free() / delete / delete[] / realloc()
==46601== at 0x4C287CA: operator delete(void*) (vg_replace_malloc.c:507)
==46601== by 0x2308A103: _M_dispose (basic_string.h:236)
==46601== by 0x2308A103: ~basic_string (basic_string.h:503)
.......
==46601== Address 0x67b2c0 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4"
编辑:D_GLIBCXX_FULLY_DYNAMIC_STRING
宏有所帮助。
现在my project -O1
:so.file -O0
作品my project -O1
:so.file -O1
失败
问题
我没有这些库的代码。 我想知道我还能做些什么来解决这个问题。
调查的下一步应该是什么?
调查的下一步应该是什么?
您应该开始调试。 通常,错误在-O0
时"侥幸逃脱",只是在优化稍微加快时才会受到重创。
因为我不知道你的代码,我只能猜测。
我假设您创建了某种仅由共享库使用的对象。可能是某种样板。你把它传递给你的共享库,它会对它做一些事情,然后删除它。
由于您从未在自己的代码中读取此变量,因此编译器很有可能将其优化掉。
要解决您的问题,您必须找到该特定变量并用volatile
标记它,以防止它的形式被优化掉。
祝你好运。
$ c++filt _ZNSs4_Rep20_S_empty_rep_storageE
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_empty_rep_storage
_S_empty_rep_storage
声明为:
// The following storage is init'd to 0 by the linker, resulting
// (carefully) in an empty string with one reference.
static size_type _S_empty_rep_storage[];
并定义为:
// Linker sets _S_empty_rep_storage to all 0s (one reference, empty string)
// at static init time (before static ctors are run).
template<typename _CharT, typename _Traits, typename _Alloc>
typename basic_string<_CharT, _Traits, _Alloc>::size_type
basic_string<_CharT, _Traits, _Alloc>::_Rep::_S_empty_rep_storage[
(sizeof(_Rep_base) + sizeof(_CharT) + sizeof(size_type) - 1) /
sizeof(size_type)];
看起来您加载的共享库具有另一个(较旧的(_S_empty_rep_storage
定义。在旧版本的 GNU C++库中,_S_empty_rep_storage
曾经是动态分配的,这就是为什么该共享库试图执行delete _S_empty_rep_storage
并崩溃的原因。
解决方法是针对使用相同C++编译器和链接器选项使用的C++库重新编译共享库。
我得到了第 3 个 pt 库源代码,事实证明它也确实 dlopen 并且发生了以下错误:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42679
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 当回溯以零开始时,如何调试崩溃
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 在cuda线程之间共享大量常量数据
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 如何从具有移动语义的类对象中生成共享指针
- Linux 可执行文件通过 dlopen 在emplace_back崩溃打开共享库
- Linux c++.在预加载的共享库中定义的基类的崩溃调用函数
- 使用 -O1 优化标志编译项目时共享库崩溃
- 调用共享C++函数时 Python 内核崩溃
- 当从共享库运行时,为什么此Android NDK代码崩溃
- 第二次调用共享对象时崩溃
- 来自新手用户的共享指针查询.我下面的代码在使用带有成员共享指针的类容器时崩溃
- 同名类之间的共享 vtables:强制转换为基类型时,对虚拟方法的调用崩溃
- C++中的共享内存崩溃
- 当链接到两个第三方共享库时,c++程序崩溃
- 由多个线程共享的Ofstream -一段时间后崩溃
- 共享内存环形缓冲区崩溃
- Android C++应用程序在链接到共享库阶段时崩溃