[launchd-changes] [23076] trunk/launchd/src
source_changes at macosforge.org
source_changes at macosforge.org
Thu Feb 15 19:17:34 PST 2007
Revision: 23076
http://trac.macosforge.org/projects/launchd/changeset/23076
Author: zarzycki at apple.com
Date: 2007-02-15 19:17:34 -0800 (Thu, 15 Feb 2007)
Log Message:
-----------
<rdar://problem/4999570> change to stackshot mechanism is yielding bogus stackshot logs
Modified Paths:
--------------
trunk/launchd/src/Makefile.am
trunk/launchd/src/Makefile.in
trunk/launchd/src/launchd.c
Removed Paths:
-------------
trunk/launchd/src/shutdown_debugger.8
trunk/launchd/src/shutdown_debugger.c
Modified: trunk/launchd/src/Makefile.am
===================================================================
--- trunk/launchd/src/Makefile.am 2007-02-16 02:51:55 UTC (rev 23075)
+++ trunk/launchd/src/Makefile.am 2007-02-16 03:17:34 UTC (rev 23076)
@@ -32,7 +32,7 @@
bin_PROGRAMS = launchctl wait4path
sbin_PROGRAMS = launchd SystemStarter
-libexec_PROGRAMS = launchproxy shutdown_debugger
+libexec_PROGRAMS = launchproxy
sysconf_DATA = hostconfig rc.common rc.netboot rc.shutdown
@@ -66,7 +66,7 @@
man5_MANS = launchd.plist.5 launchd.conf.5
-man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8 shutdown_debugger.8
+man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8
STARTUPITEMS = $(basename $(notdir $(wildcard $(srcdir)/StartupItems/*.plist)))
Modified: trunk/launchd/src/Makefile.in
===================================================================
--- trunk/launchd/src/Makefile.in 2007-02-16 02:51:55 UTC (rev 23075)
+++ trunk/launchd/src/Makefile.in 2007-02-16 03:17:34 UTC (rev 23076)
@@ -40,8 +40,7 @@
@LIBS_ONLY_FALSE at bin_PROGRAMS = launchctl$(EXEEXT) wait4path$(EXEEXT)
@LIBS_ONLY_FALSE at sbin_PROGRAMS = launchd$(EXEEXT) \
@LIBS_ONLY_FALSE@ SystemStarter$(EXEEXT)
- at LIBS_ONLY_FALSE@libexec_PROGRAMS = launchproxy$(EXEEXT) \
- at LIBS_ONLY_FALSE@ shutdown_debugger$(EXEEXT)
+ at LIBS_ONLY_FALSE@libexec_PROGRAMS = launchproxy$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.h.in
@@ -110,9 +109,6 @@
launchproxy_SOURCES = launchproxy.c
launchproxy_OBJECTS = launchproxy.$(OBJEXT)
launchproxy_LDADD = $(LDADD)
-shutdown_debugger_SOURCES = shutdown_debugger.c
-shutdown_debugger_OBJECTS = shutdown_debugger.$(OBJEXT)
-shutdown_debugger_LDADD = $(LDADD)
wait4path_SOURCES = wait4path.c
wait4path_OBJECTS = wait4path.$(OBJEXT)
wait4path_LDADD = $(LDADD)
@@ -127,12 +123,11 @@
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(liblaunch_a_SOURCES) $(liblaunch_profile_a_SOURCES) \
$(SystemStarter_SOURCES) launchctl.c $(launchd_SOURCES) \
- launchproxy.c shutdown_debugger.c wait4path.c
+ launchproxy.c wait4path.c
DIST_SOURCES = $(am__liblaunch_a_SOURCES_DIST) \
$(am__liblaunch_profile_a_SOURCES_DIST) \
$(am__SystemStarter_SOURCES_DIST) launchctl.c \
- $(am__launchd_SOURCES_DIST) launchproxy.c shutdown_debugger.c \
- wait4path.c
+ $(am__launchd_SOURCES_DIST) launchproxy.c wait4path.c
man1dir = $(mandir)/man1
man5dir = $(mandir)/man5
man8dir = $(mandir)/man8
@@ -253,7 +248,7 @@
@LIBS_ONLY_FALSE at launchproxy_LDFLAGS = -weak_framework Security
@LIBS_ONLY_FALSE at man1_MANS = wait4path.1 launchctl.1
@LIBS_ONLY_FALSE at man5_MANS = launchd.plist.5 launchd.conf.5
- at LIBS_ONLY_FALSE@man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8 shutdown_debugger.8
+ at LIBS_ONLY_FALSE@man8_MANS = StartupItemContext.8 SystemStarter.8 rc.8 launchd.8 service.8 launchproxy.8
@LIBS_ONLY_FALSE at STARTUPITEMS = $(basename $(notdir $(wildcard $(srcdir)/StartupItems/*.plist)))
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -398,9 +393,6 @@
launchproxy$(EXEEXT): $(launchproxy_OBJECTS) $(launchproxy_DEPENDENCIES)
@rm -f launchproxy$(EXEEXT)
$(LINK) $(launchproxy_LDFLAGS) $(launchproxy_OBJECTS) $(launchproxy_LDADD) $(LIBS)
-shutdown_debugger$(EXEEXT): $(shutdown_debugger_OBJECTS) $(shutdown_debugger_DEPENDENCIES)
- @rm -f shutdown_debugger$(EXEEXT)
- $(LINK) $(shutdown_debugger_LDFLAGS) $(shutdown_debugger_OBJECTS) $(shutdown_debugger_LDADD) $(LIBS)
wait4path$(EXEEXT): $(wait4path_OBJECTS) $(wait4path_DEPENDENCIES)
@rm -f wait4path$(EXEEXT)
$(LINK) $(wait4path_LDFLAGS) $(wait4path_OBJECTS) $(wait4path_LDADD) $(LIBS)
@@ -453,7 +445,6 @@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/liblaunch_profile_a-protocol_vprocUser.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libvproc.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/protocol_vprocUser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/shutdown_debugger.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wait4path.Po at am__quote@
.c.o:
Modified: trunk/launchd/src/launchd.c
===================================================================
--- trunk/launchd/src/launchd.c 2007-02-16 02:51:55 UTC (rev 23075)
+++ trunk/launchd/src/launchd.c 2007-02-16 03:17:34 UTC (rev 23076)
@@ -79,15 +79,15 @@
#define PID1LAUNCHD_CONF "/etc/launchd.conf"
#define LAUNCHD_CONF ".launchd.conf"
#define SECURITY_LIB "/System/Library/Frameworks/Security.framework/Versions/A/Security"
+#define SHUTDOWN_LOG_DIR "/var/log/shutdown"
+
extern char **environ;
static void signal_callback(void *, struct kevent *);
-static void debugshutdown_callback(void);
static void pfsystem_callback(void *, struct kevent *);
static kq_callback kqsignal_callback = signal_callback;
-static kq_callback kqdebugshutdown_callback = (kq_callback)debugshutdown_callback;
static kq_callback kqpfsystem_callback = pfsystem_callback;
static void pid1_magic_init(bool sflag);
@@ -99,6 +99,7 @@
static void monitor_networking_state(void);
static void fatal_signal_handler(int sig, siginfo_t *si, void *uap);
static void handle_pid1_crashes_separately(void);
+static void prep_shutdown_log_dir(void);
static bool re_exec_in_single_user_mode = false;
static job_t rlcj = NULL;
@@ -392,6 +393,51 @@
}
void
+prep_shutdown_log_dir(void)
+{
+ struct stat sb;
+ struct dirent *de;
+ DIR *thedir = NULL;
+
+ if (!launchd_assumes(mkdir(SHUTDOWN_LOG_DIR, S_IRWXU) != -1 || errno == EEXIST)) {
+ goto out;
+ }
+
+ if (!launchd_assumes(lstat(SHUTDOWN_LOG_DIR, &sb) != -1)) {
+ goto out;
+ }
+
+ if (!launchd_assumes(S_ISDIR(sb.st_mode))) {
+ goto out;
+ }
+
+ if (!launchd_assumes(chdir(SHUTDOWN_LOG_DIR) != -1)) {
+ goto out;
+ }
+
+ if (!launchd_assumes((thedir = opendir(".")) != NULL)) {
+ goto out;
+ }
+
+ while ((de = readdir(thedir))) {
+ if (strcmp(de->d_name, ".") == 0) {
+ continue;
+ } else if (strcmp(de->d_name, "..") == 0) {
+ continue;
+ } else {
+ launchd_assumes(remove(de->d_name) != -1);
+ }
+ }
+
+out:
+ if (thedir) {
+ closedir(thedir);
+ }
+
+ chdir("/");
+}
+
+void
launchd_shutdown(void)
{
struct stat sb;
@@ -402,17 +448,13 @@
shutdown_in_progress = true;
- if (getpid() == 1) {
- if (stat("/var/db/debugShutdownHangs", &sb) != -1) {
- /*
- * When this changes to a more sustainable API, update this:
- * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown
- */
- debug_shutdown_hangs = true;
- }
-
- launchd_assumes(kevent_mod((uintptr_t)debugshutdown_callback,
- EVFILT_TIMER, EV_ADD|EV_ONESHOT, NOTE_SECONDS, 5, &kqdebugshutdown_callback) != -1);
+ if (getpid() == 1 && stat("/var/db/debugShutdownHangs", &sb) != -1) {
+ /*
+ * When this changes to a more sustainable API, update this:
+ * http://howto.apple.com/db.cgi?Debugging_Apps_Non-Responsive_At_Shutdown
+ */
+ prep_shutdown_log_dir();
+ debug_shutdown_hangs = true;
}
rlcj = NULL;
@@ -643,17 +685,3 @@
init_pre_kevent();
}
}
-
-void
-debugshutdown_callback(void)
-{
- char *sdd_args[] = { "/usr/libexec/shutdown_debugger", NULL };
- pid_t sddp;
-
- if (launchd_assumes(posix_spawn(&sddp, sdd_args[0], NULL, NULL, sdd_args, environ) == 0)) {
- int wstatus;
-
- /* No bootstrap port was given. It is safe to block. */
- launchd_assumes(waitpid(sddp, &wstatus, 0) != -1);
- }
-}
Deleted: trunk/launchd/src/shutdown_debugger.8
===================================================================
--- trunk/launchd/src/shutdown_debugger.8 2007-02-16 02:51:55 UTC (rev 23075)
+++ trunk/launchd/src/shutdown_debugger.8 2007-02-16 03:17:34 UTC (rev 23076)
@@ -1,10 +0,0 @@
-.Dd December 14, 2006
-.Dt shutdown_debugger 8
-.Os Darwin
-.Sh NAME
-.Nm shutdown_debugger
-.Nd tool to aid debugging shutdowns
-.Sh SYNOPSIS
-.Nm
-.Sh DESCRIPTION
-This tool is invoked a few seconds after a shutdown or reboot request to figure out why the machine isn't off yet. Useful debug files are placed in /var/log/shutdown.
Deleted: trunk/launchd/src/shutdown_debugger.c
===================================================================
--- trunk/launchd/src/shutdown_debugger.c 2007-02-16 02:51:55 UTC (rev 23075)
+++ trunk/launchd/src/shutdown_debugger.c 2007-02-16 03:17:34 UTC (rev 23076)
@@ -1,537 +0,0 @@
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <mach_debug/ipc_info.h>
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/event.h>
-#include <sys/sysctl.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <spawn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <unistd.h>
-#include <signal.h>
-#include <dirent.h>
-
-extern char **environ;
-
-struct hproc {
- TAILQ_ENTRY(hproc) tqe;
- pid_t stuck_p;
- pid_t sample_p;
-};
-
-static void hproc_new(pid_t p, const char *pname);
-
-static TAILQ_HEAD(hproc_head, hproc) hprocs = TAILQ_HEAD_INITIALIZER(hprocs);
-
-static void populate_proc_list(void);
-static void debug_machports(pid_t pid, const char *pname);
-static void debug_machports2(pid_t pid, FILE *where);
-static void do_stackshot(void);
-
-static int kq;
-
-#define SHUTDOWN_LOG_DIR "/var/log/shutdown"
-
-int
-main(void)
-{
- struct kevent kev;
- struct stat sb;
- struct hproc *hp;
- struct dirent *de;
- DIR *thedir;
- int wstatus;
-
- mkdir(SHUTDOWN_LOG_DIR, S_IRWXU);
-
- assert(lstat(SHUTDOWN_LOG_DIR, &sb) != -1);
-
- assert(S_ISDIR(sb.st_mode));
-
- assert(chdir(SHUTDOWN_LOG_DIR) != -1);
-
- assert((thedir = opendir(".")) != NULL);
-
- while ((de = readdir(thedir))) {
- if (strcmp(de->d_name, ".") == 0) {
- continue;
- } else if (strcmp(de->d_name, "..") == 0) {
- continue;
- } else {
- remove(de->d_name);
- }
- }
-
- closedir(thedir);
-
- do_stackshot();
-
- assert((kq = kqueue()) != -1);
-
- debug_machports(1, "launchd");
-
- populate_proc_list();
-
- while (!TAILQ_EMPTY(&hprocs)) {
- assert(kevent(kq, NULL, 0, &kev, 1, NULL) != -1);
-
- hp = kev.udata;
-
- assert(waitpid(hp->sample_p, &wstatus, 0) != -1);
-
- TAILQ_REMOVE(&hprocs, hp, tqe);
- }
-
- exit(EXIT_SUCCESS);
-}
-
-void
-populate_proc_list(void)
-{
- int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
- struct kinfo_proc *kp = NULL;
- size_t i, len = 0;
-
- assert(sysctl(mib, 3, kp, &len, NULL, 0) != -1);
-
- assert((kp = malloc(len * 2)) != NULL);
-
- assert(sysctl(mib, 3, kp, &len, NULL, 0) != -1);
-
- for (i = 0; i < (len / sizeof(struct kinfo_proc)); i++) {
- pid_t p_iter = kp[i].kp_proc.p_pid;
-
- if (p_iter == 0 || p_iter == 1 || p_iter == getpid()) {
- continue;
- }
-
- hproc_new(p_iter, kp[i].kp_proc.p_comm);
- }
-
- free(kp);
-}
-
-void
-hproc_new(pid_t p, const char *pname)
-{
- char pidstr[100], logfile[PATH_MAX];
- char *sample_args[] = { "sample", pidstr, "1", "-mayDie", "-file", logfile, NULL };
- posix_spawnattr_t spattr;
- struct kevent kev;
- struct hproc *hp;
- pid_t sp;
-
- debug_machports(p, pname);
-
- assert((hp = calloc(1, sizeof(struct hproc))) != NULL);
-
- assert(posix_spawnattr_init(&spattr) == 0);
-
- assert(posix_spawnattr_setflags(&spattr, POSIX_SPAWN_START_SUSPENDED) == 0);
-
- snprintf(pidstr, sizeof(pidstr), "%u", p);
- snprintf(logfile, sizeof(logfile), "%s-%u.sample.txt", pname, p);
-
- assert(posix_spawnp(&sp, sample_args[0], NULL, &spattr, sample_args, environ) == 0);
-
- assert(posix_spawnattr_destroy(&spattr) == 0);
-
- EV_SET(&kev, sp, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, hp);
-
- assert(kevent(kq, &kev, 1, NULL, 0, NULL) != -1);
-
- assert(kill(sp, SIGCONT) != -1);
-
- hp->stuck_p = p;
- hp->sample_p = sp;
-
- TAILQ_INSERT_TAIL(&hprocs, hp, tqe);
-}
-
-void
-debug_machports(pid_t pid, const char *pname)
-{
- char logfilepath[PATH_MAX];
- FILE *mplogfile;
-
- snprintf(logfilepath, sizeof(logfilepath), "%s-%u.machports.txt", pname, pid);
-
- assert((mplogfile = fopen(logfilepath, "a")) != NULL);
-
- debug_machports2(pid, mplogfile);
-
- fclose(mplogfile);
-}
-
-
-/*
- * WARNING - these types are copied from xnu/osfmk/kern/ipc_kobject.h
- * Need to stay in sync to print accurate results.
- */
-#define IKOT_NONE 0
-#define IKOT_THREAD 1
-#define IKOT_TASK 2
-#define IKOT_HOST 3
-#define IKOT_HOST_PRIV 4
-#define IKOT_PROCESSOR 5
-#define IKOT_PSET 6
-#define IKOT_PSET_NAME 7
-#define IKOT_TIMER 8
-#define IKOT_PAGING_REQUEST 9
-#define IKOT_MIG 10
-#define IKOT_MEMORY_OBJECT 11
-#define IKOT_XMM_PAGER 12
-#define IKOT_XMM_KERNEL 13
-#define IKOT_XMM_REPLY 14
-#define IKOT_UND_REPLY 15
-#define IKOT_HOST_NOTIFY 16
-#define IKOT_HOST_SECURITY 17
-#define IKOT_LEDGER 18
-#define IKOT_MASTER_DEVICE 19
-#define IKOT_TASK_NAME 20
-#define IKOT_SUBSYSTEM 21
-#define IKOT_IO_DONE_QUEUE 22
-#define IKOT_SEMAPHORE 23
-#define IKOT_LOCK_SET 24
-#define IKOT_CLOCK 25
-#define IKOT_CLOCK_CTRL 26
-#define IKOT_IOKIT_SPARE 27
-#define IKOT_NAMED_ENTRY 28
-#define IKOT_IOKIT_CONNECT 29
-#define IKOT_IOKIT_OBJECT 30
-#define IKOT_UPL 31
-
-static const char *
-kobject_name(natural_t kotype)
-{
- switch (kotype) {
- case IKOT_NONE: return "message-queue";
- case IKOT_THREAD: return "kobject(THREAD)";
- case IKOT_TASK: return "kobject(TASK)";
- case IKOT_HOST: return "kobject(HOST)";
- case IKOT_HOST_PRIV: return "kobject(HOST-PRIV)";
- case IKOT_PROCESSOR: return "kobject(PROCESSOR)";
- case IKOT_PSET: return "kobject(PROCESSOR-SET)";
- case IKOT_PSET_NAME: return "kobject(PROCESSOR-SET-NAME)";
- case IKOT_TIMER: return "kobject(TIMER)";
- case IKOT_PAGING_REQUEST: return "kobject(PAGER-REQUEST)";
- case IKOT_MIG: return "kobject(MIG)";
- case IKOT_MEMORY_OBJECT: return "kobject(MEMORY-OBJECT)";
- case IKOT_XMM_PAGER: return "kobject(XMM-PAGER)";
- case IKOT_XMM_KERNEL: return "kobject(XMM-KERNEL)";
- case IKOT_XMM_REPLY: return "kobject(XMM-REPLY)";
- case IKOT_UND_REPLY: return "kobject(UND-REPLY)";
- case IKOT_HOST_NOTIFY: return "message-queue";
- case IKOT_HOST_SECURITY: return "kobject(HOST-SECURITY)";
- case IKOT_LEDGER: return "kobject(LEDGER)";
- case IKOT_MASTER_DEVICE: return "kobject(MASTER-DEVICE)";
- case IKOT_TASK_NAME: return "kobject(TASK-NAME)";
- case IKOT_SUBSYSTEM: return "kobject(SUBSYSTEM)";
- case IKOT_IO_DONE_QUEUE: return "kobject(IO-QUEUE-DONE)";
- case IKOT_SEMAPHORE: return "kobject(SEMAPHORE)";
- case IKOT_LOCK_SET: return "kobject(LOCK-SET)";
- case IKOT_CLOCK: return "kobject(CLOCK)";
- case IKOT_CLOCK_CTRL: return "kobject(CLOCK-CONTROL)";
- case IKOT_IOKIT_SPARE: return "kobject(IOKIT-SPARE)";
- case IKOT_NAMED_ENTRY: return "kobject(NAMED-MEMORY)";
- case IKOT_IOKIT_CONNECT: return "kobject(IOKIT-CONNECT)";
- case IKOT_IOKIT_OBJECT: return "kobject(IOKIT-OBJECT)";
- case IKOT_UPL: return "kobject(UPL)";
- default: return "kobject(UNKNOWN)";
- }
-}
-
-/* private structure to wrap up per-task info */
-typedef struct my_per_task_info {
- task_t task;
- pid_t pid;
- ipc_info_space_t info;
- ipc_info_name_array_t table;
- mach_msg_type_number_t tableCount;
- ipc_info_tree_name_array_t tree;
- mach_msg_type_number_t treeCount;
-} my_per_task_info_t;
-
-void
-debug_machports2(pid_t pid, FILE *where)
-{
- kern_return_t ret;
- my_per_task_info_t aTask;
- my_per_task_info_t *taskinfo = NULL;
- my_per_task_info_t *psettaskinfo;
- mach_msg_type_number_t i, j, k, taskCount;
- int emptycount = 0, portsetcount = 0, sendcount = 0, receivecount = 0, sendoncecount = 0, deadcount = 0, dncount = 0;
-
- /* if priviledged, get the info for all tasks so we can match ports up */
- if (geteuid() == 0) {
- processor_set_name_array_t psets;
- mach_msg_type_number_t psetCount;
- mach_port_t pset_priv;
- task_array_t tasks;
-
- ret = host_processor_sets(mach_host_self(), &psets, &psetCount);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "host_processor_sets() failed: %s\n", mach_error_string(ret));
- return;
- }
- if (psetCount != 1) {
- fprintf(where, "Assertion Failure: pset count greater than one (%d)\n", psetCount);
- return;
- }
-
- /* convert the processor-set-name port to a privileged port */
- ret = host_processor_set_priv(mach_host_self(), psets[0], &pset_priv);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "host_processor_set_priv() failed: %s\n", mach_error_string(ret));
- return;
- }
- mach_port_deallocate(mach_task_self(), psets[0]);
- vm_deallocate(mach_task_self(), (vm_address_t)psets, (vm_size_t)psetCount * sizeof(mach_port_t));
-
- /* convert the processor-set-priv to a list of tasks for the processor set */
- ret = processor_set_tasks(pset_priv, &tasks, &taskCount);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "processor_set_tasks() failed: %s\n", mach_error_string(ret));
- return;
- }
- mach_port_deallocate(mach_task_self(), pset_priv);
-
- /* convert each task to structure of pointer for the task info */
- psettaskinfo = (my_per_task_info_t *)malloc(taskCount * sizeof(my_per_task_info_t));
- for (i = 0; i < taskCount; i++) {
- psettaskinfo[i].task = tasks[i];
- pid_for_task(tasks[i], &psettaskinfo[i].pid);
- ret = mach_port_space_info(tasks[i], &psettaskinfo[i].info,
- &psettaskinfo[i].table, &psettaskinfo[i].tableCount,
- &psettaskinfo[i].tree, &psettaskinfo[i].treeCount);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "mach_port_space_info() failed: %s\n", mach_error_string(ret));
- return;
- }
- if (psettaskinfo[i].pid == pid)
- taskinfo = &psettaskinfo[i];
- }
- vm_deallocate(mach_task_self(), (vm_address_t)tasks, (vm_size_t)taskCount * sizeof(mach_port_t));
- }
- else
- {
- /* just the one process */
- ret = task_for_pid((mach_task_self)(), pid, &aTask.task);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "task_for_pid() failed: %s\n", mach_error_string(ret));
- return;
- }
- ret = mach_port_space_info(aTask.task, &aTask.info,
- &aTask.table, &aTask.tableCount,
- &aTask.tree, &aTask.treeCount);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "mach_port_space_info() failed: %s\n", mach_error_string(ret));
- return;
- }
- taskinfo = &aTask;
- psettaskinfo = taskinfo;
- taskCount = 1;
- }
-
- fprintf(where, "set-name ipc-object rights ");
- fprintf(where, " member-cnt\n");
- fprintf(where, "recv-name ipc-object rights ");
- fprintf(where, "reqs urefs orefs qlimit msgcount\n");
- fprintf(where, "send-name ipc-object rights ");
- fprintf(where, "reqs urefs orefs kern-object type\n");
- fprintf(where, "--------where, - ---------- ---------- ");
- fprintf(where, "---where, - ----- ----- ----------- ------------\n");
-
- for (i = 0; i < taskinfo->tableCount; i++) {
- boolean_t found = FALSE;
- boolean_t sendr = FALSE;
- boolean_t sendonce = FALSE;
- boolean_t dnreq = FALSE;
- int sendrights = 0;
- unsigned int kotype = 0;
- vm_offset_t kobject = (vm_offset_t)0;
-
- /* skip empty slots in the table */
- if (taskinfo->table[i].iin_object == 0) {
- emptycount++;
- continue;
- }
-
- if (taskinfo->table[i].iin_type == MACH_PORT_TYPE_PORT_SET) {
- mach_port_name_array_t members;
- mach_msg_type_number_t membersCnt;
-
- ret = mach_port_get_set_status(taskinfo->task,
- taskinfo->table[i].iin_name,
- &members, &membersCnt);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "mach_port_get_set_status(0x%08x) failed: %s\n",
- taskinfo->table[i].iin_name,
- mach_error_string(ret));
- continue;
- }
- fprintf(where, "0x%08x 0x%08x port-set --- 1 %5d members\n",
- taskinfo->table[i].iin_name,
- taskinfo->table[i].iin_object,
- membersCnt);
- /* get some info for each portset member */
- for (j = 0; j < membersCnt; j++) {
- for (k = 0; k < taskinfo->tableCount; k++) {
- if (taskinfo->table[k].iin_name == members[j]) {
- fprintf(where, " 0x%08x %s --- 0x%08x process(%d)\n",
- taskinfo->table[k].iin_object,
- (taskinfo->table[k].iin_type & MACH_PORT_TYPE_SEND) ? "recv,send ":"recv ",
- taskinfo->table[k].iin_name,
- pid);
- break;
- }
- }
- }
-
- ret = vm_deallocate(mach_task_self(), (vm_address_t)members,
- membersCnt * sizeof(mach_port_name_t));
- if (ret != KERN_SUCCESS) {
- fprintf(where, "vm_deallocate() failed: %s\n",
- mach_error_string(ret));
- return;
- }
- portsetcount++;
- continue;
- }
-
- if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND) {
- sendr = TRUE;
- sendrights = taskinfo->table[i].iin_urefs;
- sendcount++;
- }
-
- if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_SEND_ONCE) {
- sendonce = TRUE;
- sendoncecount++;
- }
-
- if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DNREQUEST) {
- dnreq = TRUE;
- dncount++;
- }
-
- if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_RECEIVE) {
- mach_port_status_t status;
- mach_msg_type_number_t statusCnt;
-
- statusCnt = MACH_PORT_RECEIVE_STATUS_COUNT;
- ret = mach_port_get_attributes(taskinfo->task,
- taskinfo->table[i].iin_name,
- MACH_PORT_RECEIVE_STATUS,
- (mach_port_info_t)&status,
- &statusCnt);
- if (ret != KERN_SUCCESS) {
- fprintf(where, "mach_port_get_attributes(0x%08x) failed: %s\n",
- taskinfo->table[i].iin_name,
- mach_error_string(ret));
- continue;
- }
-
- fprintf(where, "0x%08x 0x%08x %s %s%s%s %5d %s(%02d) 0x%08x 0x%08x\n",
- taskinfo->table[i].iin_name,
- taskinfo->table[i].iin_object,
- (sendr) ? "recv,send ":"recv ",
- (dnreq) ? "D":"-",
- (status.mps_nsrequest) ? "N":"-",
- (status.mps_pdrequest) ? "P":"-",
- sendrights + 1,
- (status.mps_srights) ? "Y":"N",
- status.mps_sorights,
- status.mps_qlimit,
- status.mps_msgcount);
- receivecount++;
-
- /* show other rights (in this and other tasks) for the port */
- for (j = 0; j < taskCount; j++) {
- for (k = 0; k < psettaskinfo->tableCount; k++) {
- if (&psettaskinfo[j].table[k] == &taskinfo->table[i] ||
- psettaskinfo[j].table[k].iin_object != taskinfo->table[i].iin_object)
- continue;
- fprintf(where, " 0x%08x %s --- %5d 0x%08x process(%d)\n",
- psettaskinfo[j].table[k].iin_object,
- (psettaskinfo[j].table[k].iin_type & MACH_PORT_TYPE_SEND_ONCE) ?
- "send-once " : "send ",
- psettaskinfo[j].table[k].iin_urefs,
- psettaskinfo[j].table[k].iin_name,
- psettaskinfo[j].pid);
- }
- }
- continue;
- }
- else if (taskinfo->table[i].iin_type & MACH_PORT_TYPE_DEAD_NAME)
- {
- fprintf(where, "0x%08x 0x%08x dead-name --- %5d\n",
- taskinfo->table[i].iin_name,
- taskinfo->table[i].iin_object,
- taskinfo->table[i].iin_urefs);
- deadcount++;
- continue;
- }
-
- fprintf(where, "0x%08x 0x%08x %s %s%s%s %5d ",
- taskinfo->table[i].iin_name,
- taskinfo->table[i].iin_object,
- (sendr) ? "send ":"send-once ",
- (dnreq) ? "D":"-",
- "-",
- "-",
- (sendr) ? sendrights : 1);
-
- /* converting to kobjects is not always supported */
- ret = mach_port_kernel_object(taskinfo->task,
- taskinfo->table[i].iin_name,
- &kotype, &kobject);
- if (kotype != 0) {
- fprintf(where, "0x%08x %s\n", kobject, kobject_name(kotype));
- continue;
- }
-
- /* not kobject - find the receive right holder */
- for (j = 0; j < taskCount && !found; j++) {
- for (k = 0; k < psettaskinfo[j].tableCount && !found; k++) {
- if ((psettaskinfo[j].table[k].iin_type & MACH_PORT_TYPE_RECEIVE) &&
- psettaskinfo[j].table[k].iin_object == taskinfo->table[i].iin_object ) {
- fprintf(where, "0x%08x process(%d)\n",
- psettaskinfo[j].table[k].iin_name,
- psettaskinfo[j].pid);
- found = TRUE;
- }
- }
- }
- if (!found)
- fprintf(where, "0x00000000 process(unknown)\n");
- }
- fprintf(where, "total = %d\n", taskinfo->tableCount + taskinfo->treeCount - emptycount);
- fprintf(where, "SEND = %d\n", sendcount);
- fprintf(where, "RECEIVE = %d\n", receivecount);
- fprintf(where, "SEND_ONCE = %d\n", sendoncecount);
- fprintf(where, "PORT_SET = %d\n", portsetcount);
- fprintf(where, "DEAD_NAME = %d\n", deadcount);
- fprintf(where, "DNREQUEST = %d\n", dncount);
-
- if (taskCount > 1)
- free(psettaskinfo);
-
- fprintf(where, "Finished.\n");
- return;
-}
-
-void
-do_stackshot(void)
-{
- /* yes, we really mean to exec without fork at this point in time */
- execl("/usr/libexec/stackshot", "/usr/libexec/stackshot", "-i", "-f", "./shutdown-stackshot.log", NULL);
- _exit(EXIT_FAILURE);
-}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/launchd-changes/attachments/20070215/ca3ee40d/attachment.html
More information about the launchd-changes
mailing list