iOS - uninvoked signal handlers

The signal handlers I register don't seem to be invoked when their associated signals are delivered to my process on iOS.


Is there something I specifically need to do on iOS to enable user handling of signals? Can't find any documentation on this.


For example, the following won't work, when ran from an iOS app, but will work when compiled and run on OS X.


    #include <signal.h>
   
    volatile int fooC = 0;
    volatile int fooPosix = 0;
   
    void posixHandler(int sig, siginfo_t *info, void *uap)
    {
         fooPosix = 1;
    }
   
    void cHandler(int sig)
    {
         fooC = 1;
    }
   
    int fn()
    {
         struct sigaction sigAction = {0};
         sigAction.sa_sigaction = &posixHandler;
         sigAction.sa_flags = SA_SIGINFO;
   
         if(sigaction(SIGUSR1, &sigAction, NULL) == -1)
         {
              return -1;
         }
         if(signal(SIGUSR2, &cHandler) == SIG_ERR)
         {
              return -1;
         }
   
         raise(SIGUSR1);
         raise(SIGUSR2);
   
         while(fooC == 0 && fooPosix == 0) ;
   
         return 0;
    }
Answered by DTS Engineer in 153760022

Questions about signal handling almost always raise the What are you really trying to do? response. I’ll come to that later, but first let’s look at your issue as stated.

You wrote:

For example, the following won't work, when ran from an iOS app, but will work when compiled and run on OS X.

That code works for me. I put your code into a new test project (based on the Single View Application template), tweaked it to log the result:

NSLog(@">wait");
while(fooC == 0 && fooPosix == 0) ; 
NSLog(@"<wait %d %d", fooC, fooPosix);

called

fn
in
-viewDidLoad
, then ran it on my device (iPod touch (5th generation), iOS 9.3.2). It worked as you’d expected:
Jul 13 05:59:22 VPhone SigTest[574] <Warning>: >wait
Jul 13 05:59:22 VPhone SigTest[574] <Warning>: <wait 1 1

The only gotcha is that I have to run the app from the home screen, rather than Xcode, because Xcode’s debugger catches signals.

Notwithstanding all of the above, I really have to ask about your high-level goals here. While there are very rare cases where writing a signal handler is the right thing to do on iOS, they are few and far between. Why are you doing this?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Accepted Answer

Questions about signal handling almost always raise the What are you really trying to do? response. I’ll come to that later, but first let’s look at your issue as stated.

You wrote:

For example, the following won't work, when ran from an iOS app, but will work when compiled and run on OS X.

That code works for me. I put your code into a new test project (based on the Single View Application template), tweaked it to log the result:

NSLog(@">wait");
while(fooC == 0 && fooPosix == 0) ; 
NSLog(@"<wait %d %d", fooC, fooPosix);

called

fn
in
-viewDidLoad
, then ran it on my device (iPod touch (5th generation), iOS 9.3.2). It worked as you’d expected:
Jul 13 05:59:22 VPhone SigTest[574] <Warning>: >wait
Jul 13 05:59:22 VPhone SigTest[574] <Warning>: <wait 1 1

The only gotcha is that I have to run the app from the home screen, rather than Xcode, because Xcode’s debugger catches signals.

Notwithstanding all of the above, I really have to ask about your high-level goals here. While there are very rare cases where writing a signal handler is the right thing to do on iOS, they are few and far between. Why are you doing this?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your response.


I totally thought lldb would pass on signals to my process! Thank you for pointing out this isn't the case - asking lldb to do so fixed everything. Feel foolish now.


As for your earlier question, I'm using signals to notify me when my aio_read() completes. I know there are other options, but from my understanding, this API has the lowest overhead. Building game engine, and this is part of the platform-side of the asset system.

aio is probably not the right answer on Darwin kernels. I recommend you take a look at Dispatch I/O instead; see

dispatch_io_create
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your reply (again).


I have looked at Dispatch I/O, but my initial understanding was that was a higher-level API that may call into aio down the line - though I havn't looked into this.


Edit: I looked at the open source XNU project, and it seems like aio is implemented down in BSD - but GCD nowhere to be found.


Being part of the Core OS/Hardware team, if you say otherwise, I'll take a look at it.


Is there any particular reason you recommend Dispatch I/O?


Thanks,

Zach

I looked at the open source XNU project, and it seems like aio is implemented down in BSD - but GCD nowhere to be found.

The droid you’re looking for is libdispatch.

Is there any particular reason you recommend Dispatch I/O?

Well, for a start, it gets you out of the business of dealing with signals (-:

Seriously though, I’ve not looked at Dispatch I/O’s implementation in enough detail to discuss its intricacies. I will say that I know the folks who worked on it and I’m quite confident that they’d recommend it over aio. If you want to hear one of those engineers discuss its pros, check out WWDC 2011 Session 210 Mastering Grand Central Dispatch (starting at 27:55).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
iOS - uninvoked signal handlers
 
 
Q