2012-10-04 16 views
4

我有一個gdb腳本我正在努力跟蹤所有通過objc_msgSend傳遞的Objective-C方法調用,但是我遇到了一個我似乎無法處理的問題。在回顧了Objective-C運行時源代碼之後,我開發了以下腳本來在objc_msgSend的每個中斷處打印[]。問題是有些情況下data_NEVER_USE不是有效的指針,但也不爲空。我能找到一個類是否初始化的唯一指標是在id-> data_NEVER_USE-> flags & RW_REALIZED。我在這裏丟失了哪些類初始化的內容,可以讓我跳過這種情況?GDB腳本跟蹤在iOS設備上的Objective-C調用 - 問題

b objc_msgSend 
c 
commands 
silent 

if (*$r0 == 0) 
    continue 
end 

set $id = (class_t *)$r0 
set $sel = $r1  
print *$id 
if($id->data_NEVER_USE != 0) 
    set $data = (class_ro_t *) ($id->data_NEVER_USE) 
    if (($data->flags & 0x80000000) && ($data->name)) 
     set $classname = $data->name 
     printf "[%s ", $classname 
    else 
     continue 
    end 
end 

if ($sel != 0) 
    printf "%s", $sel 
else 
    printf "null" 
end 

printf "]\n" 
continue 
end 

我很感激這方面的幫助。謝謝。

+0

感謝您的鏈接。不幸的是,使用模擬器不是一種選擇。對我來說最有用的方法是允許在物理設備上進行跟蹤,而無需訪問源代碼。 –

回答

6

這兩種方法對我來說工作得很好。請注意,在我的示例中,我手動啓動「SomeApp」,以便在啓動後立即對其進行監視。

gdb 
(gdb) attach --waitfor 'SomeApp' 

**this is where you manually start SomeApp on your device** 

call (void)instrumentObjcMessageSends(YES) 

「instrumentObjcMessageSends」啓用/禁用運行時內的消息記錄。下面是一些more information on this method.

另一種選擇,再次對您的iDevice仍然使用GDB,就是寫一個小的命令是這樣的:只要你按「C」(右上面一行讀取

FooPad:~ root# gdb 
(gdb) attach SBSettings 
Attaching to process 440. 
Reading symbols for shared libraries . done 
Reading symbols for shared libraries ............................. done 
0x35686004 in mach_msg_trap() 

(gdb) break objc_msgSend 
Breakpoint 1 at 0x3323ef72 

(gdb) commands 
Type commands for when breakpoint 1 is hit, one per line. 
End with a line saying just "end". 

>printf "-[%s %s]\n", (char *)class_getName(*(long *)$r0,$r1),$r1 
>c 
>end 

(gdb) c 
Continuing. 
// a ton of information will follow 

「繼續。」,你的屏幕將與函數名和參數填寫

最後跟着these instructions獲得工作GDB您的iDevice爲後人我會後的簡短說明此處。

GNU調試器(gdb)用於分析iOS 應用程序的運行時行爲。在最近的iOS版本中,從Cydia直接下載的GNU調試器 已損壞,無法正常運行。繼 Pod 2g博客文章也沒有幫助我。

要解決此問題,請將http://cydia.radare.org添加到cydia 源文件並下載最新的GNU Debugger(版本1708)。 GDB構建 1708適用於iOS 5.x.