What is dynamic debugging?

Dynamic debugging is to view parameters, return values, function call flow, and so on, through a series of ways, such as breaking points, printing, and so on, while our program is running. Dynamic debugging is needed not only in iOS open, but also in any language development process

Use Xcode for dynamic debugging

  • GCC and LLVM: Xcode originally used the GNU GCC compiler, but since Xcode5 it has used its own LLVM compiler. You can see an introduction to GCC and LLVM here
  • GDB and LLDB: The Xcode debugger was originally a GDB debugger developed by GNU, and has since been replaced with a self-developed LLDB debugger. You can click on the introduction of GDB and LLDB.
  1. The first thing that comes with Xcode is something calleddebugserverThe tool, Stored in the/Applications/Xcode. App/Contents/Developer/Platforms/iPhoneOS platform/De ViceSupport/xx. Xx/DeveloperDiskImage. DMG/usr/bin/debugserver directory, when we use the Xcode run our program on the iPhone, Xcode willdebugserverInstall to our iPhone, specific installation path is/Developer/usr/bin/debugserver
  • Once Xcode is connected to your phone, use the built-inLLDBCompiler to the iPhonedebugserverTransmission instruction,debugserverAfter receiving the instruction, the instruction will be run in App, and the App will return the result todebugserverAnd thendebugserverWill give information back toLLDBAnd the lastLLDBIt prints the information to Xcode.
  • However, Xcode has great limitations in this way of debugging, because only apps installed through Xcod can be debugged

How to dynamically debug any App without Xcode?

You can use terminals instead of Xcode to dynamically debug your App

The DebugServer environment is set up

1. Use the LDID to sign

  • Under the access to the iPhone/Developer/usr/bin/debugserver directory debugserver tools, copied to the Mac
  • As installed through XcodedebugserverNot enough permission, can only debug Xocde installed App, so we need to givedebugserverAdd more permissions.
  • Export using the LDD-e commanddebugserverPermission information of
ldid -e debugserver > debugserver.entitlements
Copy the code
  • Add the following two permissions in debugServer. entitlements

    • get-task-allow
    • task_for_pid-allow
  • Re-sign the DEBUgserver using the LDID

ldid -Sdebugserver.entitlements debugserver
Copy the code
  • Since the /Developer/usr/bin/ directory is read-only, we will re-sign itdebugserverPut it under /usr/bin/and thendebugserverAdd the operation permission, and you can use it on terminalsdebugserverthe
chmod + /usr/bin/debugserver
Copy the code

Method 2. Use CoDesign to sign the DEBUgServer

# view entitlements codesign -d --entitlements - Debugserver # Signature entitlements codesign -F-S - -- Entitlements debugserver. Entitlements Debugserver # can also be abbreviated as codesign-fs - -- Entitlements debugserver. Entitlements DebugserverCopy the code

Let the DebugServer attach to a process

Debugserver *: port number -a processCopy the code

*: Port number: indicates that a port on the iPhone is used to start the debugServer service (note: reserved port number cannot be used)

-a Process: Specifies the process ID or name

Start the App using the DebugServer

Debugserver -x Auto *: port number App executable file pathCopy the code

Start LLDB on the Mac and remotely connect to the DEBUgServer on the iPhone

In previous studies, we know that the IP address of iPhone can be used to connect the mobile phone, but it is necessary to ensure that the mobile phone and the computer are under the same wifi, and data transmission in this way is very slow. Therefore, the common practice is to connect the iPhone via USB, map a port on the iPhone to a port on the Mac, and then communicate with the port on the Mac

debugserver attaching

  • Map iPhone 10011 with the following command
python ./usbmuxd/tcprelay.py -t 22:10010 10011:10011
Copy the code

Port 10011 here can be defined arbitrarily, as long as the reserved port number is not used. Port 10010 is mapped to port 22 for SSH communication with the iPhone

  • After the mapping is successful, start using port 10011debugserverService. letdebugserverAppend to App process as follows:
debugserver *10011 -a wechat
Copy the code
  • If the following effect appears, == DebugServer == has been successfully attached to Tencent Video App
5s:~ root# DebugServer *:10011 -A DebugServer -@(#)PROGRAM: DebugServer PROJECT: DebugServer-360.0.26.3 for arm64. Attaching to process wechat... Listening to port 10011 for a connection from *...Copy the code

Start LLDB on the Mac and remotely connect to the debugServer service on the iPhone

  • Start LLDB on a Mac
➜  ~ lldb
(lldb)
Copy the code
  • Connect through port 10011 of the Macdebugserveservice
(lldb) process connect connect://localhost:10011
Process 6911 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x0000000186c47224 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
->  0x186c47224 <+8>: ret

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x186c47228 <+0>: mov    x16, #-0x20
    0x186c4722c <+4>: svc    #0x80
    0x186c47230 <+8>: ret
Copy the code
  • Because of the connectiondebugserverAfter the service, the program is in the breakpoint state by default, use the LLDB c command to keep the program running
(lldb) c
Process 6911 resuming
Copy the code