首页
学习
活动
专区
工具
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 类型和缓存机制不仅提高了开发效率,还减少了样板代码的编写。

13122

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

12.2K20
  • 如何使用Grid中的repeat函数

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

    57130

    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.6K10

    pythondecode函数的用法_如何使用python中的decode函数?

    大家好,又见面了,我是你们的朋友全栈君。 我们在使用Python的过程中,是通过编码实现的。编码格式是可以设定的,如果我们想要输入时编码格式时字符串编码,这时可以使用python中的decode函数。...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(...以上就是Python中decode函数的使用方法。

    2.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 评估当前线程上的表达式。

    87830

    汇编寄存器的规则

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

    2.6K50

    XCode的debug断点调试

    在 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.6K71

    XCode的debug断点调试

    在 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

    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.3K50

    使用 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

    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++,如何编译呢?

    73710

    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

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

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

    1.5K10

    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.4K20

    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
    领券