diff options
-rw-r--r-- | doc/mach.texi | 11 | ||||
-rw-r--r-- | i386/i386/trap.c | 5 | ||||
-rw-r--r-- | include/mach/gnumach.defs | 8 | ||||
-rw-r--r-- | kern/task.c | 16 | ||||
-rw-r--r-- | kern/task.h | 3 |
5 files changed, 40 insertions, 3 deletions
diff --git a/doc/mach.texi b/doc/mach.texi index 4abafe1a..fecd097b 100644 --- a/doc/mach.texi +++ b/doc/mach.texi @@ -5100,6 +5100,17 @@ printed by the kernel. The function returns @code{KERN_SUCCESS} if the call succeeded. @end deftypefun +@deftypefun kern_return_t task_set_essential (@w{task_t @var{target_task}}, @w{boolean_t @var{essential}}) + +The function @code{task_set_essential} sets whether @var{target_task} is +essential for the system, i.e. the system will completely crash and reboot if +that task crashes. This means that when the debugger is enabled, it should be +triggered on the crash, so as to get the opportunity to debug the issue instead +of just rebooting. + +The function returns @code{KERN_SUCCESS} if the call succeeded. +@end deftypefun + @node Task Execution @subsection Task Execution diff --git a/i386/i386/trap.c b/i386/i386/trap.c index eef9432f..6e446ab0 100644 --- a/i386/i386/trap.c +++ b/i386/i386/trap.c @@ -565,11 +565,12 @@ int user_trap(struct i386_saved_state *regs) } #if MACH_TTD - if (debug_all_traps_with_kttd && kttd_trap(type, regs->err, regs)) + if ((debug_all_traps_with_kttd || thread->task->essential) && + kttd_trap(type, regs->err, regs)) return 0; #endif /* MACH_TTD */ #if MACH_KDB - if (debug_all_traps_with_kdb && + if ((debug_all_traps_with_kdb || thread->task->essential) && kdb_trap(type, regs->err, regs)) return 0; #endif /* MACH_KDB */ diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs index 531b5d4d..05101a48 100644 --- a/include/mach/gnumach.defs +++ b/include/mach/gnumach.defs @@ -189,3 +189,11 @@ routine vm_allocate_contiguous( pmin : rpc_phys_addr_t; pmax : rpc_phys_addr_t; palign : rpc_phys_addr_t); + +/* + * Set whether TASK is an essential task, i.e. the whole system will crash + * if this task crashes. + */ +simpleroutine task_set_essential( + task : task_t; + essential : boolean_t); diff --git a/kern/task.c b/kern/task.c index e91c192b..e9158c73 100644 --- a/kern/task.c +++ b/kern/task.c @@ -178,6 +178,7 @@ task_create_kernel( new_task->may_assign = TRUE; new_task->assign_active = FALSE; + new_task->essential = FALSE; #if MACH_PCSAMPLE new_task->pc_sample.buffer = 0; @@ -1157,6 +1158,21 @@ task_set_name( } /* + * task_set_essential + * + * Set whether TASK is an essential task, i.e. the whole system will crash + * if this task crashes. + */ +kern_return_t +task_set_essential( + task_t task, + boolean_t essential) +{ + task->essential = !!essential; + return KERN_SUCCESS; +} + +/* * task_collect_scan: * * Attempt to free resources owned by tasks. diff --git a/kern/task.h b/kern/task.h index 52eb8324..6251317c 100644 --- a/kern/task.h +++ b/kern/task.h @@ -64,7 +64,8 @@ struct task { /* Flags */ unsigned int active:1, /* Task has not been terminated */ /* boolean_t */ may_assign:1, /* can assigned pset be changed? */ - assign_active:1; /* waiting for may_assign */ + assign_active:1, /* waiting for may_assign */ + essential:1; /* Is this task essential for the system? */ /* Miscellaneous */ vm_map_t map; /* Address space description */ |