在objective-c中,函數cal被轉換爲objc_msgSend。例如如何跨越lldb中的objc_msgSend函數?
[foo doSomething:@"keke"]
被翻譯成
objc_msgSend(foo, "doSomething:", @"keke")
我怎麼能直接一步foo.doSomething:
而LLDB調試?
在objective-c中,函數cal被轉換爲objc_msgSend。例如如何跨越lldb中的objc_msgSend函數?
[foo doSomething:@"keke"]
被翻譯成
objc_msgSend(foo, "doSomething:", @"keke")
我怎麼能直接一步foo.doSomething:
而LLDB調試?
lldb確實提供了可以控制步驟邏輯的線程計劃。
class GotoUser:
def __init__ (self, thread_plan, dict):
self.start_time = time.time()
self.thread_plan = thread_plan
target = self.thread_plan.GetThread().GetProcess().GetTarget();
module = target.GetModuleAtIndex(0)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.start_address = sbaddr.GetLoadAddress(target)
module = target.GetModuleAtIndex(1)
sbaddr = lldb.SBAddress(module.GetObjectFileHeaderAddress())
self.end_address = sbaddr.GetLoadAddress(target)
print "start addr: ", hex(self.start_address), " end addr: ", hex(self.end_address)
def explains_stop (self, event):
if self.thread_plan.GetThread().GetStopReason()== lldb.eStopReasonTrace:
return True
else:
return False
def should_stop (self, event):
cur_pc = self.thread_plan.GetThread().GetFrameAtIndex(0).GetPC()
if cur_pc >= self.start_address and cur_pc <= self.end_address:
self.thread_plan.SetPlanComplete(True)
print 'time used ', (time.time() - self.start_time)
return True
else:
return False
def should_step (self):
return True
創建一個python腳本,將它加載到lldb。 運行thread step-scripted gotouser.GotoUser
。
任務完成。
完整的源代碼: https://github.com/Jichao/lldb-scripts/blob/master/gotouser.py
版本內置LLDB: https://github.com/Jichao/lldb
使用Python線程計劃是聰明!但你不應該這樣做ObjC消息。 lldb知道objc_msgSend &其他幾個是ObjC消息的調度函數。因此,如果一個step in
以objc_msgSend結尾,lldb會從傳入的對象/選擇器對中找出方法實現,並在那裏設置一個斷點,然後繼續。
例如:
(lldb) run
Process 55502 launched: '/private/tmp/trivial' (x86_64)
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: main , stop reason = breakpoint 1.1
frame #0: 0x0000000100000f28 trivial`main at trivial.m:18
15 main()
16 {
17 Trivial *my_foo = [[Trivial alloc] init];
-> 18 [my_foo doSomething];
19 return 0;
20 }
(lldb) s
Process 55502 stopped
* thread #1: tid = 0x32619ba, function: -[Trivial doSomething] , stop reason = step in
frame #0: 0x0000000100000ed7 trivial`-[Trivial doSomething] at trivial.m:10
7 @implementation Trivial
8 - (void) doSomething
9 {
-> 10 NSLog(@"%@ called doSomething.", self);
11 }
12 @end
13
所以在這種情況下的實際消息接收器停止了一步。如果這不是你正在發生的事情,很可能是欺騙了lldb的那部分對象/選擇器 - >實現查找。我必須知道更多關於你的代碼的信息,才能弄清楚爲什麼會這樣。
那是因爲你有源代碼 – Jichao
啊,是的,這是一個獨立的問題。默認情況下,如果「步入」到達沒有調試信息的函數,lldb將不會停止,但會反過來退出。 「step」命令有一個標誌來控制這種行爲:'--step-in-avoidids-no-debug'或簡稱'-a'。如果將其設置爲false,那麼步入將停止在目標方法中,而不管它是否具有調試信息。還有一個通用設置:'target.process.thread.step-in-avoid-nodebug',您可以設置(使用'set set')命令來全局控制這種行爲,如果這更符合您的口味。 –