2015-02-23 82 views
1

libC++是否維護一個進程範圍的內部狀態,其中在代碼的一部分中發生的操作可以通過調用std :: * classes(例如std :: set)來影響代碼的某些遠端部分?要多一點具體的我見過崩潰像這樣(只顯示堆棧跟蹤的頂部):libC++是否保持內部狀態?

std::__1::__tree<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::less<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >::__insert_unique(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) + 156, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)

,其中修復了升級不直接發生碰撞庫,以糾正一個C++ ABI問題。我只是感到驚訝,一個ABI問題可能會對此產生影響,並且懷疑標準庫本身是否存在某種狀態損壞?

+3

全局'operator new'和'operator delete'維護每個進程的堆。它們被'std :: allocator'使用,所以(默認情況下)被任何分配內存的標準類使用,並且似乎在這裏被牽連。破壞堆可能會破壞使用它的任何其他代碼。 – 2015-02-23 18:27:27

+1

'std :: __ 1'的錯誤通常表示您使用的是LLVM的** libC++ **,而不是GNU的** libstdC++ **。 – Macmade 2015-02-23 18:27:37

+0

@Macmade好點讓我重新安排我的問題在一瞬間...... – wilsonmichaelpatrick 2015-02-23 18:33:23

回答

5

C++不提供受保護的環境。如果代碼的任何部分都做了禁止的事情(例如刪除一個對象兩次,註銷一個數組的限制......),那麼代碼的任何其他位置都可以立即執行或在很長時間之後執行任何操作。

其實通常的問題是,錯誤只是顯然不會造成任何傷害,因爲該程序(顯然)只是工作。

有關違反ABI的錯誤是非常低的水平(例如機器碼可能需要保留某個寄存器,而不是),並且沒有什麼可以讓您驚訝的。歡迎來到「未定義的行爲」地獄。

在特定的std::setstd::map在某些實施方式中已知取決於標記,因此覆蓋全局變量甚至會影響稍後創建的映射和集合。

幾乎在C++中的所有內容都依賴於動態分配的內存,並且違反ABI的程序可能會破壞與之相關的數據結構,並且該效果可能會在稍後顯示數百萬條執行的指令(例如,損壞的空閒塊被重新分配給某些內容其他)。