2012-03-27 74 views
4

我想在這裏做一些小事,但文檔建議它應該是可能的。也許LLDB仍然太新了,但是我得到了很多調試器崩潰/死鎖,即使沒有發生這種情況,它看起來並不像我預期的那樣工作。iOS:LLDB多行斷點命令不能按預期工作

我想把所有選擇器調用的調試包裝在一起,以提取特定塊代碼內的消息調用圖。 (我可以解釋爲什麼如果你真的想知道,但它與調試器問題並不真正相關。)

我開始用Xcode斷點來開始跟蹤事物(對於獎勵點,這是發生在輔助線程,但我可以告訴大家,沒有,沒有任何其他線程正在做它的屬性子給該對象的任何訪問或任何東西):

[myObject startProcessing]; 

斷點觸發,和我運行「bt」,只是爲了提取:

* thread #5: tid = 0x2203, 0x000277d2 ......... 

然後我做一些事情溫和地邪惡:我在objc_msgSend中放置了一個斷點,就在它向真實對象選擇器調用的指令處。 objc_msgSend的樣子:

libobjc.A.dylib`objc_msgSend: 
...(instructions)... 
0x37babfa4: bx  r12 
...(more instructions)... 

(實際上有兩個BX電話,但讓我們保持簡單。)我運行:

breakpoint set -a 0x37babfa4 -t 0x2203 

(TID包括在內,因爲我有足夠多的麻煩追蹤這一個線程,我不需要無關的東西干擾。)

這裏是腳本進來的地方。上面描述的設置完全按照我喜歡的方式工作。如果我繼續執行,直到斷點觸發,我可以運行:

frame select 0 
thread step-inst -m this-thread 5 
frame info 
continue 

,效果將是調試器:

  • 移動到objc_msgSend幀由一個指令
  • 步驟,推進它進入它指向的對象選擇器框架
  • 顯示相關詳細信息(對象類型,選擇器調用)
  • 恢復執行

在這一點上,我可以反覆粘貼這四個命令並複製輸出,直到我討厭自己。

如果,另一方面,我跑:

breakpoint command add -s command 

,並在這些完全相同的命令,一切都休息粘貼。它不會前進到對象選擇框。它不顯示框架細節,或者至少不是正確的 - 取決於各種調整(見下文),它可能會或可能不會顯示「objc_msgSend」作爲當前函數。它不會恢復執行。

在這種情況下,如果我能得到這個例子的工作,我會大部分是快樂的。但對於更多獎勵積分,我也有蟒蛇試過這個,我寧願因爲這將讓更多的複雜的日誌記錄:

breakpoint command add -s python 
> thread = frame.GetThread() 
> thread.StepInstruction(1) 
> newFrame = thread.GetFrameAtIndex(0) 
> print " " * thread.GetNumFrames() + newFrame.GetFunctionName() 
> process = thread.GetProcess() 
> process.Continue() 
> DONE 

同樣沒有好處。再次取決於微小的細節,這可能或可能不打印東西(通常是objc_msgSend),但它從不打印正確的東西。它從不向前推進教學。之後它永遠不會恢復執行。

再次,如果我手動操作,python版本可以正常工作:如果我等到斷點觸發,然後運行「腳本」並輸入完全相同的行,則按預期工作。有些部件甚至會孤立地工作,例如如果我除了獲取進程的部分以及調用process.Continue()並且自動觸發這些部分,那麼「有效」(意味着我看到lldb提示在它暫停並恢復執行時快速閃爍,通常我後悔這是因爲它變成了沒有反應,崩潰後不久)。

所以:任何想法?技術尚未準備好,還是我錯過了一些可以修復一切的難題?或者我應該完全放棄,只是住在一起的事實,有對象的內部,我將永遠不會明白?一些地方...

+0

在使用LLDB進行調試時,SO報告存在其他問題。我知道的一個問題(但找不到裁判文件)報道了切換回GDB時出現的問題。我猜這不是* gasp *成熟的產品。 – 2012-03-27 21:57:50

+0

@PeterM:是的,我從來沒有(很多)麻煩gdb是越野車,但它的功能是更多像這樣更花哨的東西更多的限制。也許我需要切換回去,然後再嘗試幾個版本,但... – Archaeopterasa 2012-03-27 23:26:12

回答

3

斷點命令無法繼續執行,然後再取回控制,至少今天。有很多未解決的問題,如果斷點1正在運行該過程,然後命中斷點2,會發生什麼情況。除了代碼庫是否可以正確處理嵌套斷點(它被設計爲......)的整個問題之外,如果斷點2決定執行應該停止,這意味着什麼?斷點1的狀態被拋棄了嗎?

似乎有點深奧的是擔心斷點在踩下劣質過程時碰到另一個斷點,但除非所有細節都已經制定出來,否則用戶很容易在腳中自拍。所以對於今天來說,斷點命令可以在斷點被擊中或繼續運行時停止 - 但是沒有任何運行一點點和做更多處理的能力。我知道這對於某些任務來說是非常有用的功能,但在完成之前還有很多需要考慮的問題。

在某些情況下,有可能圍繞處理它的其他方式...如果你想停止功能parser()只有當它已被稱爲功能lexer(),很容易把一個斷點lexer()一些一些python命令可以將一個堆棧幀放到堆棧中,並查看調用函數是什麼。如果不是lexer(),請繼續。不過,我認爲這不會適用於你想要做的事情。