github doronz88/pymobiledevice3 v11.28.0

latest releases: v11.28.2, v11.28.1
5 hours ago

Highlights

✨ core-profile-session stackshot prints symbolicated call stacks

The command used to dump the whole stackshot as JSON. It now prints the call stack of every thread of every process, with the thread's name, dispatch queue, state, QoS, priority and CPU times:

pymobiledevice3 developer dvt core-profile-session stackshot --process SpringBoard
# SpringBoard [42]  size 100.4 MB  max rss 320.3 MB  9 threads
#   Thread 514  com.apple.main-thread  waiting  user-interactive  pri 47  cpu 4.441s user, 0.783s sys
#       0  libsystem_kernel.dylib  mach_msg2_trap + 8
#       1  libsystem_kernel.dylib  mach_msg_overwrite + 424
#       2  libsystem_kernel.dylib  mach_msg + 24
#       3  CoreFoundation          __CFRunLoopServiceMachPort + 136
#       ...
  • Frames are symbolicated against the Xcode device support of the device, in pure Python. When it is missing, a warning points at developer fetch-symbols download and frames are printed as image + offset. --symbols DIR uses another symbols tree.
  • --json prints the raw stackshot as before, and --out still writes it to a file. Scripts that parsed the default output need to add --json.
  • --process PID/NAME limits the output to one process.
  • Swift and C++ names are printed mangled, and main executables as uuid + offset.

✨ Kernel frames in stackshot

Given the kernelcache of the firmware the device runs, kernel frames get the name of their kernel image. With the kernel signatures of blacktop/symbolicator they are symbolicated too, and the kernel function a blocked thread resumes in is printed as its continuation. Both need ipsw installed.

pymobiledevice3 developer dvt core-profile-session stackshot \
    --kernelcache kernelcache.release.iphone17 --kernel-signatures symbolicator/kernel
#       0  com.apple.kernel  thread_invoke + 1232  (kernel)
#       4  com.apple.kernel  sbwait + 236  (kernel)
#       5  com.apple.kernel  soreceive + 2060  (kernel)

The signatures name part of the kernel only; a frame in a function they do not match stays as image + offset.

✨ fetch-symbols download keeps what it already downloaded

It downloaded several GB and split the shared cache again on every run. A finalized DeviceSupport directory is now left alone, and with an explicit output directory the files already having the size the device reports are kept. --force downloads everything again.

pymobiledevice3 developer fetch-symbols download
# INFO Symbols were already downloaded into: ~/Library/Developer/Xcode/iOS DeviceSupport/... (use --force to download them again)

With ipsw_parser 1.8.2 it also handles a device reporting its shared cache under /System/Cryptexes/OS, and a shared cache Xcode's extractor refuses.

✨ dvt oslog prints messages the way the device does

  • Numbers follow their printf conversion: a -1 for %d no longer prints as 18446744073709551615, nor a %f as its raw bits.
  • %{bool}d, %{BOOL}d and %{errno}d, nil objects, padded strings, uuid and data arguments, a literal %%, and the Network, mDNS and CoreLocation value types are printed like os_log does.
  • Rows are stamped with the device's time instead of the time the host printed them.
  • --format json records gain format_string and arguments, a list of {type, value} per argument.
  • The parser is about 18 times faster (about 1,100 to 20,000 rows/s on a replayed capture), so it no longer falls behind a busy device.

🐛 Bug fixes

  • dvt oslog exited with "unpack requires a buffer of 4 bytes" on a thread id of 0x1000000 or above, and most lines carried a stray NUL.
  • os_trace read the mach timestamp of an entry two bytes early.
  • Passing a timeout to the notification proxy raised AssertionError before anything was sent.
  • Finishing a sysdiagnose archive got a fresh full --timeout instead of what was left of it.

What's Changed

Full Changelog: v11.27.2...v11.28.0

Don't miss a new pymobiledevice3 release

NewReleases is sending notifications on new releases.