Debugging memory problems in network extension

Hi,


I have a packet tunnel provider that crashs randomly with SIGABRT in AutoreleasePoolPage::pop(). The problem is that since it is launched by the system, there isn't any useful crash details in the lldb window nor can i enable the enviroment variables needed for memory debugging.


I've looked into trying to narrow it down in my code but after 2 weeks, I still haven't identified the root cause. Are there any tools/techniques that I can use to pinpoint this autorelease issue?


Additional details:


1. Call stack:

#0 0x0000000183a992ec in __pthread_kill ()

#1 0x0000000183c3e6a8 in pthread_kill$VARIANT$armv81 ()

#2 0x0000000183a07d0c in abort ()

#3 0x0000000183ad1838 in free ()

#4 0x00000001831ea13c in (anonymous namespace)::AutoreleasePoolPage::pop(void*) ()

#5 0x0000000102da2a90 in <this is my code>


2. "po $arg1" doesn't work on frames #3 and #4. To get to the 1st arg, it looks like the call to pop() passes in the (void*) as follows:

    0x102da2a88 <+504>:  ldur   x0, [x29, #-0x58]
    0x102da2a8c <+508>:  bl     0x1034ab69c               ; symbol stub for: objc_autoreleasePoolPop

IIUC, i need to take $x29 and subtract 0x58, then that memory location is loaded into $x0:

(lldb) x/1 ($x29-0x58)

0x16dd92a78: 0x0b204138

However, 0xb204000 doesn't look like any of the other heap addresses, so this doesn't look like the thing getting freed.


At this point, I'm pretty stuck. Any help would be greatly appreciated.

Replies

Are there any tools/techniques that I can use to pinpoint this autorelease issue?

I’ve never tried this on iOS but on macOS you can set environment variables in an app extension via the XPCService > EnvironmentVariables key. There’s details on this below.

As iOS doesn’t give you access to launchctl you’ll have to check whether it works by calling getenv. If it does work, you should then by able to enable zombies via its environment variable.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"


You can set an environment variable permanently by modifying your Info.plist. This works because an Network Extension provider is a type of app extension, and an app extension acts very much like an XPC Service. So, to start, read the xpcservice.plist man page (in Terminal, type man 5 xpcservice.plist) and its discussion of the EnvironmentVariables property. For example:

<dict>
   …
   <key>XPCService</key>
   <dict>
       <key>EnvironmentVariables</key>
       <dict>
           <key>FOO</key>
           <string>BAR</string>
       </dict>
   </dict>
</dict>
</plist>

You can check whether this had the desired effect by running the procinfo subcommand of launchctl:

$ sudo launchctl procinfo `pgrep QNEPacketTunnelProvider`
program path = /Applications/QNEPacketTunnel.app/Contents/PlugIns/QNEPacketTunnelProvider.appex/Contents/MacOS/QNEPacketTunnelProvider
…
environment vector = {
   …
   FOO => BAR
   …
}
…

IMPORTANT This works on macOS 10.12 but not on earlier systems.