其实无论调试什么,都会发现lldb的功能朴实的让人心急如焚。比如Windows调试器基本都会自动记录上一次的断点信息,每次调试时根据模块位置重新下好端点。
lldb可能天生就是为源码调试准备的,一旦没有源码,根据模块名+偏移的下端点方式它是无论如何都不能识别。好在它提供了python接口,方便开发调试插件弥补自身的缺陷。
所以与其说lldb是个调试器,不说它是个SDK,只有基于它开发出来的图形调试器才具备实用性。
那就来看看一些在Windows调试时不值得一提的简单操作,在lldb下该如何达阵
附加Flash进程
用Safari打开指定页面后,执行以下脚本lldb就会附加到包含Flash的进程上了
pid=$(ps aux | grep WebKit.Plugin | grep 64 | awk '{print $2}'|sort| tail -1) lldb -p $pid
搜索内存中的指定常数
由于没有查看memory layout的命令,只能借助vmmap,先找到比如malloc的内存区域,然后再逐一生成查找命令。以下命令用于从WebKit找到HeapSpray的特定字符:
pid=$(ps aux | grep Build | grep web | awk '{print $2}' | sort | tail -1) vmmap $pid | grep "WebKit Malloc " | grep "-" | awk '{print $3}' | awk -F '-' '{print "memory find -e '$1'","0x" $1, "0x" $2}
在模块固定偏移下断点
这个听起来是最稀松平常的任务了,比如打算在Flash的0x78A4C0偏移处下一个断点,而且要在每次lldb附加后自动完成。首先要编写一个lldb的插件,完成Flash模块基地址的查找和断点地址的计算,最后下断点:
import lldb import shlex import optparse import time def obreak(debugger, command, result, dict): command_args = shlex.split(command) parser = create_obreak_options() try: (options, args) = parser.parse_args(command_args) except: return if len(args) > 0: offset = int(args[0], 16) else: offset = 0x78A4C0 target = debugger.GetSelectedTarget() base = 0 for mod in target.modules: if mod.file.GetFilename() == "FlashPlayer-10.6": for sec in mod.sections: if sec.name == "__TEXT": base = sec.get_addr().load_addr address = base+offset target.BreakpointCreateByAddress(address) def create_obreak_options(): usage = "usage: %prog -f offset" description='''break on offset_belongs_to_Flash''' parser = optparse.OptionParser(description=description, prog='obreak',usage=usage) parser.add_option("-f", "--offset", dest="offset", help="break on certain offset of Flash", metavar="OFFSET") return parser def __lldb_init_module (debugger, dict): parser = create_obreak_options() obreak.__doc__ = parser.format_help() debugger.HandleCommand('command script add -f %s.obreak obreak' % __name__)
但这还不够,还需要在.lldbinit.rc文件中增加一些辅助代码,保证上述插件的自动执行
command script import ~/path_to_obreak.py target stop-hook add -o "script '--loading script--'" target stop-hook add obreak target stop-hook disable 2 target stop-hook disable 3