簡體   English   中英

使用 -O1 優化標志編譯項目時共享庫崩潰

[英]Shared library crash when project compiled with -O1 optimization flag

問題:

我正在將新的共享庫連接到項目。 它加載了運行時動態鏈接。
這個新的共享庫正在調用另一個共享庫。

如果項目是用-O0標志編譯的 - 一切正常。
如果項目是用-O1標志編譯的 - 這個新庫調用的庫正在獲取

無效的 free()/delete/delete[]/realloc()

崩潰總是與std::stringbasic_stringstd::basic_stringbuf相關聯。

檢查的內容:

Valgrind 在崩潰前在應用程序中沒有顯示任何問題。

我試圖:

  • 將 lib 從運行時動態鏈接更改為加載時動態鏈接
  • 檢查 lib 是否使用與我的 ( 4.4.7 ) 相同的 gcc 編譯 - 似乎是這樣,至少 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 -O0so.file -O0有效
my project -O1 so.file -O1so.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-rd pt 庫源代碼,結果它也執行 dlopen 並出現以下錯誤: https ://gcc.gnu.org/bugzilla/show_bug.cgi ? id = 42679

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM