2016-06-09 20 views
2

在Mac OS X和iOS模擬器(均爲x86)中,我們可以使用內聯彙編中的int3指令將其捕獲到調試器(LLDB)。這很好,因爲它陷入了一個特定的代碼行,但我們可以通過在調試器中點擊繼續來立即繼續。如何陷入調試器並繼續iOS硬件?

有沒有辦法在iOS硬件上做到這一點?

An answer to an older question提及raise(SIGINT)據我所見(從檢查signal.h)不存在。另一個答案提到trap彙編指令,這會導致構建錯誤(「無法識別的指令助記符」)。同樣無法識別的是BKPT彙編指令mentioned in ARM documentation

我試過__builtin_trap()這差不多就是我想要的,但是不允許我繼續。除非我用jump +1register write pc `$pc+8\`手動前進指令指針,否則我會一直點擊它,這比繼續下去要方便得多。

我正在爲使用Xcode 7.3.1的32位和64位設備的iOS 9構建。任何幫助表示讚賞!

+1

downvoter,想解釋一下嗎? – Luke

+0

我想他downvoted你的問題,因爲signal()和SIGINT都是標準C的一部分。http://opensource.apple.com//source/xnu/xnu-1456.1.26/bsd/sys/signal.h – diegog

+0

raise (SIGINT)可以工作,但並不總是可靠的,有一段時間它會稍後停下來,並且您需要走線程樹以查找斷點的位置。我曾經使用這個解決方案,然後刪除。後來我發現ASSERT應該不再繼續下去,你應該面對它們而不是無視它們,爲什麼你想斷言呢? –

回答

1

蘋果的libc signal.h包括XNU的sys/signal.h,這定義SIGINT(在所有平臺上):

// [...] 

#define SIGHUP 1 /* hangup */ 
#define SIGINT 2 /* interrupt */ 
#define SIGQUIT 3 /* quit */ 
// [...] 

因此,雖然我無法確認這種做法確實工作(由於缺乏在iOS 9設備就我而言),阻礙你迴歸的障礙實際上不成問題。

至於彙編指令,BKPT是一個有效的ARM指令,但只適用於A32。 A64變體名爲BRK
如果您正在構建胖二進制文件並無條件使用其中任何一個,那麼您將始終遇到編譯器錯誤。

另請注意,這兩個指令都需要一個立即值(傳遞給調試器)。忽略該值也會產生編譯器錯誤。

這就是說,你應該能夠插入調試指令A32和A64用一個簡單的#if

#if __LP64__ 
asm volatile("BRK 0"); 
#else 
asm volatile("BKPT 0"); 
#endif 

您可以通過您選擇的0255之間的任意值代替0

TRAP指令的注意事項:雖然蘋果的彙編似乎接受這個指令A32,並將其轉換到0xe7ffdefe,它會發出關於A64的「無法識別的指令助記符」,類似於BKPT指令。
我也無法找到任何有關ARM信息中心或Apple文檔中的指令的參考。

+0

這裏有一些很棒的信息,謝謝!不幸的是,BRK/BKPT與__builtin_trap()具有相同的問題。我會再次嘗試SIGINT,看看會發生什麼。 – Luke

+0

SIGINT和SIGTRAP確實在做我想做的事情,雖然堆棧比我想要的更深一層。謝謝! – Luke

+0

我很高興能夠提供幫助。 [另一個答案](https://stackoverflow.com/a/20713868)提到'SVC',它是'BKPT' /'BRK'的非調試對象 - 謹慎嘗試'asm(「SVC 0」) '與BKPT' /'BRK'有什麼不同? – Siguza