Projects
Browse Source     Search     Timeline     Wiki

Changeset 23051

Show
Ignore:
Timestamp:
02/09/07 09:56:21 (22 months ago)
Author:
zarzycki@…
Message:

Better shutdown debugging.

Location:
trunk/launchd/src
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • trunk/launchd/src/launchd.c

    r23045 r23051  
    395395launchd_shutdown(void) 
    396396{ 
     397        struct stat sb; 
     398 
    397399        if (shutdown_in_progress) { 
    398400                return; 
     
    401403        shutdown_in_progress = true; 
    402404 
    403 #if 0 
    404         struct stat sb; 
    405  
    406         if (stat("/var/db/debugShutdownHangs", &sb) != -1) { 
    407                 /* 
    408                  * When this changes to a more sustainable API, update this: 
    409                  * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown 
    410                  */ 
    411                 debug_shutdown_hangs = true; 
    412         } 
    413 #else 
    414405        if (getpid() == 1) { 
     406                if (stat("/var/db/debugShutdownHangs", &sb) != -1) { 
     407                        /* 
     408                         * When this changes to a more sustainable API, update this: 
     409                         * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown 
     410                         */ 
     411                        debug_shutdown_hangs = true; 
     412                } 
     413 
    415414                launchd_assumes(kevent_mod((uintptr_t)debugshutdown_callback, 
    416415                                        EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 5, &kqdebugshutdown_callback) != -1); 
    417416        } 
    418 #endif 
    419417 
    420418        rlcj = NULL; 
     
    655653 
    656654        if (launchd_assumes(posix_spawn(&sddp, sdd_args[0], NULL, NULL, sdd_args, environ) == 0)) { 
    657                 launchd_assumes(kevent_mod(sddp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqsimple_zombie_reaper) != -1); 
    658         } 
    659 } 
     655                int wstatus; 
     656 
     657                /* No bootstrap port was given. It is safe to block. */ 
     658                launchd_assumes(waitpid(sddp, &wstatus, 0) != -1); 
     659        } 
     660} 
  • trunk/launchd/src/launchd.h

    r23045 r23051  
    3232struct conncb; 
    3333 
    34 extern kq_callback kqsimple_zombie_reaper; 
    3534extern sigset_t blocked_signals; 
    3635extern bool debug_shutdown_hangs; 
  • trunk/launchd/src/launchd_core_logic.c

    r23050 r23051  
    338338static bool cronemu_min(struct tm *wtm, int min); 
    339339 
    340 static void simple_zombie_reaper(void *, struct kevent *); 
    341  
    342 kq_callback kqsimple_zombie_reaper = simple_zombie_reaper; 
    343  
    344340static int dir_has_files(job_t j, const char *path); 
    345341static char **mach_cmd2argv(const char *string); 
    346342jobmgr_t root_jobmgr; 
    347343jobmgr_t gc_this_jobmgr; 
    348  
    349 void 
    350 simple_zombie_reaper(void *obj __attribute__((unused)), struct kevent *kev) 
    351 { 
    352         waitpid(kev->ident, NULL, 0); 
    353 } 
    354344 
    355345void 
     
    17801770                        job_dispatch(j, true); 
    17811771                } else if ((uintptr_t)&j->exit_timeout == kev->ident) { 
    1782                         if (debug_shutdown_hangs) { 
    1783                                 job_force_sampletool(j); 
    1784                         } 
     1772                        job_force_sampletool(j); 
    17851773                        job_log(j, LOG_WARNING, "Exit timeout elapsed (%u seconds). Killing.", j->exit_timeout); 
    17861774                        job_assumes(j, kill(j->p, SIGKILL) != -1); 
     
    36263614job_force_sampletool(job_t j) 
    36273615{ 
    3628         char *sample_args[] = { "sample", NULL, "1", "-mayDie", NULL }; 
     3616        struct stat sb; 
     3617        char logfile[PATH_MAX]; 
    36293618        char pidstr[100]; 
     3619        char *sample_args[] = { "sample", pidstr, "1", "-mayDie", "-file", logfile, NULL }; 
     3620        char *contents = NULL; 
     3621        int logfile_fd = -1; 
     3622        int console_fd = -1; 
    36303623        pid_t sp; 
     3624 
     3625        if (!debug_shutdown_hangs) { 
     3626                return; 
     3627        } 
    36313628         
    36323629        snprintf(pidstr, sizeof(pidstr), "%u", j->p); 
    3633         sample_args[1] = pidstr; 
    3634  
    3635         if (job_assumes(j, posix_spawnp(&sp, sample_args[0], NULL, NULL, sample_args, environ) == 0)) { 
    3636                 job_assumes(j, kevent_mod(sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, &kqsimple_zombie_reaper) != -1); 
     3630        snprintf(logfile, sizeof(logfile), "/var/log/shutdown/%s-%u.sample.txt", j->label, j->p); 
     3631 
     3632        job_assumes(j, mkdir("/var/log/shutdown", S_IRWXU) != -1 || errno == EEXIST); 
     3633 
     3634        /* 
     3635         * This will stall launchd for as long as the 'sample' tool runs. 
     3636         * 
     3637         * We didn't give the 'sample' tool a bootstrap port, so it therefore 
     3638         * can't deadlock against launchd. 
     3639         */ 
     3640        if (job_assumes(j, (errno = posix_spawnp(&sp, sample_args[0], NULL, NULL, sample_args, environ)) == 0)) { 
     3641                int wstatus; 
     3642 
     3643                job_assumes(j, waitpid(sp, &wstatus, 0) != -1); 
     3644        } 
     3645 
     3646        if (!job_assumes(j, (logfile_fd = open(logfile, O_RDONLY|O_NOCTTY)) != -1)) { 
     3647                goto out; 
     3648        } 
     3649 
     3650        if (!job_assumes(j, (console_fd = open(_PATH_CONSOLE, O_WRONLY|O_APPEND||O_NOCTTY)) != -1)) { 
     3651                goto out; 
     3652        } 
     3653 
     3654        if (!job_assumes(j, fstat(logfile_fd, &sb) != -1)) { 
     3655                goto out; 
     3656        } 
     3657 
     3658        contents = malloc(sb.st_size); 
     3659 
     3660        if (!job_assumes(j, contents != NULL)) { 
     3661                goto out; 
     3662        } 
     3663 
     3664        if (!job_assumes(j, read(logfile_fd, contents, sb.st_size) == sb.st_size)) { 
     3665                goto out; 
     3666        } 
     3667 
     3668        job_assumes(j, write(console_fd, contents, sb.st_size) == sb.st_size); 
     3669 
     3670out: 
     3671        if (contents) { 
     3672                free(contents); 
     3673        } 
     3674 
     3675        if (logfile_fd != -1) { 
     3676                job_assumes(j, close(logfile_fd) != -1); 
     3677        } 
     3678 
     3679        if (console_fd != -1) { 
     3680                job_assumes(j, close(console_fd) != -1); 
    36373681        } 
    36383682}