首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何使用Swift打印LLDB中的#line #file #函数的等价物?

在Swift中,可以使用#line#file#function等预处理器指令来获取代码中的行号、文件名和函数名等信息。然而,在LLDB(调试器)中,没有直接等价的指令来获取这些信息。不过,我们可以通过一些技巧来实现类似的功能。

首先,我们可以使用expr命令在LLDB中执行一段Swift代码来获取这些信息。例如,要获取当前行号,可以使用以下命令:

代码语言:txt
复制
expr #line

要获取当前文件名,可以使用以下命令:

代码语言:txt
复制
expr #file

要获取当前函数名,可以使用以下命令:

代码语言:txt
复制
expr #function

这些命令将在LLDB中执行Swift代码,并返回相应的值。

另外,为了方便使用,我们可以将这些命令封装成LLDB的自定义命令。首先,创建一个名为lldb.swift的文件,内容如下:

代码语言:txt
复制
import Foundation

extension String {
    func lldbExpression() -> String {
        return "expr \(self)"
    }
}

class LLDBCommand: NSObject, NSCoding {
    let command: String
    
    init(command: String) {
        self.command = command
    }
    
    func encode(with coder: NSCoder) {
        coder.encode(command, forKey: "command")
    }
    
    required convenience init?(coder: NSCoder) {
        guard let command = coder.decodeObject(forKey: "command") as? String else {
            return nil
        }
        self.init(command: command)
    }
    
    func execute(debugger: inout LLDBDebugger) {
        debugger.executeCommand(command)
    }
}

class LLDBDebugger: NSObject, NSCoding {
    var commands: [LLDBCommand] = []
    
    func executeCommand(_ command: String) {
        print("Executing command: \(command)")
        // 在这里执行LLDB命令
        // 可以使用lldb.SBCommandInterpreter类来执行命令
    }
    
    func addCommand(_ command: LLDBCommand) {
        commands.append(command)
    }
    
    func executeCommands() {
        for command in commands {
            command.execute(debugger: &self)
        }
    }
    
    func encode(with coder: NSCoder) {
        coder.encode(commands, forKey: "commands")
    }
    
    required convenience init?(coder: NSCoder) {
        guard let commands = coder.decodeObject(forKey: "commands") as? [LLDBCommand] else {
            return nil
        }
        self.init()
        self.commands = commands
    }
}

func saveDebugger(_ debugger: LLDBDebugger) {
    let fileURL = FileManager.default.temporaryDirectory.appendingPathComponent("lldb.debugger")
    let data = NSKeyedArchiver.archivedData(withRootObject: debugger)
    try? data.write(to: fileURL)
    print("Debugger saved to: \(fileURL.path)")
}

func loadDebugger() -> LLDBDebugger? {
    let fileURL = FileManager.default.temporaryDirectory.appendingPathComponent("lldb.debugger")
    guard let data = try? Data(contentsOf: fileURL) else {
        return nil
    }
    return NSKeyedUnarchiver.unarchiveObject(with: data) as? LLDBDebugger
}

let debugger = LLDBDebugger()
debugger.addCommand(LLDBCommand(command: "#line".lldbExpression()))
debugger.addCommand(LLDBCommand(command: "#file".lldbExpression()))
debugger.addCommand(LLDBCommand(command: "#function".lldbExpression()))
saveDebugger(debugger)

然后,在终端中执行以下命令来加载LLDB的自定义命令:

代码语言:txt
复制
command script import /path/to/lldb.swift

接下来,可以使用以下命令来执行LLDB中的自定义命令:

代码语言:txt
复制
command script import /path/to/lldb.swift
lldb.debugger.executeCommands()

执行完命令后,LLDB将输出相应的行号、文件名和函数名等信息。

这样,我们就可以在LLDB中使用Swift打印#line#file#function的等价物了。请注意,这只是一种近似的方法,因为LLDB中没有直接等价的指令来获取这些信息。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

如何使用 Swift GraphQL

前言我一直在分享关于类型安全和在 Swift 构建健壮 API 更多内容。今天,我想继续探讨类型安全的话题,介绍 GraphQL。GraphQL 是一种用于 API 查询语言。...本周,我们将讨论 GraphQL 好处,并学习如何Swift使用它。基础知识首先介绍一下 GraphQL。GraphQL 是一种用于 API 查询语言。...GraphQL 自定义类型每个字段都必须声明其类型。默认情况下,每个字段都可以为 nil。带有感叹号字段不能为 nil。我使用星球大战 API 来向你展示本文中示例。让我们继续进行一些查询。...这个脚本下载模式并为你查询生成 Swift 类型。你可以在这个脚本轻松更改 GraphQL 端点以连接到你 GraphQL 后端。我们已准备好使用 ApolloGraphQL 项目。...在 Swift ,ApolloGraphQL 框架极大地简化了 GraphQL 查询和变更实现过程,自动生成 Swift 类型和缓存机制不仅提高了开发效率,还减少了样板代码编写。

12822

Mysql注入load_file()函数使用

前言 在Msql注入,load_file()函数在获得webshell以及提权过程起着十分重要作用,常被用来读取各种配置文件 而load_file函数只有在满足两个条件情况下才可以使用: 1、文件权限...在实际注入,我们有两个难点需要解决: 1、绝对物理路径。 2、构造有效畸形语句。...在很多PHP程序,当提交一个错误查询时,如果display_errors=on,程序就会暴露web目录绝对路径,只有知道 路径,那么对于一个可以注入PHP程序来说,整个服务器安全将受到严重威胁...看过《SQL Injection with MySQL》朋友肯定知道用char()函数或者把字符转换成16进制。...2、能够使用union (需要mysql 3以上版本) 3、对方没有对(')进行过滤(因为outfile后面的('')不可以用其他函数代替转换) 后天条件需要二个: 1、就是mysql用户拥有file_priv

11.6K10
  • 如何使用Gridrepeat函数

    如果我们希望多行和/或多列大小相同,这可能会变得重复。 repeat()函数可以将我们从重复解救出来。...使用minmax()函数 minmax() 函数本身需要两个参数--最小值和最大值,中间用逗号隔开。因此,通过 minmax(),我们可以在灵活环境为轨道设置一系列可能尺寸。...我们很快就会看到如何获得更好效果。 使用min()或者max() minmax() 函数参数也可以是 min() 或 max() 函数。这两个函数都接收两个参数。...min()函数应用两个值较小值,而 max() 函数应用较大值。这在响应式环境中非常有用。...在上图中,你可以看到末端列行编号仍然是 8,而 8 则堆叠在网格行 7、6 和 5 上方。 那么我们该如何看待这一切呢?

    55130

    Swift Actors 使用如何及防止数据竞争

    Swift Actors 是Swift 5.5新内容,也是WWDC 2021上并发重大变化一部分。在有 actors 之前,数据竞争是一个常见意外情况。...Swift Actors 旨在完全解决数据竞争问题,但重要是要明白,很可能还是会遇到数据竞争。本文将介绍 Actors 是如何工作,以及你如何在你项目中使用它们。 什么是 Actors?...Swift Actors 可以保护他们状态免受数据竞争影响,并且使用它们可以让编译器在编写应用程序时为我们提供有用反馈。...Serial DispatchQueue: Concurrency in Swift explained一文解释技术启发。我将向你展示使用 Actor 前后对比。...所有与同步访问有关逻辑都被隐藏在Swift标准库实现细节里。然而,最有趣部分发生在我们试图使用或读取任何可变属性和方法时候: Actors方法是隔离,以便同步访问。

    2.5K10

    pythondecode函数用法_如何使用pythondecode函数

    大家好,又见面了,我是你们朋友全栈君。 我们在使用Python过程,是通过编码实现。编码格式是可以设定,如果我们想要输入时编码格式时字符串编码,这时可以使用pythondecode函数。...decode函数可以以 encoding 指定编码格式解码字符串,并默认编码为字符串编码。 1、decode函数 以 encoding 指定编码格式解码字符串,默认编码为字符串编码。...2、decode()方法语法 str.decode(encoding=’UTF-8′,errors=’strict’) 3、参数 encoding ——要使用编码,如:utf-8,gb2312,cp936...4、使用实例 u = ‘中文’ #指定字符串类型对象u str = u.encode(‘gb2312’) #以gb2312编码对u进行编码,获得bytes类型对象str u1 = str.decode(...以上就是Pythondecode函数使用方法。

    2K20

    汇编和内存

    # 汇编和内存 你已经开了汇编学习旅程,并且在前几章你已经学习了汇编调用一些黑魔法,你现在知道了,当一个函数被调用,他参数和返回值是如何传递。...但是您还没学到是将代码加载到内存后如何执行代码。 在本章,您将探索程序执行方式。...尤其是在打印出寄存器内容时会用到。 请记住,寄存器在 Swift 上下文中不可用,因此您需要使用 Objective-C 上下文。 现在,您已经具有从汇编角度探讨本章内容所需工具!...在控制台中使用 command + F 来搜索关键字 range = [ 其中范围第一个值便是 该地址称为加载地址。 这是此函数在内存实际物理地址!...单击 Objective-C 函数任何框架。 下一步,在 LLDB 控制台中键入以下内容: p/i 0x55 好多了,对吧? 现在,回到手中应用程序。

    1.2K20

    Swift进阶-LLDB调试

    程序猿最好利器就是开发工具,iOS开发者最基本,最关键一点就是熟练使用Xcode,而LLDB则是Xcode至关重要一环。...command 管理自定义LLDB命令命令 disassemble 拆卸当前指定指令,默认为当前函数为当前线程和堆栈帧 expression 评估当前线程上表达式。...b 使用几个速记格式一个设置断点 bt 显示当前线程调用堆栈。...将程序计数器设置为新地址 kill 终止当前目标进程 l 使用几个速记一个列出相关源代码格式 list 使用几个速记一个列出相关源代码格式 n 源级单步,单步调用。...显示任何返回值与LLDB默认格式 q 退出LLDB调试器 r 在调试器启动可执行文件 rbreak 在可执行文件设置断点或断点集。 repl 评估当前线程上表达式。

    85730

    汇编寄存器规则

    # 汇编寄存器规则 在本章,您将了解到 CPU 使用寄存器,并研究和修改传入函数参数。您还将了解常见苹果计算机架构,以及如何函数使用它们寄存器。这就是所谓架构调用约定。...了解汇编如何工作以及特定架构调用约定如何工作是一项极其重要技能。它可以让您观察没有源代码函数参数,并允许您修改传入函数参数。...首先,在 Swift 调试上下文内寄存器不可用。意味着你不得不获取到任何你想要数据,并使用 OC 调试上下文打印出传入 Swift 函数寄存器。...# RAX,用于返回寄存器 等等 -- 还有呢!到这里,你已经了解了函数六个寄存器是如何调用,但是返回值呢? 幸运是,只有一个指定寄存器用于返回值:RAX。...RAX 寄存器用于函数返回值,无论您使用是 Objective-C 还是 Swift。 您可以利用寄存器做很多事情。尝试浏览您没有源代码应用;将为解决棘手调试问题奠定良好基础。

    2.5K50

    XCodedebug断点调试

    LLDB ,你可以使用 process continue 命令来达到同样效果,它别名为 continue,或者也可以缩写为 c。...如果你确实想跳进一个函数调用来调试或者检查程序执行情况,那就用第三个按钮,step in,或者在LLDB使用 thread step in,step,或者 s 命令。...br li Current breakpoints: 1: file = '/Users/arig/Desktop/DebuggerDance/DebuggerDance/main.m', line...断点行为 (Action) 上面的例子,你或许想知道每一次到达断点时候 i 值。我们可以使用 p i 作为断点行为。这样每次到达断点时候,都会自动运行这个命令。...你也可以添加多个行为,可以是调试器命令,shell 命令,也可以是更直接打印: 可以看到它打印 i,然后大声念出那个句子,接着打印了自定义表达式。

    5.5K71

    XCodedebug断点调试

    LLDB ,你可以使用 process continue 命令来达到同样效果,它别名为 continue,或者也可以缩写为 c。...如果你确实想跳进一个函数调用来调试或者检查程序执行情况,那就用第三个按钮,step in,或者在LLDB使用 thread step in,step,或者 s 命令。...br li Current breakpoints: 1: file = '/Users/arig/Desktop/DebuggerDance/DebuggerDance/main.m', line...断点行为 (Action) 上面的例子,你或许想知道每一次到达断点时候 i 值。我们可以使用 p i 作为断点行为。这样每次到达断点时候,都会自动运行这个命令。...你也可以添加多个行为,可以是调试器命令,shell 命令,也可以是更直接打印: 可以看到它打印 i,然后大声念出那个句子,接着打印了自定义表达式。

    1.7K70

    OC对象原理(二)

    ,并且打断点,如下: 在断点处使用x tank来打印tank内存段,我们发现front、back、left、right这四个属性每个属性都占用了一个字节,这实际上是很耗内存。...联合体(又称为共用体)各变量是“互斥”,其内存空间是共用——缺点是不够“包容”;优点是,内存使用更为精细灵活,也节省了内存空间。...p/t是二进制打印 p/o是八进制打印 p/x是十六进制打印 p/d是十进制打印 【题外话结束】 现在咱来想想,如何获取一个对象类呢?...接下来进行验证: 第一步,我使用x/4gx tank来打印了实例对象tank内存地址,第一段地址就是isa存储内容,即对应类地址: (lldb) x/4gx tank 0x600003b64270...而上面第四步也是0x00000001074b11d8,所以说,上面第四步NSObject是根元类。 Clang编译 我们在研究过程,经常会需要将OC代码编译成C++,如何编译呢?

    73510

    使用 LLDB 调试 Go 程序

    2、通用操作 显示文件和行号,设置断点以及反编译: 1 (lldb) l 2 (lldb) l line 3 (lldb) l file.go:line 4 (lldb) b line 5 (lldb)...b file.go:line 6 (lldb) disas 显示 backtrace 和 unwind stack frame: 1 (lldb) bt 2 (lldb) frame n Show the...如果有同名本地变量,比如shadowed 变量, 你不知道哪个是哪个 -调试信息仅仅描述了变量在内存位置,所以你可能看到寄存器变量stale数据 -不能打印函数类型 教程 在这个例子我们可以检查标准库正则表达式...命令frame variable会列出这个函数所有的本地变量以及它们值。但是使用它有点危险,因为它会尝试打印出未初始化变量。未初始化slice可能会导致lldb打印出巨大数组。...函数参数: 1 (lldb) frame var -l 2 (*testing.T) t = 0x000000020834a000 打印这个参数时候,你会注意到它是一个指向Regexp指针。

    2.1K30

    iOS开发 Xcode各种调试、DEBUG

    所以我们这么做: 编辑断点 添加条件Condition 还可以Action在条件断点触发时执行事件 如:输出信息 4.方法断点 打印调试 尽管ARC已经让内存管理变得简单、省时和高效,但是在object...(这里有一个关于调试器如何工作总体解释。) 你以前有可能已经使用过调试器,即使只是在 Xcode 界面上加一些断点。但是通过一些小技巧,你就可以做一些非常酷事情。...命令 print 打印值 缩写p print是 expression -- 缩写 printk可以指定格式打印 如 默认 p 十六进制 p/x、 二进制 p/t (lldb) p 16 16 (...在 LLDB ,你可以使用 process continue 命令来达到同样效果,它别名为 continue,或者也可以缩写为 c。...如果你确实想跳进一个函数调用来调试或者检查程序执行情况,那就用第三个按钮,step in,或者在LLDB使用 thread step in,step,或者 s 命令。

    2.2K50

    Objective-Ckotilin 混编项目函数调用栈异常排查笔记(1) - Fast Unwind 与序章

    第三篇,主要介绍 lldb 调试器 获取 Backtrace(函数调用栈) 原理及解决方案介绍 问题背景 有位网友反馈自己负责一款多种语言(objective-c/Swift/kotlin)混编...一个 栈帧。...对于帧 0,这是 APP 暂停或终止时在线程上执行机器指令地址。对于其他栈帧,这是在控制权返回到该栈帧之后执行第一条机器指令地址。 main:在完全符号化崩溃报告,代表函数名称。...如果源文件行号为0,则表示该 栈帧 不会映射到原始代码特定代码行。...分配堆栈空间、调用其他函数、保存非易失性寄存器或使用异常处理每个函数都必须具有 prolog epilog(尾声) epilog (尾声) 是函数结束部分指令。

    1.5K10

    Swift 周报 第二十三期

    周报精选 新闻和社区:苹果iPhone 15 Pro硬件细节曝光,广大网友期待USB-C接口迎来普及 Swift 论坛:讨论嵌套泛型问题 推荐博文:iOS App 项目优化 话题讨论: 生活遇到问题你会使用...(中间没有选项) 当使用 -disable-reflection-metadata 标志禁用时,LLDB 将无法使用反射元数据,从而导致调试功能显着降低。...通过使用 -enable-reflection-for-debugger-only 标志,LLDB 可以使用反射,但是,它不会链接到 NTD,这将允许链接器通过 dead-stripping 消除它。...LLDB: 可能需要更改 LLDB,以教会它在没有提供 DSYM 情况下进行调试时发现 DWARF 段反射。...话题讨论 生活遇到问题你会使用 chatGTP 寻找答案吗? 欢迎在文末留言参与讨论。

    1.1K20

    iOS-Swift 结构体与类

    一、结构体 在 Swift 标准库,绝大多数公开类型都是结构体,而枚举和类只占很小一部分。...: malloc 在Mac、iOS malloc 函数分配内存大小总是16 倍数。...因为在Mac、iOS malloc 函数分配内存大小总是16 倍数,所以最终系统会分配 CGPoint 内存大小为 48 字节。...五、结构体与类选择 结构体与类使用方式很相似,那么在平时开发中使用结构体比较好还是类比较好呢?这种时候分情况,如果定义数据结构比较简单情况下,建议用结构体,比如 Model。...object; } (滑动显示更多) 在函数内部会调用一个 swift_slowAlloc 函数,我们来看下 swift_slowAlloc 函数内部实现: void *swift::swift_slowAlloc

    1.4K10

    Swift Task

    Swift Task 是 WWDC 2021 引入并发框架一部分。任务允许我们从非并发方法创建并发环境,使用 async/await 调用方法。...在任务执行异步方法 除了同步返回值或抛出错误外,任务还可以执行异步方法。我们需要一个任务来在不支持并发函数执行任何异步方法。...不支持并发函数“async”调用是 Swift 常见错误。...这个打印语句是演示了如何使用静态取消检查两种方法其中一种。另一种是通过在检测到取消时抛出错误来停止执行当前任务: let imageTask = Task { () -> UIImage?...打印出高优先级原始值,显示其实相匹配: (lldb) p Task.currentPriority (TaskPriority) $R0 = (rawValue = 25) (lldb) po TaskPriority.high.rawValue

    3.3K20

    Xcode Debug 大全

    (这里有一个关于调试器如何工作总体解释。) 你以前有可能已经使用过调试器,即使只是在 Xcode 界面上加一些断点。但是通过一些小技巧,你就可以做一些非常酷事情。...(lldb) p/t (char)16 0b00010000 你也可以使用 p/c 打印字符,或者 p/s 打印以空终止字符串 p/d打印ACRSII(译者注:以 ‘\0’ 结尾字符串)。...在 LLDB ,你可以使用 process continue 命令来达到同样效果,它别名为 continue,或者也可以缩写为 c。...LLDB 则可以使用 thread step-over,next,或者 n 命令。...如果你确实想跳进一个函数调用来调试或者检查程序执行情况,那就用第三个按钮,step in,或者在LLDB使用 thread step in,step,或者 s 命令。

    1.2K21
    领券