• iOS调试技巧——使用Python 自定义LLDB


    一、类介绍

    在使用Python 自定义LLDB之前,先了解一下LLDB的一些类型

    • SBTarget 正在被调试的程序
    • SBProcess 和程序关联的具体的进程
    • SBThread 执行的线程
    • SBFrame 和线程关联的一个栈帧
    • SBVariable 变量,寄存器或是一个表达式

    一般情况下,我们取到SBFrame就可以进行方法调用来打印关键信息

    二、断点调试示例

    在写Python前,先使用Xcode断点执行一下

    自定义类MyClass
    .h文件

    @interface MyClass : NSObject
    
    + (NSString *)lldbTest;
    
    @end
    
    • 1
    • 2
    • 3
    • 4
    • 5

    .m文件

    @implementation MyClass
    
    + (NSString *)lldbTest {
        return @"lldb test successed";
    }
    
    @end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    中断程序

    打开lldb控制台

    下面就开始写lldb的命令
    预期目标,打印出[MyClass lldbTest]的返回值

    输入script

    (lldb) script
    Python Interactive Interpreter. To exit, type 'quit()', 'exit()'.
    >>> 
    
    • 1
    • 2
    • 3

    定义变量test接收MyClass lldbTest]的返回值

    >>> test = lldb.frame.EvaluateExpression('(NSString *)[MyClass lldbTest]').GetObjectDescription()
    
    • 1

    打印变量test

    >>> print(test)
    
    • 1

    至此,直接在Xcode中使用lldb打印出[MyClass lldbTest]的返回值就完成了

    三、编写Python

    如果想把这个功能打包起来,使用一句命令调用,就需要使用Python来扩展我们的lldb命令

    1、新建Python文件

    这里将Python文件命名问lldbtest.py

    1、引入lldb头文件
    import lldb
    
    • 1
    2、初始化函数
    def __lldb_init_module(debugger, internal_dict):
        debugger.HandleCommand()
    
    • 1
    • 2

    在HandleCommand中添加命令:

    'command script add lldb_test -f lldbtest.test'
    
    • 1

    lldb_test表示命令名称,lldbtest是Python文件名,test是自定义方法名

    初始化函数最终

    def __lldb_init_module(debugger, internal_dict):
        debugger.HandleCommand('command script add lldb_test -f lldbtest.test')
    
    • 1
    • 2
    3、自定义Python方法

    获取当前的frame栈帧

      target = debugger.GetSelectedTarget()
      process = target.GetProcess()
      thread = process.GetSelectedThread()
      currentFrame = thread.GetSelectedFrame()
    
    • 1
    • 2
    • 3
    • 4

    调用方法

    def test(debugger, command, result, internal_dict):
      target = debugger.GetSelectedTarget()
      process = target.GetProcess()
      thread = process.GetSelectedThread()
      currentFrame = thread.GetSelectedFrame()
      test = currentFrame.EvaluateExpression('(NSString *)[Person lldbTest]').GetObjectDescription()
      print("result:%s" % test)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    整个Python文件

    #自定义lldb命令 
    import lldb
    
    def test(debugger, command, result, internal_dict):
      target = debugger.GetSelectedTarget()
      process = target.GetProcess()
      thread = process.GetSelectedThread()
      currentFrame = thread.GetSelectedFrame()
      test = currentFrame.EvaluateExpression('(NSString *)[Person lldbTest]').GetObjectDescription()
      print("result:%s" % test)
    
    def __lldb_init_module(debugger, internal_dict):
        debugger.HandleCommand('command script add lldb_test -f lldbtest.test')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    四、自动加载python脚本

    原理:xcode启动的时候会读取一个默认文件:~/.lldbinit
    只需要将命令command script import /Users/xx/Desktop/lldbtest.py 写入这个文件即可。
    /Users/xx/Desktop/lldbtest.py是Python文件路径

    测试:

  • 相关阅读:
    【Docker】三、docker网络通信机制
    【数据结构入门_数组】 Leetcode 566. 重塑矩阵
    微信小程序图表的引入并解决van-tab切换时不显示图表的问题
    如何处理前端本地存储和缓存?
    Sentinel系列之SlotChain、NodeSelectorSlot、ClusterBuilderSlot分析
    MySQL事务
    不要再使用Load方式加载数据到Hive了,这种方式很low,你造吗?
    Clickhouse—时间窗口函数
    【网络编程】网络编程中的基本概念及Java实现UDP、TCP客户端服务器程序(万字博文)
    【2021研电赛】基于深度学习的蛋白质与化合物结合性质预测
  • 原文地址:https://blog.csdn.net/u012903898/article/details/134030999