3 回答

TA貢獻1828條經驗 獲得超4個贊
通過TC的回答類似的問題的啟發在這里,我把一個調試斷點動作,將注銷類和方法名,每objc_msgSend()時觸發您的應用程序。這與我在此答案中描述的DTrace腳本類似。
要啟用此斷點操作,請創建一個新的符號斷點(在Xcode 4中,轉到斷點導航器并使用窗口左下方的加號創建一個新的符號斷點)。將符號objc_msgSend設置為,將其設置為在評估操作后自動繼續,然后使用以下命令將該操作設置為調試器命令:
printf "[%s %s]\n", (char *)object_getClassName(*(long*)($esp+4)),*(long *)($esp+8)
您的斷點應如下所示:
斷點動作
在針對您的應用程序運行時,這應該注銷以下消息:
[UIApplication sharedApplication]
[UIApplication _isClassic]
[NSCFString getCString:maxLength:encoding:]
[UIApplication class]
[SLSMoleculeAppDelegate isSubclassOfClass:]
[SLSMoleculeAppDelegate initialize]
如果您想知道我在哪里提取了內存地址,請閱讀有關Objective-C運行時內部的Phrack文章。上面的內存地址僅適用于Simulator,因此您可能需要進行調整才能針對iOS設備上的應用程序運行。Collin建議在回答中進行以下修改以在設備上運行該修改:
printf "[%s %s]\n", (char *)object_getClassName($r0),$r1
另外,我認為您會發現注銷應用程序中調用的每個方法都會使您不知所措。您也許可以使用一些條件來對此進行過濾,但是我不知道這是否可以幫助您了解代碼的執行方式。

TA貢獻1836條經驗 獲得超13個贊
如果使用的是LLDB,則需要使用以下調試器命令。這些已在Xcode 4.6中進行了測試。
設備:
expr -- (void) printf("[%s %s]\n", (char *)object_getClassName($r0),$r1)
模擬器:
expr -- (void) printf("[%s %s]\n", (char *)object_getClassName(*(long*)($esp+4)), *(long *)($esp+8))

TA貢獻1799條經驗 獲得超6個贊
可以使用debugger命令將Brad Larson的方法調整為在設備上運行:
printf "[%s %s]\n", (char *)object_getClassName($r0),$r1
可以在此處的技術說明中找到更多信息:technotes
- 3 回答
- 0 關注
- 471 瀏覽
添加回答
舉報