天天看點

xcode反彙編調試iOS模拟器程式(三)檢視Objective-C函數與參數

在Objective-C函數的入口處(第一行)加斷點,可用esp指針來探查參數。

以esp為基址,往後的偏移分别是:

0:函數執行完畢後的傳回位址(不是傳回值的位址哦)

4:對象執行個體的指針,即self指針

8:selector,實際是一個char數組型的字元串,即char*

12:(如果有)第一個參數

…(前一個參數的基址+前一個參數所占的位元組數):(如果有)第n個參數

由此,要調試這樣一個函數

時,斷點後可在gdb這樣調試:

po *(id*)($esp+4)                  // 得到對象執行個體的描述。執行越過函數頭部後,應為 po *(id*)($ebp+8),以下類同。

p (char*)*(SEL*)($esp+8)     // 得到selector的名字

po *(id*)($esp+12)               // 得到p1的description

p *(CGRect*)($esp+16)       // 得到p2的各個成員值,輸出結果為:“(CGRect) $1 = origin=(x=10, y=20) size=(width=30, height=40)”

p *(CGPoint*)($esp+32)   // 因為一個CGRect結構體占16位元組(4個float),是以是“+32”,即“+16+16”, 得到p3的各個成員值,輸出結果為:“(CGPoint) $4 = (x=50, y=60)”

po *(id*)($esp+40)       // 因為一個CGPoint結構體占8位元組(2個float),是以是“+40”,即“+32+8”、得到p4的description

注意:由于在第一行,push了ebp,會導緻esp被修改,而第二行又立刻把esp的值賦給ebp,是以在執行經過函數的這些頭部後,可以用ebp類似地通路,不過參數的偏移都需要+4。

下面是如何檢視浮點型參數。

浮點型參數會通過SSE寄存器來傳遞,可以在gdb中這樣檢視:

(lldb不能用上面的指令,暫沒去研究用什麼替代)

例如調試上例中的

編譯器會把參數反序送入xmm寄存器組,即40傳入xmm0,30傳入xmm1……

在CGRectMake加斷點,執行到下圖中的位置時輸入指令

指令結果如下:

因為SSE寄存器是128位的,gdb并不知道哪些bit是有意義的,是以列出了一些猜測的結果。

我們傳入的是CGFloat,即float,故v4_float = {0, 0, 0, 40} 是有意義的。

當傳入的是double型,則v2_double有意義。

xcode反彙編調試iOS模拟器程式

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8697654">(一)檢視反彙編</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8700964">(二)看懂反彙編</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8721870">(三)檢視Objective-C函數與參數</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8752235">(四)自動斷點應用之NSNotificationCenter</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8755491">(五)調試objc_msgSend函數</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8766487">(六)函數出入口處的處理與局部變量</a>

<a target="_blank" href="http://blog.csdn.net/hursing/article/details/8766719">(七)Debug與Release的差別</a>

繼續閱讀