LLDB调试

2,259 阅读1分钟

LLDB是Xcode自带的调试工具,既可以在本地调试Mac程序,也可以在远程调试iPhone程序。当使用Xcode调试远程设备时(iPhone),Xcode会讲debugserver文件复制到设备中(路径:/Developer/usr/bin/,可以查看md5值确定是同一个),以便在设备上启动一个服务,等待Xcode进行远程调试。但是debugserver默认只能调试自己开发的APP,调试AppStore下载的app时,会报错error: failed to attach process 8487: unable to start the exception thread Exiting.

debugserver

debugserver运行在iOS上,顾名思义,它作为服务端,实际执行LLDB(作为客户端)传过来的命令,再把执行结果反馈给LLDB,显示给用户,即所谓的“远程调试”。

为了调试其他app,我们需要对debugserver文件进行操作。

  1. 赋予debugserver文件task_for_pid权限。

    • 复制debugserver文件,可以使用scp命令或者直接使用ifunbox等工具。
    $ scp -P 12345 root@localhost:/Developer/usr/bin/debugserver ~/Desktop
    
    • 签名权限
      签名权限有两种修改方式:

      • 使用codesign进行签名 新建权限文件entitlements.plist,写入以下内容:

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
        <plist version="1.0">
        <dict>
            <key>com.apple.springboard.debugapplications</key>
            <true/>
            <key>run-unsigned-code</key>
            <true/>
            <key>get-task-allow</key>
            <true/>
            <key>task_for_pid-allow</key>
            <true/>
        </dict>
        </plist>
        

        使用codesign进行签名,命令如下:

        $ codesign -s - --entitlements entitlements.plist -f debugserver
        
      • 使用ldid进行签名
        导出debugserver的entitlements文件

        $ ldid -e debugserver > debugserver.entitlements
        

        增加以下内容

        <key>get-task-allow</key>
        <true/>
        <key>task_for_pid-allow</key>
        <true/>
        

        使用ldid进行重签名

        $ ldid -Sdebugserver.entitlements debugserver
        
    • 将debugserver复制回手机,复制到手机的/usr/bin目录下。

    $ scp -P 12345 ~/Desktop/debugserver root@localhost:/usr/bin/
    
  2. 进行调试
    使用openSSH类似,建议做端口转发后,使用usb进行调试,速度更快。将本机的1234端口转发到设备的1234端口。

    1. 找到目标进程 $ ps -A或者$ ps aux
    2. 输入$ debugserver *:1234 -a 应用名称/PID,命令执行后,进入链接等待状态,被调试的进程会卡住。
    3. Mac终端输入$ lldb进入lldb调试状态
    4. 通过$ process connect connect://localhost:1234命令进行连接,连接完成后,目标进程处于暂停状态,输入$ c跳过。
    5. 在运行过程中,使用Control + C暂停程序,进行调试。