【问题标题】:bypassing exc_breakpoint crash to continue program execution绕过 exc_breakpoint 崩溃继续程序执行
【发布时间】:2020-12-16 06:18:15
【问题描述】:

在测试我的 iOS 应用(它是一个锻炼应用)期间,该应用在尝试保存锻炼数据时崩溃了 (EXC_BREAKPOINT)。

崩溃是一个索引超出范围的问题,数组计数比锻炼秒数少 1。 (我应该从 1 而不是 0 开始秒计数器)

 for i in 0...seconds {
        let data = "\(i),\(dataArray.powerGenY[i-1]),\(dataArray.powerGenYAlt[i-1])\n"
        
        do {
          try data.appendToURL(fileURL: fileURL)
        }
        catch {
          print("Could not write data to file")
        }
      }

无论如何,这个错误把我带到了 LLDB。有什么方法可以让我使用 LLDB 绕过此错误并继续执行?

【问题讨论】:

    标签: swift lldb


    【解决方案1】:

    已经锻炼了一个小时,我还没准备好让这次崩溃带走我的数据。由于崩溃让我进入 LLDB,我想看看是否有任何方法可以通过跳过/绕过/更改 i 的值来挽救数据,以便程序执行可以继续。

    最初我尝试过

    (lldb) po i = 3327
    error: <EXPR>:3:1: error: cannot assign to value: 'i' is immutable
    i = 3327
    ^
    

    但它不会让我更改值 (I is immutable)

    然后我尝试了thread jump -l 1,但它发出了一些关于不是当前函数之外的代码执行的错误。

    (lldb) th j -l 29
    error: CSVExport.swift:29 is outside the current function.
    

    最后,通过这个网站https://www.inovex.de/blog/lldb-patch-your-code-with-breakpoints/ 并尝试一些事情。帮助的是线程跳转

    线程返回

    上面提到的线程跳转的缺点可以通过使用 改变控制流行为的不同技术。代替 直接操作受影响的代码行的想法是 操纵程序的其他部分,从而导致 期望的行为。对于给定的示例,这意味着更改 can_pass() 的返回值从 0 到 1。当然,可以这样做 通过 LLDB。要使用的命令是 thread 就像以前一样,但是这个 子命令 return 过早从堆栈中返回的时间 框架,从而使其执行短路。

    执行 thread return 1 成功了。这对 index out of range 问题返回 true (1),然后继续执行到下一行代码。

    【讨论】:

    • thread jump 将电脑移动到其他地方,这样您就可以跳过代码。这是非常危险的(如果你跳过一个初始化程序,你会得到未初始化的数据,如果你跳过一个保留或释放,你会得到泄漏或释放后使用等)。所以这是一个非常危险的操作,但在某些情况下可以安全使用。但是跳到另一个函数是没有意义的。堆栈框架是为您所在的函数设置的,并且跳转到另一个函数将强制新代码在没有任何本地变量的堆栈上操作。这几乎是 0% 的工作机会,所以 lldb 禁止它。
    • @jim Ingham 我的目标只是挽救我在使用该应用程序进行室内骑行时产生的一个多小时的锻炼数据。而已。执行线程跳转使我摆脱了“索引超出范围”错误(这段代码是一个函数调用)继续执行下一行代码。就是这样。
    • 当然,工具在那里是因为有时会出现绝望的情况......我只是想弄清楚为什么不允许“线程跳转”从一个函数跳转到另一个函数。它的工作机会真的很小,不值得尝试支持它。
    • 哦。我明白你现在的意思了。干杯!
    猜你喜欢
    • 1970-01-01
    • 2015-07-16
    • 2019-11-23
    • 1970-01-01
    • 2018-01-08
    • 2013-12-10
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多