Ensure Objective-C Code Execution Before Cocoa Exit Applications

Suppose a cocoa application needs to perform some vital objective-c operation before it exits (for any reason, a failure or exit).

Is it possible to enforce arbitrary objective-c code in response to every failure event? ( SIGINT, SIGBUS, SIGSEGV, Etc., ignoring "uncatchables" ( SIGSTOP, SIGKILL, lightning bolt, etc.))


It would be helpful to know what your hooks are trying to do.

For example: let's say that for the application to work, it is absolutely necessary to change the value of some mutable system-wide configuration variable X. When launched, the application receives a snapshot of the current state of X, and then modifies it. When the application successfully exits, it simply restores X to its predetermined initial value before exiting. My question is this: is it possible to guarantee that X will be restored even if the application terminates with an error?

+5
source share
3 answers

The short answer is no.

A longer answer is still missing, but you can minimize the possibility of not using reset a config variable with a mutable system. In the scheme:

  • When launched, your application will create a faceless background process;
  • , ( wait(2) ) ;
  • .

, , , , . , reset .

+3

, , - , (, ).

.

, , . ( ) ( ).

.


, .

" " " - ". , .

. .

, , undefined, . , , .

, , , , .

, .


. sigaction.

, , , _exit(), access(), alarm(), cfgetispeed(), cfgetospeed(), cfsetispeed(), cfsetospeed(), chdir(), chmod(), chown(), close(), creat(), dup(), dup2(), execle(), execve(), fcntl(), fork(), fpathconf(), fstat(), fsync(), getegid(), geteuid(), getgid(), getgroups(),    getpgrp(), getpid(), getppid(), getuid(), kill(), link(), lseek(), mkdir(), mkfifo(), open(), pathconf(), pause(), pipe (), raise(), read(), rename(), rmdir(), setgid(), setpgid(), setsid(), setuid(), sigaction(), sigaddset(), sigdelset(), sigemptyset(),    sigfillset(), sigismember(), signal(), sigpending(), sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), tcdrain(), tcflow(), tcflush(), tcgetattr (), tcgetpgrp(), tcsendbreak(), tcsetattr(), tcsetpgrp(), time(), times(), umask(), uname(), unlink(), utime(),    wait(), waitpid(), write(), aio_error(), sigpause(), aio_return(), aio_suspend(), sem_post(), sigset(), strcpy(), strcat(), strncpy(), strncat (), strlcpy() strlcat().

, , . , undefined. , , ; .

: .

Mpte a; sp tjat sogma;, au ne de; overed pm amu tjread amd, ogjt ne de; overed nu .

: , . , , .

+6

, .

    signal(SIGBUS, signalHandler);
    signal(SIGSEGV, signalHandler);

void signalHandler(int signal)
{   
    NSMutableString *crashReport = [[NSMutableString alloc] init];
    void* callstack[128];
    int i, frames = backtrace(callstack, 128);
    char** strs = backtrace_symbols(callstack, frames);
    for (i = 0; i < frames; ++i) {
        //printf("%s\n", strs[i]);
        [crashReport appendFormat:@"%s\n",strs[i]];

    }
    free(strs);
    // write crashReport to file
    [crashReport release];
    exit(1);
}  

but if the failure is included in NSMutableString or freed or in the free () function, this code will not work. (As bbum explains :
there is no way to guarantee that any given piece of code will be executed when the application terminates)

+1
source

All Articles