• 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文件路径

    测试:

  • 相关阅读:
    oracle行转列、列转行总结
    独家 | 2022 年十项突破性技术
    Unity 2018发布在iOS 16.3偶尔出现画面不动的问题
    基于阶梯碳交易的含P2G-CCS耦合和燃气掺氢的虚拟电厂优化调度(matlab代码)
    keras fit_generator 增加并行度问题 use_multiprocessing
    【FPGA开发】时钟管理单元介绍与应用
    39. 组合总和
    easy_login通关思路
    gitlab修改默认存储目录
    java虚拟机详解篇十一(java虚拟机栈)
  • 原文地址:https://blog.csdn.net/u012903898/article/details/134030999