Debugging complex daemons from start

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

Debugging complex daemons from start

Postby backendbilly » Sun Sep 18, 2016 5:28 pm

I've never come across examples related to debugging complex daemons on iOS such as locationd. Attaching is never an issue but debugging the daemon on start was never successful for me given the fact that a lot of pre-initialization happen prior to stopping at the daemon entry point. In my case, the daemon always exited.

J or anybody, have you ever come across debugging such complex daemons and whether you have a technique to stop the debugger at daemon entry point?

Billy
backendbilly
Site Admin
 
Posts: 132
Joined: Fri May 29, 2015 5:58 pm

Re: Debugging complex daemons from start

Postby morpheus » Mon Sep 19, 2016 4:19 pm

Simple technique: Force inject a simple library, and in its constructor for (;;) { sleep(1);}

Then attach a debugger at your leisure.
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm

Re: Debugging complex daemons from start

Postby backendbilly » Tue Sep 20, 2016 3:55 am

Sounds like fun J. Would you mind elaborating on the force injection part please? Much appreciated.
backendbilly
Site Admin
 
Posts: 132
Joined: Fri May 29, 2015 5:58 pm

Re: Debugging complex daemons from start

Postby TheDarkKnight » Tue Sep 20, 2016 2:27 pm

J is referring to the use of the environment variable DYLD_INSERT_LIBRARIES, which is mentioned briefly in MOXiI on p129.

By setting the environment to point to a library that you create, the dynamic linker (launchd) will load your library, allowing you to execute code in the target process.
When the library to be inserted contains a constructor, it will be invoked when loaded, giving you the ability to add the code
Code: Select all
 for(;;) {sleep(1);}
and attach the debugger.

In the case of a service, you can add the DYLD_INSERT_LIBRARIES as an Environment Variable to the service's plist.

A simple example of its usage is with the libGMalloc library that resides in /usr/lib/.
Execute the following shell command and note the output: -

Code: Select all
DYLD_INSERT_LIBRARIES=/usr/lib/libgmalloc.dylib `which ls`
TheDarkKnight
 
Posts: 26
Joined: Wed Dec 16, 2015 10:30 am

Re: Debugging complex daemons from start

Postby Siguza » Tue Sep 20, 2016 4:10 pm

I found the following in "man launchd.plist":

WaitForDebugger <boolean>
This optional key specifies that launchd should launch the job in a suspended state so that a debugger can be attached to the process as early as possible (at the first instruction).


"launchctl debug" is supposed to add that to a service, too.
I didn't try it, but does that not work(on iOS), or does that wait at a later point than where inserted libraries' constructors get executed?
User avatar
Siguza
Unicorn
 
Posts: 159
Joined: Thu Jan 28, 2016 10:38 am

Re: Debugging complex daemons from start

Postby TheDarkKnight » Wed Sep 21, 2016 7:44 am

WaitForDebugger works as expected.

The problem I've found with using launchctl debug is that it doesn't often work. I think that may be due to the cache, which is described in the man pages as:

launchd maintains an in-memory cache of XPC service configuration files to minimize the disk I/O


Whilst there's an option for uncache service-name in the man pages, it returns
Command is not yet implemented
TheDarkKnight
 
Posts: 26
Joined: Wed Dec 16, 2015 10:30 am

Re: Debugging complex daemons from start

Postby backendbilly » Wed Sep 21, 2016 1:37 pm

J is referring to the use of the environment variable DYLD_INSERT_LIBRARIES, which is mentioned briefly in MOXiI on p129.

That was my first thought too. I'm familiar with DYLD_INSERT_LIBRARIES but wasn't sure how to use within a launchd config. Then I came across this https://www.theiphonewiki.com/wiki/Launchd.conf_Untether. I haven't tried it yet.

WaitForDebugger <boolean>


That was my first try is to configure the /System/Library/LaunchDaemons/.. plist file and add a "WaitForDebugger". Never seemed to work on iOS

Billy
backendbilly
Site Admin
 
Posts: 132
Joined: Fri May 29, 2015 5:58 pm

Re: Debugging complex daemons from start

Postby morpheus » Wed Sep 21, 2016 4:57 pm

As far as I can remember (it's been a while) WFD never worked for me on iOS. Hence the DYLD_INSERT_LIBRARIES suggestion. dont bother with launchd.conf - it's removed as of iOS 8.

Add to your plist:

<key>EnvironmentVariables</key>
<dict>
<key>DYLD_INSERT_LIBRARIES</key>
<string>/path/to/libname.dylib</string>
</dict>

Caveat: as of 9.2.x for some value of x launchd refuses this variable. But there's a clever workaround I'm not sure I can share here because AAPL might plug it.
morpheus
Site Admin
 
Posts: 532
Joined: Thu Apr 11, 2013 6:24 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 5 guests