2012-02-29 97 views
6

我正在開發一個最近增長了大量C++基礎的iOS應用程序。 C++並不是我的專長,而且我因例外而感到沮喪。我正在尋找的是一種獲取堆棧跟蹤到(未處理)異常拋出的站點的方法。我會說「未處理」限定符是可選的;我會打破任何異常拋出作爲最後的手段,雖然未處理的例外是理想的。我可以獲得未處理(目標)C++異常的堆棧跟蹤嗎?

我目前得到的是無用的。假設我沒有任何相應的異常處理程序越往上調用堆棧,我這樣做

std::vector<int> my_vector; 
my_vector.at(40) = 2; // Throws std::out_of_range 

應用程序將在main()突破,我會得到一個日誌消息說「終止稱爲拋出異常。」沒有幫助。

將通用try/catch塊放在callstack的上方也沒有幫助,因爲callstack在異常處理期間解除了catch塊的位置,使得我不知道異常的實際來源。這也適用於提供我自己的terminate_handler。斷言更有用,但它們要求我在某種程度上預測錯誤情況,這是我不能總是這樣做的。即使意外的異常超過了我的先發制人的assert()s,我仍然希望調試器能夠進入。

我想避免的是不得不將每個可能在try/catch塊中引發異常的調用都包裝起來,以便將堆棧跟蹤發送到錯誤。在運行時,我真的不想捕捉這些異常。當它們發生時,這意味着程序執行中存在一個致命的缺陷,並且它無法正常繼續。我只是想得到通知,所以我可以確定原因並修復問題,以免再次發生。


在Objective C,我可以把一個象徵性的斷點objc_exception_throw,任何時候我擰的東西了,我會立即中斷執行,並用一個漂亮的堆棧跟蹤信息呈現,所以我知道在哪裏的問題。很有幫助。

我意識到這種行爲實際上只是有用的,因爲兩種語言之間異常處理的哲學差異。 Objective C異常僅用於表示不可恢復的錯誤。常規錯誤處理的任務是通過錯誤返回碼完成的。這意味着任何客觀的C異常是一個很好的開發人員斷點的候選人。

C++似乎對Exceptions有不同的用處。它們用於處理致命錯誤例行錯誤(至少在我正在使用的第三方庫中)。這意味着我可能並不想在C++中拋出任何異常,但如果我不能僅在未處理的異常中分解,我仍然會發現該功能很有用。

+0

C●彙編程序時

你可能有唯一的問題是++異常並不是真正用於_routine_錯誤,但它們有時會被濫用。確實,他們不僅僅是因爲不可恢復的錯誤。 – bames53 2012-02-29 22:27:28

回答

5

你可以快速建立在所有C休息++扔條件在Xcode:

  • cmd+6
  • +」 按鈕 - >添加例外斷點
    • C++ - >std::out_of_range
    • 在投擲

更新

如果你有很多他們的壽過濾掉,你可能會喜歡:

  • 創建符號斷點
  • 符號= __cxa_throw(可能因標準庫而異)
  • 操作>調試器命令= bt
  • EVAL後自動繼續=開

bt命令日誌的回溯。按照這種方式配置,它將自動繼續。因此,這將只記錄每個拋出的異常的回溯 - 當程序由於未處理的異常而終止時,線索將會在最終的日誌回溯(通常是最後一次,除非庫重新拋出)之間。

+2

啊,在用戶界面中。完善。 – 2012-02-29 21:45:25

+0

但我掙扎。看起來你應該能夠只指定某些例外來打破。我使用的是ZXing,它在任何地方都會拋出異常(在正常操作期間每幀幾次)。我需要忽略這些。然而,當我在某些完全不相關的東西上設置斷點時,例如'std :: out_of_range',所有ZXing的std :: exception子類都會觸發斷點。這是正常的嗎? – 2012-02-29 22:15:31

+0

@MattWilding ok。用這個案例的另一個角度更新。 – justin 2012-02-29 23:12:21

1

在應用程序中,我得到許多C++異常進行調試,我將「Catch C++ Exceptions on Throw」關閉,直到我到達應用程序中將拋出異常的位置,然後打開該選項並通常下一個拋出的異常是我正在尋找的。這將會比錯誤發生的地方深入幾層,但堆棧完好無損,因此您可以確定發生了什麼。

0

檢查PLCrashReporter。我們將它與我們的應用程序(主要依賴C++)一起使用它,並且即使對於C++代碼也會生成堆棧跟蹤。使用這不是爲iOS的原生寫的(蘋果的編譯器使用R7來保存追溯不是根據官方的ARM EBI符號棧幀)

相關問題