| Index: gdb/darwin-nat.c
|
| diff --git a/gdb/darwin-nat.c b/gdb/darwin-nat.c
|
| index 26ee23a89ac6df9a443c6ce70ecae3e26ce4bb3e..f0f938d260ae0cf44187d9d0d0aa562fb67ea836 100644
|
| --- a/gdb/darwin-nat.c
|
| +++ b/gdb/darwin-nat.c
|
| @@ -1,5 +1,5 @@
|
| /* Darwin support for GDB, the GNU debugger.
|
| - Copyright (C) 2008-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 2008-2013 Free Software Foundation, Inc.
|
|
|
| Contributed by AdaCore.
|
|
|
| @@ -16,8 +16,7 @@
|
| GNU General Public License for more details.
|
|
|
| You should have received a copy of the GNU General Public License
|
| - along with this program. If not, see <http://www.gnu.org/licenses/>.
|
| -*/
|
| + along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
| #include "defs.h"
|
| #include "top.h"
|
| @@ -33,7 +32,7 @@
|
| #include "regcache.h"
|
| #include "event-top.h"
|
| #include "inf-loop.h"
|
| -#include "gdb_stat.h"
|
| +#include <sys/stat.h>
|
| #include "exceptions.h"
|
| #include "inf-child.h"
|
| #include "value.h"
|
| @@ -49,7 +48,6 @@
|
| #include <signal.h>
|
| #include <string.h>
|
| #include <ctype.h>
|
| -#include <sys/param.h>
|
| #include <sys/sysctl.h>
|
| #include <sys/proc.h>
|
| #include <libproc.h>
|
| @@ -66,6 +64,7 @@
|
| #include <mach/port.h>
|
|
|
| #include "darwin-nat.h"
|
| +#include "common/filestuff.h"
|
|
|
| /* Quick overview.
|
| Darwin kernel is Mach + BSD derived kernel. Note that they share the
|
| @@ -145,7 +144,7 @@ static struct inferior *darwin_inf_fake_stop;
|
| #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
|
|
|
| /* This controls output of inferior debugging. */
|
| -static int darwin_debug_flag = 0;
|
| +static unsigned int darwin_debug_flag = 0;
|
|
|
| /* Create a __TEXT __info_plist section in the executable so that gdb could
|
| be signed. This is required to get an authorization for task_for_pid.
|
| @@ -323,7 +322,7 @@ darwin_check_new_threads (struct inferior *inf)
|
| thread_t old_id = old ? old->gdb_port : THREAD_NULL;
|
|
|
| inferior_debug
|
| - (12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:%x old_id:%x\n"),
|
| + (12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:0x%x old_id:0x%x\n"),
|
| new_ix, new_nbr, old_ix, old_nbr, new_id, old_id);
|
|
|
| if (old_id == new_id)
|
| @@ -708,7 +707,7 @@ darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread,
|
| /* Set or reset single step. */
|
| if (step != thread->single_step)
|
| {
|
| - inferior_debug (4, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
|
| + inferior_debug (4, _("darwin_set_sstep (thread=0x%x, enable=%d)\n"),
|
| thread->gdb_port, step);
|
| darwin_set_sstep (thread->gdb_port, step);
|
| thread->single_step = step;
|
| @@ -878,8 +877,8 @@ darwin_decode_message (mach_msg_header_t *hdr,
|
| if (res < 0)
|
| {
|
| /* Should not happen... */
|
| - printf_unfiltered (_("darwin_wait: ill-formatted message (id=%x)\n"),
|
| - hdr->msgh_id);
|
| + printf_unfiltered
|
| + (_("darwin_wait: ill-formatted message (id=0x%x)\n"), hdr->msgh_id);
|
| /* FIXME: send a failure reply? */
|
| status->kind = TARGET_WAITKIND_SPURIOUS;
|
| return minus_one_ptid;
|
| @@ -891,23 +890,23 @@ darwin_decode_message (mach_msg_header_t *hdr,
|
| status->kind = TARGET_WAITKIND_STOPPED;
|
| thread->msg_state = DARWIN_MESSAGE;
|
|
|
| - inferior_debug (4, _("darwin_wait: thread=%x, got %s\n"),
|
| + inferior_debug (4, _("darwin_wait: thread=0x%x, got %s\n"),
|
| thread->gdb_port,
|
| unparse_exception_type (thread->event.ex_type));
|
|
|
| switch (thread->event.ex_type)
|
| {
|
| case EXC_BAD_ACCESS:
|
| - status->value.sig = TARGET_EXC_BAD_ACCESS;
|
| + status->value.sig = GDB_EXC_BAD_ACCESS;
|
| break;
|
| case EXC_BAD_INSTRUCTION:
|
| - status->value.sig = TARGET_EXC_BAD_INSTRUCTION;
|
| + status->value.sig = GDB_EXC_BAD_INSTRUCTION;
|
| break;
|
| case EXC_ARITHMETIC:
|
| - status->value.sig = TARGET_EXC_ARITHMETIC;
|
| + status->value.sig = GDB_EXC_ARITHMETIC;
|
| break;
|
| case EXC_EMULATION:
|
| - status->value.sig = TARGET_EXC_EMULATION;
|
| + status->value.sig = GDB_EXC_EMULATION;
|
| break;
|
| case EXC_SOFTWARE:
|
| if (thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
|
| @@ -929,11 +928,11 @@ darwin_decode_message (mach_msg_header_t *hdr,
|
| }
|
| }
|
| else
|
| - status->value.sig = TARGET_EXC_SOFTWARE;
|
| + status->value.sig = GDB_EXC_SOFTWARE;
|
| break;
|
| case EXC_BREAKPOINT:
|
| /* Many internal GDB routines expect breakpoints to be reported
|
| - as GDB_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
|
| + as GDB_SIGNAL_TRAP, and will report GDB_EXC_BREAKPOINT
|
| as a spurious signal. */
|
| status->value.sig = GDB_SIGNAL_TRAP;
|
| break;
|
| @@ -975,7 +974,7 @@ darwin_decode_message (mach_msg_header_t *hdr,
|
| status->value.sig = WTERMSIG (wstatus);
|
| }
|
|
|
| - inferior_debug (4, _("darwin_wait: pid=%d exit, status=%x\n"),
|
| + inferior_debug (4, _("darwin_wait: pid=%d exit, status=0x%x\n"),
|
| res, wstatus);
|
|
|
| /* Looks necessary on Leopard and harmless... */
|
| @@ -992,7 +991,7 @@ darwin_decode_message (mach_msg_header_t *hdr,
|
| }
|
| }
|
|
|
| - printf_unfiltered (_("Bad local-port: %x\n"), hdr->msgh_local_port);
|
| + printf_unfiltered (_("Bad local-port: 0x%x\n"), hdr->msgh_local_port);
|
| status->kind = TARGET_WAITKIND_SPURIOUS;
|
| return minus_one_ptid;
|
| }
|
| @@ -1015,7 +1014,7 @@ cancel_breakpoint (ptid_t ptid)
|
| pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
|
| if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
|
| {
|
| - inferior_debug (4, "cancel_breakpoint for thread %x\n",
|
| + inferior_debug (4, "cancel_breakpoint for thread 0x%x\n",
|
| ptid_get_tid (ptid));
|
|
|
| /* Back up the PC if necessary. */
|
| @@ -1076,7 +1075,7 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status)
|
|
|
| if (kret != MACH_MSG_SUCCESS)
|
| {
|
| - inferior_debug (5, _("mach_msg: ret=%x\n"), kret);
|
| + inferior_debug (5, _("mach_msg: ret=0x%x\n"), kret);
|
| status->kind = TARGET_WAITKIND_SPURIOUS;
|
| return minus_one_ptid;
|
| }
|
| @@ -1110,7 +1109,7 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status)
|
| if (kret != MACH_MSG_SUCCESS)
|
| {
|
| inferior_debug
|
| - (5, _("darwin_wait: mach_msg(pending) ret=%x\n"), kret);
|
| + (5, _("darwin_wait: mach_msg(pending) ret=0x%x\n"), kret);
|
| break;
|
| }
|
|
|
| @@ -1128,7 +1127,7 @@ darwin_wait (ptid_t ptid, struct target_waitstatus *status)
|
| }
|
| else
|
| inferior_debug
|
| - (3, _("darwin_wait: thread %x hit a non-gdb breakpoint\n"),
|
| + (3, _("darwin_wait: thread 0x%x hit a non-gdb breakpoint\n"),
|
| thread->gdb_port);
|
| }
|
| else
|
| @@ -1182,7 +1181,7 @@ darwin_mourn_inferior (struct target_ops *ops)
|
|
|
| kret = mach_port_move_member (gdb_task,
|
| inf->private->notify_port, MACH_PORT_NULL);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + MACH_CHECK_ERROR (kret);
|
|
|
| kret = mach_port_request_notification (gdb_task, inf->private->task,
|
| MACH_NOTIFY_DEAD_NAME, 0,
|
| @@ -1190,7 +1189,7 @@ darwin_mourn_inferior (struct target_ops *ops)
|
| MACH_MSG_TYPE_MAKE_SEND_ONCE,
|
| &prev);
|
| /* This can fail if the task is dead. */
|
| - inferior_debug (4, "task=%x, prev=%x, notify_port=%x\n",
|
| + inferior_debug (4, "task=0x%x, prev=0x%x, notify_port=0x%x\n",
|
| inf->private->task, prev, inf->private->notify_port);
|
|
|
| if (kret == KERN_SUCCESS)
|
| @@ -1371,40 +1370,76 @@ darwin_attach_pid (struct inferior *inf)
|
| /* Create a port to get exceptions. */
|
| kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
|
| &darwin_ex_port);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to create exception port, mach_port_allocate "
|
| + "returned: %d"),
|
| + kret);
|
|
|
| kret = mach_port_insert_right (gdb_task, darwin_ex_port, darwin_ex_port,
|
| MACH_MSG_TYPE_MAKE_SEND);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to create exception port, mach_port_insert_right "
|
| + "returned: %d"),
|
| + kret);
|
|
|
| /* Create a port set and put ex_port in it. */
|
| kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
|
| &darwin_port_set);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to create port set, mach_port_allocate "
|
| + "returned: %d"),
|
| + kret);
|
|
|
| kret = mach_port_move_member (gdb_task, darwin_ex_port, darwin_port_set);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to move exception port into new port set, "
|
| + "mach_port_move_member\n"
|
| + "returned: %d"),
|
| + kret);
|
| }
|
|
|
| /* Create a port to be notified when the child task terminates. */
|
| kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
|
| &inf->private->notify_port);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to create notification port, mach_port_allocate "
|
| + "returned: %d"),
|
| + kret);
|
|
|
| kret = mach_port_move_member (gdb_task,
|
| inf->private->notify_port, darwin_port_set);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to move notification port into new port set, "
|
| + "mach_port_move_member\n"
|
| + "returned: %d"),
|
| + kret);
|
|
|
| kret = mach_port_request_notification (gdb_task, inf->private->task,
|
| MACH_NOTIFY_DEAD_NAME, 0,
|
| inf->private->notify_port,
|
| MACH_MSG_TYPE_MAKE_SEND_ONCE,
|
| &prev_not);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| - gdb_assert (prev_not == MACH_PORT_NULL);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Termination notification request failed, "
|
| + "mach_port_request_notification\n"
|
| + "returned: %d"),
|
| + kret);
|
| + if (prev_not != MACH_PORT_NULL)
|
| + {
|
| + /* This is unexpected, as there should not be any previously
|
| + registered notification request. But this is not a fatal
|
| + issue, so just emit a warning. */
|
| + warning (_("\
|
| +A task termination request was registered before the debugger registered\n\
|
| +its own. This is unexpected, but should otherwise not have any actual\n\
|
| +impact on the debugging session."));
|
| + }
|
|
|
| kret = darwin_save_exception_ports (inf->private);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to save exception ports, task_get_exception_ports"
|
| + "returned: %d"),
|
| + kret);
|
|
|
| /* Set exception port. */
|
| if (enable_mach_exceptions)
|
| @@ -1413,7 +1448,10 @@ darwin_attach_pid (struct inferior *inf)
|
| mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
|
| kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port,
|
| EXCEPTION_DEFAULT, THREAD_STATE_NONE);
|
| - gdb_assert (kret == KERN_SUCCESS);
|
| + if (kret != KERN_SUCCESS)
|
| + error (_("Unable to set exception ports, task_set_exception_ports"
|
| + "returned: %d"),
|
| + kret);
|
|
|
| push_target (darwin_ops);
|
| }
|
| @@ -1453,7 +1491,8 @@ darwin_ptrace_me (void)
|
|
|
| /* Wait until gdb is ready. */
|
| res = read (ptrace_fds[0], &c, 1);
|
| - gdb_assert (res == 0);
|
| + if (res != 0)
|
| + error (_("unable to read from pipe, read returned: %d"), res);
|
| close (ptrace_fds[0]);
|
|
|
| /* Get rid of privileges. */
|
| @@ -1476,6 +1515,9 @@ darwin_pre_ptrace (void)
|
| ptrace_fds[1] = -1;
|
| error (_("unable to create a pipe: %s"), safe_strerror (errno));
|
| }
|
| +
|
| + mark_fd_no_cloexec (ptrace_fds[0]);
|
| + mark_fd_no_cloexec (ptrace_fds[1]);
|
| }
|
|
|
| static void
|
| @@ -1493,6 +1535,9 @@ darwin_ptrace_him (int pid)
|
| close (ptrace_fds[0]);
|
| close (ptrace_fds[1]);
|
|
|
| + unmark_fd_no_cloexec (ptrace_fds[0]);
|
| + unmark_fd_no_cloexec (ptrace_fds[1]);
|
| +
|
| darwin_init_thread_list (inf);
|
|
|
| startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
|
| @@ -1546,6 +1591,32 @@ darwin_create_inferior (struct target_ops *ops, char *exec_file,
|
| }
|
|
|
|
|
| +/* Set things up such that the next call to darwin_wait will immediately
|
| + return a fake stop event for inferior INF.
|
| +
|
| + This assumes that the inferior's thread list has been initialized,
|
| + as it will suspend the inferior's first thread. */
|
| +
|
| +static void
|
| +darwin_setup_fake_stop_event (struct inferior *inf)
|
| +{
|
| + darwin_thread_t *thread;
|
| + kern_return_t kret;
|
| +
|
| + gdb_assert (darwin_inf_fake_stop == NULL);
|
| + darwin_inf_fake_stop = inf;
|
| +
|
| + /* When detecting a fake pending stop event, darwin_wait returns
|
| + an event saying that the first thread is in a DARWIN_STOPPED
|
| + state. To make that accurate, we need to suspend that thread
|
| + as well. Otherwise, we'll try resuming it when resuming the
|
| + inferior, and get a warning because the thread's suspend count
|
| + is already zero, making the resume request useless. */
|
| + thread = VEC_index (darwin_thread_t, inf->private->threads, 0);
|
| + kret = thread_suspend (thread->gdb_port);
|
| + MACH_CHECK_ERROR (kret);
|
| +}
|
| +
|
| /* Attach to process PID, then initialize for debugging it
|
| and wait for the trace-trap that results from attaching. */
|
| static void
|
| @@ -1597,8 +1668,8 @@ darwin_attach (struct target_ops *ops, char *args, int from_tty)
|
|
|
| darwin_check_osabi (inf->private, ptid_get_tid (inferior_ptid));
|
|
|
| - gdb_assert (darwin_inf_fake_stop == NULL);
|
| - darwin_inf_fake_stop = inf;
|
| + darwin_setup_fake_stop_event (inf);
|
| +
|
| inf->private->no_ptrace = 1;
|
| }
|
|
|
| @@ -1610,7 +1681,7 @@ darwin_attach (struct target_ops *ops, char *args, int from_tty)
|
| previously attached. It *might* work if the program was
|
| started via fork. */
|
| static void
|
| -darwin_detach (struct target_ops *ops, char *args, int from_tty)
|
| +darwin_detach (struct target_ops *ops, const char *args, int from_tty)
|
| {
|
| pid_t pid = ptid_get_pid (inferior_ptid);
|
| struct inferior *inf = current_inferior ();
|
| @@ -1688,19 +1759,20 @@ darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
|
| Return 0 on failure; number of bytes read / writen otherwise. */
|
| static int
|
| darwin_read_write_inferior (task_t task, CORE_ADDR addr,
|
| - char *rdaddr, const char *wraddr, int length)
|
| + gdb_byte *rdaddr, const gdb_byte *wraddr,
|
| + int length)
|
| {
|
| kern_return_t kret;
|
| mach_vm_address_t offset = addr & (mach_page_size - 1);
|
| mach_vm_address_t low_address = (mach_vm_address_t) (addr - offset);
|
| mach_vm_size_t aligned_length = (mach_vm_size_t) PAGE_ROUND (offset + length);
|
| pointer_t copied;
|
| - int copy_count;
|
| + mach_msg_type_number_t copy_count;
|
| mach_vm_size_t remaining_length;
|
| mach_vm_address_t region_address;
|
| mach_vm_size_t region_length;
|
|
|
| - inferior_debug (8, _("darwin_read_write_inferior(task=%x, %s, len=%d)\n"),
|
| + inferior_debug (8, _("darwin_read_write_inferior(task=0x%x, %s, len=%d)\n"),
|
| task, core_addr_to_string (addr), length);
|
|
|
| /* Get memory from inferior with page aligned addresses. */
|
| @@ -1816,10 +1888,13 @@ out:
|
|
|
| /* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
|
| to RDADDR.
|
| - Return 0 on failure; number of bytes read / writen otherwise. */
|
| + Return 0 on failure; number of bytes read / written otherwise. */
|
|
|
| +#ifdef TASK_DYLD_INFO_COUNT
|
| +/* This is not available in Darwin 9. */
|
| static int
|
| -darwin_read_dyld_info (task_t task, CORE_ADDR addr, char *rdaddr, int length)
|
| +darwin_read_dyld_info (task_t task, CORE_ADDR addr, gdb_byte *rdaddr,
|
| + int length)
|
| {
|
| struct task_dyld_info task_dyld_info;
|
| mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
|
| @@ -1839,28 +1914,9 @@ darwin_read_dyld_info (task_t task, CORE_ADDR addr, char *rdaddr, int length)
|
| memcpy (rdaddr, (char *)&task_dyld_info + addr, length);
|
| return length;
|
| }
|
| +#endif
|
|
|
|
|
| -/* Return 0 on failure, number of bytes handled otherwise. TARGET
|
| - is ignored. */
|
| -static int
|
| -darwin_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
|
| - struct mem_attrib *attrib, struct target_ops *target)
|
| -{
|
| - struct inferior *inf = current_inferior ();
|
| - task_t task = inf->private->task;
|
| -
|
| - if (task == MACH_PORT_NULL)
|
| - return 0;
|
| -
|
| - inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
|
| - core_addr_to_string (memaddr), len, write ? 'w' : 'r');
|
| -
|
| - if (write)
|
| - return darwin_read_write_inferior (task, memaddr, NULL, myaddr, len);
|
| - else
|
| - return darwin_read_write_inferior (task, memaddr, myaddr, NULL, len);
|
| -}
|
|
|
| static LONGEST
|
| darwin_xfer_partial (struct target_ops *ops,
|
| @@ -1881,6 +1937,7 @@ darwin_xfer_partial (struct target_ops *ops,
|
| case TARGET_OBJECT_MEMORY:
|
| return darwin_read_write_inferior (inf->private->task, offset,
|
| readbuf, writebuf, len);
|
| +#ifdef TASK_DYLD_INFO_COUNT
|
| case TARGET_OBJECT_DARWIN_DYLD_INFO:
|
| if (writebuf != NULL || readbuf == NULL)
|
| {
|
| @@ -1888,6 +1945,7 @@ darwin_xfer_partial (struct target_ops *ops,
|
| return -1;
|
| }
|
| return darwin_read_dyld_info (inf->private->task, offset, readbuf, len);
|
| +#endif
|
| default:
|
| return -1;
|
| }
|
| @@ -1923,10 +1981,10 @@ darwin_pid_to_exec_file (int pid)
|
| char *path;
|
| int res;
|
|
|
| - path = xmalloc (MAXPATHLEN);
|
| + path = xmalloc (PATH_MAX);
|
| make_cleanup (xfree, path);
|
|
|
| - res = proc_pidinfo (pid, PROC_PIDPATHINFO, 0, path, MAXPATHLEN);
|
| + res = proc_pidinfo (pid, PROC_PIDPATHINFO, 0, path, PATH_MAX);
|
| if (res >= 0)
|
| return path;
|
| else
|
| @@ -2045,7 +2103,6 @@ _initialize_darwin_inferior (void)
|
| darwin_ops->to_pid_to_str = darwin_pid_to_str;
|
| darwin_ops->to_pid_to_exec_file = darwin_pid_to_exec_file;
|
| darwin_ops->to_load = NULL;
|
| - darwin_ops->deprecated_xfer_memory = darwin_xfer_memory;
|
| darwin_ops->to_xfer_partial = darwin_xfer_partial;
|
| darwin_ops->to_supports_multi_process = darwin_supports_multi_process;
|
| darwin_ops->to_get_ada_task_ptid = darwin_get_ada_task_ptid;
|
| @@ -2057,12 +2114,12 @@ _initialize_darwin_inferior (void)
|
| inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
|
| getpid ());
|
|
|
| - add_setshow_zinteger_cmd ("darwin", class_obscure,
|
| - &darwin_debug_flag, _("\
|
| + add_setshow_zuinteger_cmd ("darwin", class_obscure,
|
| + &darwin_debug_flag, _("\
|
| Set if printing inferior communication debugging statements."), _("\
|
| Show if printing inferior communication debugging statements."), NULL,
|
| - NULL, NULL,
|
| - &setdebuglist, &showdebuglist);
|
| + NULL, NULL,
|
| + &setdebuglist, &showdebuglist);
|
|
|
| add_setshow_boolean_cmd ("mach-exceptions", class_support,
|
| &enable_mach_exceptions, _("\
|
|
|