簡體   English   中英

我可以獲得未處理(目標)C ++異常的堆棧跟蹤嗎?

[英]Can I get a stack trace for un-handled (Objective) C++ exceptions?

我正在開發一個最近已經發展成為一個大型C ++庫的iOS應用程序。 C ++不是我的強項,我對異常感到沮喪。 我正在尋找的是一種將堆棧跟蹤到(未處理的)異常拋出的站點的方法。 我會說“未處理”限定符是可選的; 盡管未處理的異常是理想的,但我會決定打破任何異常拋出作為最后的手段。

我目前得到的是沒用的。 假設我在callstack上面沒有任何適當的異常處理程序,我會做類似的事情

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

該應用程序將在main()中斷,我將收到一條日志消息,說“終止稱為拋出異常”。 沒用。

將通用try / catch塊放在callstack的上方也無濟於事,因為在異常處理期間,callstack在catch塊的點處被解開,讓我對實例的異常原點一無所知。 這也適用於提供我自己的terminate_handler 斷言更有用,但它們要求我在某種程度上預測錯誤條件,這是我不能總是這樣做的。 我仍然希望調試器能夠介入,即使意外的異常使它超過我的先發制人的assert()

我想要避免的是必須包裝每個可能在try / catch塊中拋出異常的調用,只是為了讓堆棧跟蹤錯誤。 在運行時,我真的對捕獲這些異常不感興趣。 當它們發生時,意味着程序執行中存在致命缺陷,並且它無法正常繼續。 我只是想得到通知,所以我可以確定原因並修復問題,這樣就不會再發生了。


在Objective C中,我可以在objc_exception_throw上放置一個符號斷點,任何時候我搞砸了什么,我會立即中斷執行並呈現一個很好的堆棧跟蹤,所以我知道問題出在哪里。 很有幫助。

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

C ++似乎對Exceptions有不同的用法。 它們習慣於處理致命錯誤常規錯誤(至少在我正在使用的第三方庫中)。 這意味着我可能實際上並不想打破C ++中引發的每個異常,但如果我不能僅僅處理未處理的異常,我仍然會發現這種能力很有用。

您可以在Xcode中快速建立所有C ++拋出條件的中斷:

  • cmd+6
  • + ”按鈕 - >添加異常斷點
    • C ++ - > std::out_of_range
    • 在扔

更新

如果您有很多過濾器,您可能更願意:

  • 創建一個符號斷點
  • 符號= __cxa_throw (可能因std庫而異)
  • 操作>調試器命令= bt
  • eval = On后自動繼續

bt命令記錄回溯。 以這種方式配置,它將自動繼續。

因此,這將只記錄每個拋出異常的回溯 - 當程序由於未處理的異常而終止時,線索將在最終記錄的回溯中(通常是最后一個,除非庫重新拋出)。

在應用程序中我使用許多c ++異常進行調試,我將“Catch C ++ Exceptions on Throw”關閉,直到我到應用程序中它將拋出異常,然后我打開該選項,通常是下一個異常被拋出的是我正在尋找的。 這將比錯誤的位置更深一些,但堆棧是完整的,所以你可以弄清楚發生了什么。

檢查PLCrashReporter 我們將它與我們的應用程序(它嚴重依賴於C ++)一起使用,它甚至為C ++代碼生成堆棧跟蹤。

您可能遇到的唯一問題是當使用本身不是為iOS編寫的匯編程序時(Apple的編譯器使用R7來保存堆棧幀以跟蹤符號,這不符合官方ARM EBI)

暫無
暫無

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

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