Debugserver: Difference between revisions

From iPhone Development Wiki
No edit summary
m (General revising)
 
(19 intermediate revisions by 11 users not shown)
Line 1: Line 1:
{{DISPLAYTITLE:debugserver}}
{{DISPLAYTITLE:debugserver}}


<tt>[[debugserver]]</tt> is a console app that as server for remote gdb debugging. It is installed when a device is marked for development. It can be found in <tt>/Developer/usr/bin/debugserver</tt>. This is also the process invoked by Xcode to debug applications on the device.
<tt>'''debugserver'''</tt> is a console app that acts as server for remote gdb or lldb debugging. It is installed when a device is marked for development. It can be found in <tt>/Developer/usr/bin/debugserver</tt>. This is also the process invoked by Xcode to debug applications on the device.


== Command line options ==
If you're using iOS 7, see [[Debugging on iOS 7]] for more context.
<tt>debugserver</tt> can be invoked with
 
= Command line options =


  debugserver [<options>] host:<port> [<prog-name> <arg1> <arg2> ...]
  debugserver [<options>] host:<port> [<prog-name> <arg1> <arg2> ...]


Where ''options'' can be:
''options'' can be as follows:
 
{| class="wikitable"
{| class="wikitable"
|-
|-
Line 36: Line 38:
* '''fork''': Launch program using <tt>fork(2)</tt> and <tt>exec(3)</tt>.
* '''fork''': Launch program using <tt>fork(2)</tt> and <tt>exec(3)</tt>.
* '''posix''': Launch program using <tt>posix_spawn(2)</tt>.
* '''posix''': Launch program using <tt>posix_spawn(2)</tt>.
* '''spring''': Launch program via SpringBoard.
* '''backboard''': Launch program via BackBoard Services.
The '''backboard''' option is only available in the closed-source version included in Xcode.
|-
|-
| <tt>--lockdown</tt> || Obtain parameters from <tt>lockdown</tt> (?)
| <tt>--lockdown</tt> || Obtain parameters from <tt>lockdown</tt> (?)
|}
|}


== Patching for process attaching ==
= Patching for process attaching =
The vanilla <tt>debugserver</tt> cannot attach to any processes due to lack of entitlement to allow <tt>task_for_pid()</tt>. An entitlement must be inserted to the binary to allow this.
 
The vanilla <tt>debugserver</tt> lacks the <tt>task_for_pid()</tt> entitlement. For building and debugging your own apps on a properly provisioned device, this is not a problem; assuming your project and device are properly configured with your active iOS Developer Program, <tt>debugserver</tt> should have no trouble attaching to an app built and sent down to the device by Xcode. However, debugserver cannot attach to any other processes, including other apps from the App Store, due to lack of entitlement to allow <tt>task_for_pid()</tt>. An entitlement must be inserted into the binary to allow this. '''Note: The /Developer directory is actually a mounted read-only ramdisk. You cannot add any entitlements to the copy of debugserver installed there; it must be extracted to another directory and used from there.'''
 
'''0.''' <code>cd ~</code>


* '''0.''' <code>cd ~</code>
'''1.''' Thin the binary because <tt>[[ldid]]</tt> does not support fat binaries:
* '''1.''' Thin the binary because <tt>[[ldid]]</tt> does not support fat binaries:<br />
<source lang="bash">
lipo -thin armv6 /Developer/usr/bin/debugserver -output ~/debugserver
lipo -thin armv6 /Developer/usr/bin/debugserver -output ~/debugserver
* '''2.''' Save for following as <tt>ent.xml</tt>:
</source>
 
'''2.''' Save the following as <tt>ent.xml</tt>:
<source lang="xml">
<source lang="xml">
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
Line 63: Line 71:
</plist>
</plist>
</source>
</source>
* '''3.''' Apply the entitlement with <tt>ldid</tt>:
 
'''3.''' Apply the entitlement with <tt>ldid</tt>:
  ldid -Sent.xml debugserver
  ldid -Sent.xml debugserver


== Example session ==
= Attaching to a process =
* '''1.''' Copy MobileNotes to your Mac, e.g. to <tt>/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes</tt>.
 
* '''2.''' On the device, type:
'''1.''' On the device, type:
./debugserver 0.0.0.0:1234 -a "YouTube"
 
'''Example:'''
My-iPhone-5S:~ root# '''./debugserver *:1234 -a "YouTube"'''
debugserver-300.2 for arm64.
Attaching to process YouTube...
Spawning general listening thread.
Spawning kqueue listening thread.
Listening to port 1234 for a connection from *...
 
'''2.''' On your Mac, launch lldb and type the following commands (but replace the IP with your device's IP):
platform select remote-ios
process connect connect://192.168.2.104:1234
 
'''Example:'''
mbkim:Debug_Server Kim$ lldb
(lldb) '''platform select remote-ios'''
  Platform: remote-ios
  Connected: no
  SDK Path: "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/7.0"
  SDK Roots: [ 0] "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2"
[...]
  SDK Roots: [21] "/Users/Kim/Library/Developer/Xcode/iOS DeviceSupport/7.0.4 (11B554a)"
(lldb) '''process connect connect://192.168.2.104:1234'''
Process 2612 stopped
* thread #1: tid = 0x30d1e, 0x3ba51a84 libsystem_kernel.dylib`mach_msg_trap + 20, queue = 'com.apple.main-thread, stop reason = signal SIGSTOP
    frame #0: 0x3ba51a84 libsystem_kernel.dylib`mach_msg_trap + 20
libsystem_kernel.dylib`mach_msg_trap + 20:
-> 0x3ba51a84:  pop    {r4, r5, r6, r8}
    0x3ba51a88:  bx    lr
libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x3ba51a8c:  mov    r12, sp
    0x3ba51a90:  push  {r4, r5, r6, r8}
(lldb) '''po [[UIApplication sharedApplication] delegate]'''
<YTAppDelegate: 0x15e635a0>
(lldb)
 
== Debugging through USB instead of WiFi ==
 
If you find that debugging through WiFi is a little slow, or if you need to debug an app while WiFi is off, you can use usbmuxd to connect through USB. Refer to [[SSH Over USB]], replacing the source and destination ports with <code>1234</code> and using <tt>localhost</tt> instead of an IP.
 
Connect with lldb:
(lldb) '''process connect connect://localhost:1234'''
Process 2612 stopped
...
 
= Example session (old instructions) =
 
'''Note: these instructions only work on iOS 6 and older. For iOS 7, follow the example above.'''
 
'''1.''' Copy MobileNotes to your Mac, e.g. to <tt>/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes</tt>.
 
'''2.''' On the device, type:
  ~/debugserver -x spring host:6789 /Applications/MobileNotes.app/MobileNotes
  ~/debugserver -x spring host:6789 /Applications/MobileNotes.app/MobileNotes
<blockquote>This will launch MobileNotes and wait for the remote debugger.</blockquote>
This will launch MobileNotes and wait for the remote debugger.
--------
 
=== GDB ===
'''3.''' Launch the debugger and attach it to the remote process:
* On your Mac, launch <tt>/Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb/gdb-arm-apple-darwin</tt>.
If using '''GDB''':
* On your Mac, launch <tt>/Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb/gdb-arm-apple-darwin</tt>.
* Type the following in <tt>gdb</tt>:
* Type the following in <tt>gdb</tt>:
  set shlib-path-substitutions / /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/
  set shlib-path-substitutions / /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/
  file /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes
  file /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes
  target remote-macosx 192.168.1.101:6789
  target remote-macosx 192.168.1.101:6789
<blockquote>where 192.168.1.101 should be replaced by the actual IP address of your device. The remote debug connection is now complete.</blockquote>
Where 192.168.1.101 should be replaced by the actual IP address of your device. The remote debug connection is now complete.


=== LLDB ===
If using '''LLDB''':
* On your Mac, launch <tt>lldb</tt>.
* On your Mac, launch <tt>lldb</tt>.
* Type the following in <tt>lldb</tt>:
* Type the following in <tt>lldb</tt>:
  platform select remote-ios
  platform select remote-ios
  process connect connect://192.168.1.101:6789
  process connect connect://192.168.1.101:6789
--------
* '''5.''' Enter <tt>c</tt> to continue and do whatever you want.


== References ==
'''4.''' Enter <tt>c</tt> to continue and do whatever you want.
* iphone-debugserver project — http://code.google.com/p/iphone-debugserver/
 
= External links =
 
* [http://code.google.com/p/iphone-debugserver/ iphone-debugserver project]

Latest revision as of 22:28, 31 March 2020


debugserver is a console app that acts as server for remote gdb or lldb debugging. It is installed when a device is marked for development. It can be found in /Developer/usr/bin/debugserver. This is also the process invoked by Xcode to debug applications on the device.

If you're using iOS 7, see Debugging on iOS 7 for more context.

Command line options

debugserver [<options>] host:<port> [<prog-name> <arg1> <arg2> ...]

options can be as follows:

Option Effect
-a process Attach debugserver to process. The process can be a pid or executable name.
-d integer Assign the waitfor-duration.
-f ? ?
-g Turn on debugging.
-i integer Assign the waitfor-interval.
-l filename Log to file. Set filename to stdout to log to standard output.
-t Use task ID instead of process ID.
-v Verbose.
-w ? ?
-x method
--launch=method
How to launch the program. Can be one of:
  • auto: Auto-detect the best launch method to use.
  • fork: Launch program using fork(2) and exec(3).
  • posix: Launch program using posix_spawn(2).
  • backboard: Launch program via BackBoard Services.

The backboard option is only available in the closed-source version included in Xcode.

--lockdown Obtain parameters from lockdown (?)

Patching for process attaching

The vanilla debugserver lacks the task_for_pid() entitlement. For building and debugging your own apps on a properly provisioned device, this is not a problem; assuming your project and device are properly configured with your active iOS Developer Program, debugserver should have no trouble attaching to an app built and sent down to the device by Xcode. However, debugserver cannot attach to any other processes, including other apps from the App Store, due to lack of entitlement to allow task_for_pid(). An entitlement must be inserted into the binary to allow this. Note: The /Developer directory is actually a mounted read-only ramdisk. You cannot add any entitlements to the copy of debugserver installed there; it must be extracted to another directory and used from there.

0. cd ~

1. Thin the binary because ldid does not support fat binaries:

lipo -thin armv6 /Developer/usr/bin/debugserver -output ~/debugserver

2. Save the following as ent.xml:

<!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>get-task-allow</key>
	<true/>
	<key>task_for_pid-allow</key>
	<true/>
	<key>run-unsigned-code</key>
	<true/>
</dict>
</plist>

3. Apply the entitlement with ldid:

ldid -Sent.xml debugserver

Attaching to a process

1. On the device, type:

./debugserver 0.0.0.0:1234 -a "YouTube"

Example:

My-iPhone-5S:~ root# ./debugserver *:1234 -a "YouTube"
debugserver-300.2 for arm64.
Attaching to process YouTube...
Spawning general listening thread.
Spawning kqueue listening thread.
Listening to port 1234 for a connection from *...

2. On your Mac, launch lldb and type the following commands (but replace the IP with your device's IP):

platform select remote-ios
process connect connect://192.168.2.104:1234

Example:

mbkim:Debug_Server Kim$ lldb
(lldb) platform select remote-ios
  Platform: remote-ios
 Connected: no
  SDK Path: "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/7.0"
 SDK Roots: [ 0] "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2"
[...]
 SDK Roots: [21] "/Users/Kim/Library/Developer/Xcode/iOS DeviceSupport/7.0.4 (11B554a)"
(lldb) process connect connect://192.168.2.104:1234
Process 2612 stopped
* thread #1: tid = 0x30d1e, 0x3ba51a84 libsystem_kernel.dylib`mach_msg_trap + 20, queue = 'com.apple.main-thread, stop reason = signal SIGSTOP
    frame #0: 0x3ba51a84 libsystem_kernel.dylib`mach_msg_trap + 20
libsystem_kernel.dylib`mach_msg_trap + 20:
-> 0x3ba51a84:  pop    {r4, r5, r6, r8}
   0x3ba51a88:  bx     lr

libsystem_kernel.dylib`mach_msg_overwrite_trap:
   0x3ba51a8c:  mov    r12, sp
   0x3ba51a90:  push   {r4, r5, r6, r8}
(lldb) po [[UIApplication sharedApplication] delegate]
<YTAppDelegate: 0x15e635a0>
(lldb) 

Debugging through USB instead of WiFi

If you find that debugging through WiFi is a little slow, or if you need to debug an app while WiFi is off, you can use usbmuxd to connect through USB. Refer to SSH Over USB, replacing the source and destination ports with 1234 and using localhost instead of an IP.

Connect with lldb:

(lldb) process connect connect://localhost:1234
Process 2612 stopped
...

Example session (old instructions)

Note: these instructions only work on iOS 6 and older. For iOS 7, follow the example above.

1. Copy MobileNotes to your Mac, e.g. to /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes.

2. On the device, type:

~/debugserver -x spring host:6789 /Applications/MobileNotes.app/MobileNotes

This will launch MobileNotes and wait for the remote debugger.

3. Launch the debugger and attach it to the remote process: If using GDB:

  • On your Mac, launch /Developer/Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb/gdb-arm-apple-darwin.
  • Type the following in gdb:
set shlib-path-substitutions / /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/
file /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.sdk/Applications/MobileNotes.app/MobileNotes
target remote-macosx 192.168.1.101:6789

Where 192.168.1.101 should be replaced by the actual IP address of your device. The remote debug connection is now complete.

If using LLDB:

  • On your Mac, launch lldb.
  • Type the following in lldb:
platform select remote-ios
process connect connect://192.168.1.101:6789

4. Enter c to continue and do whatever you want.

External links