内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

lldb入坑指北(1):给Xcode批量添加启用&禁用断点功能

2018-03-12 17:17 出处:清屏网 人气: 评论(0

前言

据说,是否熟练掌握 lldb 相关的命令,可以快速判断 iOS 工程师的 level

本文所实现的功能已经合入到 chisel 的开发分支上面。

欢迎follow我的github https://github.com/sunbohong

为了避免浪费你的时间,在阅读本文前,请先思考以下问题:

  • 你是否经常使用Xcode的断点功能?
  • Xcode的断点功能好用吗?
  • 如果给Xcode批量添加启用&禁用断点功能,是否会提高你的工作效率?

如果都是 NO ,那么,请先阅读 https://objccn.io/issue-19-2/ 后再回来阅读本文章。相信我,掌握甚至精通lldb能够快速的提供你的生产力。

如果以上问题都是 YES ,那么,欢迎继续阅读以下内容。

阅读本文需要以下技能:

  • 对 Python 有基本的了解
  • 对 Xcode 的断点功能有基本的了解(相关的文档见下方的参考链接)

通过本文,希望大家可以了解以下内容:

  • 了解 lldb 的API架构
  • 通过 lldb 相关 API,构建自己的效率工具(Python脚本)

入门

LLDB

LLDB 是一个开源调试器,它已经被内置在 Xcode 程序中。

如下图所示,位于主窗口的底部,名为 Conseole 的窗口就是用于和 lldb 交互的区域。

断点

首先,通过以下操作,对lldb有基本的了解。

  • 创建一个程序
  • viewDidLoad 处添加添加断点
  • 运行程序,并使程序停在断点处
  • 在 Console 区域输入 po self 并回车
  • 观察输出结果

当程序暂停后(通过断点或者手动点击暂停按钮),Console 区域就会进入 lldb 模式。

po self 是指把 self 当做一个对象进行打印,类似的还有 p self 等命令。

ps.通过 help 命令,可以打印所有的可用命令。

pss.通过 help po 命令,可以打印该命令的用法。

Chisel

Chisel 是一个 Python 脚本集合,建议读者自行阅读 https://objccn.io/issue-19-2/ 后再看下面的部分

进阶

再看LLDB

LLDB 的调试接口本质上是一个C++共享库,在 Mac 系统上,它被打包为 LLDB.framework(正常情况下,它存在与 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework 路径下),在类unix 系统上,它是 lldb.so.

这些调试接口可以在 lldb 的脚本解释器内直接使用,或者可以被 引入 lldb.py 模块 的Python脚本 使用。

LLDB 本身支持用户自定义命令,比如通过脚本可以自定义一个 pviews 命令,该命令可以打印APP所有的视图。ps.该命令已经在 Chisel 中实现。

lldb脚本入门

首先,我们先通过一个非常简单的脚本,构造一个自定义命令。

  • 在~/ls.py 位置创建一个脚本,内容如下:
#!/usr/bin/python

import lldb
import commands
import optparse
import shlex

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print 'The "ls" python command has been installed and is ready for use.'
  • 在lldb中载入脚本
(lldb) command script import ~/ls.py
  • 执行命令
(lldb) ls ./
Applications
Users
...

到此为止,我们已经成功的实现了一个自定义的命令。

OK,让我们重新解释一下上面的代码。

command script import ~/ls.py

command 是lldb用于管理自定义命令的一个入口。

command script import 可以导入一个自定义的脚本文件。

```

def __lldb_init_module(debugger, internal_dict):

debugger.HandleCommand('command script add -f ls.ls ls')

print 'The "ls" python command has been installed and is ready for use.'

[TOC]

前言

据说,是否熟练掌握 lldb 相关的命令,可以快速判断 iOS 工程师的 level

本文所实现的功能已经合入到 chisel 的开发分支上面。

欢迎follow我的github https://github.com/sunbohong

为了避免浪费你的时间,在阅读本文前,请先思考以下问题:

  • 你是否经常使用Xcode的断点功能?
  • Xcode的断点功能好用吗?
  • 如果给Xcode批量添加启用&禁用断点功能,是否会提高你的工作效率?

如果都是 NO ,那么,请先阅读 https://objccn.io/issue-19-2/ 后再回来阅读本文章。相信我,掌握甚至精通lldb能够快速的提供你的生产力。

如果以上问题都是 YES ,那么,欢迎继续阅读以下内容。

阅读本文需要以下技能:

  • 对 Python 有基本的了解
  • 对 Xcode 的断点功能有基本的了解(相关的文档见下方的参考链接)

通过本文,希望大家可以了解以下内容:

  • 了解 lldb 的API架构
  • 通过 lldb 相关 API,构建自己的效率工具(Python脚本)

入门

LLDB

LLDB 是一个开源调试器,它已经被内置在 Xcode 程序中。

如下图所示,位于主窗口的底部,名为 Conseole 的窗口就是用于和 lldb 交互的区域。

断点

首先,通过以下操作,对lldb有基本的了解。

  • 创建一个程序
  • viewDidLoad 处添加添加断点
  • 运行程序,并使程序停在断点处
  • 在 Console 区域输入 po self 并回车
  • 观察输出结果

当程序暂停后(通过断点或者手动点击暂停按钮),Console 区域就会进入 lldb 模式。

po self 是指把 self 当做一个对象进行打印,类似的还有 p self 等命令。

ps.通过 help 命令,可以打印所有的可用命令。

pss.通过 help po 命令,可以打印该命令的用法。

Chisel

Chisel 是一个 Python 脚本集合,建议读者自行阅读 https://objccn.io/issue-19-2/ 后再看下面的部分

进阶

再看LLDB

LLDB 的调试接口本质上是一个C++共享库,在 Mac 系统上,它被打包为 LLDB.framework(正常情况下,它存在与 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework 路径下),在类unix 系统上,它是 lldb.so.

这些调试接口可以在 lldb 的脚本解释器内直接使用,或者可以被 引入 lldb.py 模块 的Python脚本 使用。

LLDB 本身支持用户自定义命令,比如通过脚本可以自定义一个 pviews 命令,该命令可以打印APP所有的视图。ps.该命令已经在 Chisel 中实现。

lldb脚本入门

首先,我们先通过一个非常简单的脚本,构造一个自定义命令。

  • 在~/ls.py 位置创建一个脚本,内容如下:
#!/usr/bin/python

import lldb
import commands
import optparse
import shlex

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print 'The "ls" python command has been installed and is ready for use.'
  • 在lldb中载入脚本
(lldb) command script import ~/ls.py
  • 执行命令
(lldb) ls ./
Applications
Users
...

到此为止,我们已经成功的实现了一个自定义的命令。

OK,让我们重新解释一下上面的代码。

command script import ~/ls.py

command 是lldb用于管理自定义命令的一个入口。

command script import 可以导入一个自定义的脚本文件。

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print 'The "ls" python command has been installed and is ready for use.'

脚本文件被导入时,并且 def __lldb_init_module(debugger, internal_dict): 方法会被检测到时,它会被自动调用。我们可以在这里一次性实现多个自定义命令。

debuggerlldb.SBDebugger lldb.SBDebugger-class 的一个实例,代表了当前的调试器对象。

internal_dict 包含了当前脚本会话的变量和方法。

HandleCommand 是一个实例方法,通过它,我们可以在Python脚本里面,调用lldb的方法。比如,这里的 command script add -f ls.ls ls

command script add -f ls.ls ls 的含义是“声明一个自定义的命令 ls ,这个命令的实现时 ls.ls ”。

command script add -f 函数名 自定义命令名

-f 代表后面跟着一个函数名,类似还有 -c ,代表一个 Python 类。

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

debugger 上面已经讲过,不再赘述。

command 是一个字符串,是我们命令的参数,通过情况下,我们可以使用 shlex 模块的 shlex.split(command) 命令切割处理。当然,这里直接透传就可以了。

resultlldb.SBCommandReturnObject 的实例。

internal_dict 上面已经讲过,不再赘述。

这个函数是我们自定义命令的核心,它通过调用Python模块 commandsgetoutput 方法,获取 ls 命令的输出结果,并打印到结果中。

批量管理断点

通过上面的介绍,相信读者很容易实现一个批量管理断点的自定义命令。

这里简单介绍一下我的思路。

  • 注册两个自定义命令作为入口, benable & bdisable
  • 通过一个函数实现状态的控制 def switchBreakpointState(expression,on):
  • 遍历断点和location,当符合要求时,切换断点和location的状态。

## lldb 模块简介

lldb 的Python环境提供了以下几个公共变量,我们后面的脚本会用到。

| 模块变量 | 模块类型 |

| -------- | -------- |

| lldb.debugger | lldb.SBDebugger | 当前的|

| lldb.target | lldb.SBTarget |

| lldb.process | lldb.SBProcess |

| lldb.thread | lldb.SBThread |

| lldb.frame | lldb.SBFrame |

完整源码

#!/usr/bin/python

import lldb
import commands
import optparse
import shlex

import re

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

def switchBreakpointState(expression,on):
    print str(expression)
    print str(on) 
    expression_pattern = re.compile(r'{}'.format(expression),re.I)
    print str(expression_pattern) 
    target = lldb.debugger.GetSelectedTarget()
    print str(target) 
    for breakpoint in target.breakpoint_iter():
        if breakpoint.IsEnabled() != on and (expression_pattern.search(str(breakpoint))):
            print str(breakpoint)
            breakpoint.SetEnabled(on)   
            for location in breakpoint:
                if location.IsEnabled() != on and (expression_pattern.search(str(location)) or expression == hex(location.GetAddress()) ):
                    print str(location)
                    location.SetEnabled(on)

def benable(debugger, command, result, internal_dict):
    switchBreakpointState(str(command),True)

def bdisable(debugger, command, result, internal_dict):
    switchBreakpointState(str(command),False) 

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    debugger.HandleCommand('command script add -f ls.benable benable')
    debugger.HandleCommand('command script add -f ls.bdisable bdisable')
    print 'The python commands has been installed and is ready for use.'

参考文档

[TOC]

前言

据说,是否熟练掌握 lldb 相关的命令,可以快速判断 iOS 工程师的 level

本文所实现的功能已经合入到 chisel 的开发分支上面。

欢迎follow我的github https://github.com/sunbohong

为了避免浪费你的时间,在阅读本文前,请先思考以下问题:

  • 你是否经常使用Xcode的断点功能?
  • Xcode的断点功能好用吗?
  • 如果给Xcode批量添加启用&禁用断点功能,是否会提高你的工作效率?

如果都是 NO ,那么,请先阅读 https://objccn.io/issue-19-2/ 后再回来阅读本文章。相信我,掌握甚至精通lldb能够快速的提供你的生产力。

如果以上问题都是 YES ,那么,欢迎继续阅读以下内容。

阅读本文需要以下技能:

  • 对 Python 有基本的了解
  • 对 Xcode 的断点功能有基本的了解(相关的文档见下方的参考链接)

通过本文,希望大家可以了解以下内容:

  • 了解 lldb 的API架构
  • 通过 lldb 相关 API,构建自己的效率工具(Python脚本)

入门

LLDB

LLDB 是一个开源调试器,它已经被内置在 Xcode 程序中。

如下图所示,位于主窗口的底部,名为 Conseole 的窗口就是用于和 lldb 交互的区域。

断点

首先,通过以下操作,对lldb有基本的了解。

  • 创建一个程序
  • viewDidLoad 处添加添加断点
  • 运行程序,并使程序停在断点处
  • 在 Console 区域输入 po self 并回车
  • 观察输出结果

当程序暂停后(通过断点或者手动点击暂停按钮),Console 区域就会进入 lldb 模式。

po self 是指把 self 当做一个对象进行打印,类似的还有 p self 等命令。

ps.通过 help 命令,可以打印所有的可用命令。

pss.通过 help po 命令,可以打印该命令的用法。

Chisel

Chisel 是一个 Python 脚本集合,建议读者自行阅读 https://objccn.io/issue-19-2/ 后再看下面的部分

进阶

再看LLDB

LLDB 的调试接口本质上是一个C++共享库,在 Mac 系统上,它被打包为 LLDB.framework(正常情况下,它存在与 /Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework 路径下),在类unix 系统上,它是 lldb.so.

这些调试接口可以在 lldb 的脚本解释器内直接使用,或者可以被 引入 lldb.py 模块 的Python脚本 使用。

LLDB 本身支持用户自定义命令,比如通过脚本可以自定义一个 pviews 命令,该命令可以打印APP所有的视图。ps.该命令已经在 Chisel 中实现。

lldb脚本入门

首先,我们先通过一个非常简单的脚本,构造一个自定义命令。

  • 在~/ls.py 位置创建一个脚本,内容如下:
#!/usr/bin/python

import lldb
import commands
import optparse
import shlex

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print 'The "ls" python command has been installed and is ready for use.'
  • 在lldb中载入脚本
(lldb) command script import ~/ls.py
  • 执行命令
(lldb) ls ./
Applications
Users
...

到此为止,我们已经成功的实现了一个自定义的命令。

OK,让我们重新解释一下上面的代码。

command script import ~/ls.py

command 是lldb用于管理自定义命令的一个入口。

command script import 可以导入一个自定义的脚本文件。

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    print 'The "ls" python command has been installed and is ready for use.'

脚本文件被导入时,并且 def __lldb_init_module(debugger, internal_dict): 方法会被检测到时,它会被自动调用。我们可以在这里一次性实现多个自定义命令。

debuggerlldb.SBDebugger lldb.SBDebugger-class 的一个实例,代表了当前的调试器对象。

internal_dict 包含了当前脚本会话的变量和方法。

HandleCommand 是一个实例方法,通过它,我们可以在Python脚本里面,调用lldb的方法。比如,这里的 command script add -f ls.ls ls

command script add -f ls.ls ls 的含义是“声明一个自定义的命令 ls ,这个命令的实现时 ls.ls ”。

command script add -f 函数名 自定义命令名

-f 代表后面跟着一个函数名,类似还有 -c ,代表一个 Python 类。

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

debugger 上面已经讲过,不再赘述。

command 是一个字符串,是我们命令的参数,通过情况下,我们可以使用 shlex 模块的 shlex.split(command) 命令切割处理。当然,这里直接透传就可以了。

resultlldb.SBCommandReturnObject 的实例。

internal_dict 上面已经讲过,不再赘述。

这个函数是我们自定义命令的核心,它通过调用Python模块 commandsgetoutput 方法,获取 ls 命令的输出结果,并打印到结果中。

批量管理断点

通过上面的介绍,相信读者很容易实现一个批量管理断点的自定义命令。

这里简单介绍一下我的思路。

  • 注册两个自定义命令作为入口, benable & bdisable
  • 通过一个函数实现状态的控制 def switchBreakpointState(expression,on):
  • 遍历断点和location,当符合要求时,切换断点和location的状态。

## lldb 模块简介

lldb 的Python环境提供了以下几个公共变量,我们后面的脚本会用到。

| 模块变量 | 模块类型 |

| -------- | -------- |

| lldb.debugger | lldb.SBDebugger | 当前的|

| lldb.target | lldb.SBTarget |

| lldb.process | lldb.SBProcess |

| lldb.thread | lldb.SBThread |

| lldb.frame | lldb.SBFrame |

完整源码

#!/usr/bin/python

import lldb
import commands
import optparse
import shlex

import re

def ls(debugger, command, result, internal_dict):
    print >>result, (commands.getoutput('/bin/ls %s' % command))

def switchBreakpointState(expression,on):
    print str(expression)
    print str(on) 
    expression_pattern = re.compile(r'{}'.format(expression),re.I)
    print str(expression_pattern) 
    target = lldb.debugger.GetSelectedTarget()
    print str(target) 
    for breakpoint in target.breakpoint_iter():
        if breakpoint.IsEnabled() != on and (expression_pattern.search(str(breakpoint))):
            print str(breakpoint)
            breakpoint.SetEnabled(on)   
            for location in breakpoint:
                if location.IsEnabled() != on and (expression_pattern.search(str(location)) or expression == hex(location.GetAddress()) ):
                    print str(location)
                    location.SetEnabled(on)

def benable(debugger, command, result, internal_dict):
    switchBreakpointState(str(command),True)

def bdisable(debugger, command, result, internal_dict):
    switchBreakpointState(str(command),False) 

def __lldb_init_module(debugger, internal_dict):
    debugger.HandleCommand('command script add -f ls.ls ls')
    debugger.HandleCommand('command script add -f ls.benable benable')
    debugger.HandleCommand('command script add -f ls.bdisable bdisable')
    print 'The python commands has been installed and is ready for use.'

参考文档


分享给小伙伴们:
本文标签: Xcodelldb

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号