29 #include <sys/ptrace.h>
32 #include <mach_error.h>
33 #include <mach/exception.h>
34 #include <mach/message.h>
35 #include <mach/notify.h>
36 #include <mach/vm_attributes.h>
39 #include <hurd/interrupt.h>
41 #include <hurd/msg_request.h>
42 #include <hurd/process.h>
46 #include <hurd/process_request.h>
47 #include <hurd/signal.h>
48 #include <hurd/sigpreempt.h>
66 #include "exc_request_S.h"
68 #include "process_reply_S.h"
69 #include "msg_reply_S.h"
70 #include "exc_request_U.h"
96 struct proc *run_thread,
104 void inf_signal (
struct inf *inf,
enum gdb_signal sig);
107 #define inf_debug(_inf, msg, args...) \
108 do { struct inf *__inf = (_inf); \
109 debug ("{inf %d %s}: " msg, __inf->pid, \
110 host_address_to_string (__inf) , ##args); } while (0)
126 #define INF_MSGPORT_RPC(inf, rpc_expr) \
127 HURD_MSGPORT_RPC (proc_getmsgport (proc_server, inf->pid, &msgport), \
128 (refport = inf->task->port, 0), 0, \
129 msgport ? (rpc_expr) : EIEIO)
134 #define INF_RESUME_MSGPORT_RPC(inf, rpc_expr) \
135 (inf_set_threads_resume_sc_for_signal_thread (inf) \
138 __e = INF_MSGPORT_RPC (inf, rpc_expr); \
255 int delta = proc->
sc - proc->
cur_sc;
264 proc_debug (proc,
"storing back changed thread state");
273 while (delta-- > 0 && !err)
276 err = task_suspend (proc->
port);
278 err = thread_suspend (proc->
port);
283 while (delta++ < 0 && !err)
286 err = task_resume (proc->
port);
288 err = thread_resume (proc->
port);
295 running = !err && proc->
sc == 0;
297 proc_debug (proc,
"is %s", err ?
"dead" : running ?
"running" :
"suspended");
323 struct inf *inf = proc->
inf;
326 if (running && force)
340 thread_abort (proc->
port);
356 int was_aborted = proc->
aborted;
359 will_modify ?
" (with intention to modify)" :
"");
363 if (!was_aborted && proc->
aborted)
372 (thread_state_t) &proc->
state, &state_size);
382 return (thread_state_t) &proc->
state;
394 return task_get_exception_port (proc->
port, port);
396 return thread_get_exception_port (proc->
port, port);
403 proc_debug (proc,
"setting exception port: %lu", port);
405 return task_set_exception_port (proc->
port, port);
407 return thread_set_exception_port (proc->
port, port);
414 mach_port_t exc_port;
421 mach_port_deallocate (mach_task_self (), proc->
exc_port);
443 proc_debug (proc,
"inserting exception port: %lu", exc_port);
445 if (cur_exc_port != exc_port)
449 if (err || cur_exc_port == proc->
exc_port)
454 mach_port_deallocate (mach_task_self (), cur_exc_port);
469 warning (
_(
"Error setting exception port for %s: %s"),
486 proc_debug (proc,
"restoring real exception port");
499 warning (
_(
"Error setting exception port for %s: %s"),
515 proc_debug (proc,
"tracing %s", set ?
"on" :
"off");
521 if (proc->
exc_port == MACH_PORT_NULL)
541 mach_port_t prev_port = MACH_PORT_NULL;
570 mach_port_request_notification (mach_task_self (), port,
571 MACH_NOTIFY_DEAD_NAME, 1,
573 MACH_MSG_TYPE_MAKE_SEND_ONCE,
576 warning (
_(
"Couldn't request notification for port %lu: %s"),
581 if (prev_port != MACH_PORT_NULL)
582 mach_port_deallocate (mach_task_self (), prev_port);
604 struct inf *inf = proc->
inf;
617 if (proc->
port != MACH_PORT_NULL)
619 if (proc->
exc_port != MACH_PORT_NULL)
628 mach_port_deallocate (mach_task_self (), proc->
port);
639 struct inf *inf =
xmalloc (
sizeof (
struct inf));
684 mach_port_deallocate (mach_task_self (), inf->
wait.
exc.
reply);
708 mach_port_destroy (mach_task_self (), inf->
event_port);
718 inf_debug (inf,
"startup: pid = %d", pid);
723 err = mach_port_allocate (mach_task_self (),
729 mach_port_insert_right (mach_task_self (), inf->
event_port,
745 task_port = MACH_PORT_NULL;
748 error_t err = proc_pid2task (proc_server, pid, &task_port);
751 error (
_(
"Error getting task for pid %d: %s"),
755 inf_debug (inf,
"setting task: %lu", task_port);
758 task_suspend (task_port);
760 if (task && task->
port != task_port)
767 if (task_port != MACH_PORT_NULL)
793 mach_msg_type_number_t noise_len = 0;
795 mach_msg_type_number_t pi_len = 0;
798 proc_getprocinfo (proc_server, inf->
pid, &info_flags,
799 (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
803 inf->
stopped = !!(pi->state & PI_STOPPED);
804 inf->
nomsg = !!(pi->state & PI_NOMSG);
806 inf->
traced = !!(pi->state & PI_TRACED);
807 vm_deallocate (mach_task_self (), (vm_address_t) pi,
808 pi_len *
sizeof (*(procinfo_t) 0));
810 vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
820 mach_msg_type_number_t noise_len = 0;
822 mach_msg_type_number_t pi_len = 0;
823 int info_flags = PI_FETCH_TASKINFO;
824 int suspend_count = -1;
828 err = proc_getprocinfo (proc_server, inf->
pid, &info_flags,
829 (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
836 if (inf->
task->
cur_sc < pi->taskinfo.suspend_count && suspend_count == -1)
842 suspend_count = pi->taskinfo.suspend_count;
846 suspend_count = pi->taskinfo.suspend_count;
848 vm_deallocate (mach_task_self (), (vm_address_t) pi,
849 pi_len *
sizeof (*(procinfo_t) 0));
851 vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
858 abort = !
query (
_(
"Pid %d has an additional task suspend count of %d;"
859 " clear it? "), inf->
pid,
864 error (
_(
"Additional task suspend count left untouched."));
883 sigset_t mask = on ? ~(sigset_t) 0 : 0;
886 INIT_TRACEMASK, mask));
891 warning (
_(
"Can't modify tracing state for pid %d: %s"),
892 inf->
pid,
"No signal thread");
896 warning (
_(
"Can't modify tracing state for pid %d: %s"),
918 inf_debug (inf,
"updating suspend counts");
923 int task_running = (task->
sc == 0), thread_running = 0;
935 for (thread = inf->
threads; thread; thread = thread->
next)
944 (thread_running && task_running) ?
"" :
"not ");
946 inf->
running = thread_running && task_running;
967 if (thread->
tid == tid)
970 thread = thread->
next;
981 if (thread->
port == port)
984 thread = thread->
next;
995 for (thread = inf->
threads; thread; thread = thread->
next)
1004 thread_array_t threads;
1005 mach_msg_type_number_t num_threads, i;
1016 error_t err = task_threads (task->
port, &threads, &num_threads);
1035 mach_msg_type_number_t search_start = 0;
1037 struct proc *matched[num_threads + 1];
1039 struct proc *last = 0;
1043 memset (matched, 0,
sizeof (matched));
1047 mach_msg_type_number_t left;
1049 for (i = search_start, left = num_threads; left; i++, left--)
1051 if (i >= num_threads)
1053 if (thread->
port == threads[i])
1056 matched[i] = thread;
1058 thread = thread->
next;
1067 thread->
port = MACH_PORT_NULL;
1070 last->
next = thread;
1076 for (i = 0; i < num_threads; i++)
1080 mach_port_deallocate (mach_task_self (), threads[i]);
1086 thread =
make_proc (inf, threads[i], next_thread_id++);
1088 last->
next = thread;
1092 proc_debug (thread,
"new thread: %lu", threads[i]);
1110 vm_deallocate (mach_task_self (),
1111 (vm_address_t) threads, (num_threads *
sizeof (
thread_t)));
1132 struct proc *run_thread,
int run_others)
1134 struct proc *thread;
1137 for (thread = inf->
threads; thread; thread = thread->
next)
1138 if (thread == run_thread)
1140 else if (run_others)
1152 struct proc *thread;
1156 for (thread = inf->
threads; thread; thread = thread->
next)
1177 struct proc *thread;
1181 for (thread = inf->
threads; thread; thread = thread->
next)
1202 inf_debug (inf,
"clearing step thread");
1254 struct proc *thread;
1270 for (thread = inf->
threads; thread; thread = thread->
next)
1300 struct proc *thread;
1302 inf_debug (inf,
"stealing exception ports");
1307 for (thread = inf->
threads; thread; thread = thread->
next)
1315 struct proc *thread;
1317 inf_debug (inf,
"restoring exception ports");
1322 for (thread = inf->
threads; thread; thread = thread->
next)
1336 #define NAME gdb_signal_to_name (sig)
1338 if (host_sig >= _NSIG)
1356 inf_debug (inf,
"passing through exception:"
1357 " task = %lu, thread = %lu, exc = %d"
1358 ", code = %d, subcode = %d",
1362 exception_raise_request (e->
handler,
1363 e->
reply, MACH_MSG_TYPE_MOVE_SEND_ONCE,
1368 error (
_(
"Can't forward spontaneous exception (%s)."),
NAME);
1379 msg_sig_post_untraced_request (msgport,
1381 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1398 inf_debug (inf,
"sending %s to unstopped process"
1399 " (so resuming signal thread)",
NAME);
1402 msg_sig_post_untraced (msgport, host_sig,
1408 warning (
_(
"Can't deliver signal %s: No signal thread."),
NAME);
1422 error_t err = proc_pid2proc (proc_server, inf->
pid, &proc);
1428 err = proc_mark_cont (proc);
1431 struct proc *thread;
1433 for (thread = inf->
threads; thread; thread = thread->
next)
1434 thread_resume (thread->
port);
1446 struct inf *gnu_current_inf = 0;
1459 mach_msg_header_t hdr;
1460 mach_msg_type_t
type;
1464 struct proc *thread;
1467 extern int exc_server (mach_msg_header_t *, mach_msg_header_t *);
1468 extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *);
1469 extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
1470 extern int process_reply_server (mach_msg_header_t *, mach_msg_header_t *);
1481 error (
_(
"There are no threads; try again later."));
1489 if (proc_wait_pid != inf->
pid && !inf->
no_wait)
1492 inf_debug (inf,
"requesting wait on pid %d", inf->
pid);
1498 inf_debug (inf,
"cancelling previous wait on pid %d", proc_wait_pid);
1499 interrupt_operation (proc_server, 0);
1508 inf_debug (inf,
"waits pending: %d", proc_waits_pending);
1509 proc_wait_pid = inf->
pid;
1515 proc_waits_pending = 1;
1524 inf_debug (inf,
"waiting for an event...");
1525 err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT,
1527 MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
1538 if (err == EMACH_RCV_INTERRUPTED)
1546 mach_msg_header_t hdr;
1547 mach_msg_type_t err_type;
1553 inf_debug (inf,
"event: msgid = %d", msg.hdr.msgh_id);
1556 if (!notify_server (&msg.hdr, &reply.hdr)
1557 && !exc_server (&msg.hdr, &reply.hdr)
1558 && !process_reply_server (&msg.hdr, &reply.hdr)
1559 && !msg_reply_server (&msg.hdr, &reply.hdr))
1561 error (
_(
"Got a strange event, msg id = %d."), msg.hdr.msgh_id);
1564 error (
_(
"Handling event, msgid = %d: %s"),
1580 inf_debug (inf,
"pending_execs, ignoring minor event");
1587 inf_debug (inf,
"one pending exec completed");
1602 inf_debug (inf,
"suppressing return, rewaiting...");
1608 memcpy (status, &inf->
wait.
status, sizeof (*status));
1618 if (!thread || thread->
port == MACH_PORT_NULL)
1640 inf_debug (inf,
"returning ptid = %s, status = %s (%d)",
1657 thread_t thread_port, task_t task_port,
1658 int exception,
int code,
int subcode)
1664 "thread = %lu, task = %lu, exc = %d, code = %d, subcode = %d",
1665 thread_port, task_port, exception, code, subcode);
1677 mach_port_deallocate (mach_task_self (), thread_port);
1678 mach_port_deallocate (mach_task_self (), task_port);
1689 if (exception == EXC_BREAKPOINT)
1693 mach_port_deallocate (mach_task_self (), reply_port);
1700 inf_debug (waiting_inf,
"Handler is thread exception port <%lu>",
1706 inf_debug (waiting_inf,
"Handler is task exception port <%lu>",
1713 mach_port_mod_refs (mach_task_self (),
1733 mach_port_deallocate (mach_task_self (), reply_port);
1745 warning (
_(
"Pid %d died with unknown exit status, using SIGKILL."),
1757 inf_debug (waiting_inf,
"port = %lu", dead_port);
1763 if (proc_wait_pid == inf->
pid)
1779 thread->
port = MACH_PORT_NULL;
1787 mach_port_deallocate (mach_task_self (), dead_port);
1794 #define ILL_RPC(fun, ...) \
1795 extern kern_return_t fun (__VA_ARGS__); \
1796 kern_return_t fun (__VA_ARGS__) \
1798 warning (_("illegal rpc: %s"), #fun); \
1802 ILL_RPC (do_mach_notify_no_senders,
1803 mach_port_t
notify, mach_port_mscount_t count)
1804 ILL_RPC (do_mach_notify_port_deleted,
1806 ILL_RPC (do_mach_notify_msg_accepted,
1808 ILL_RPC (do_mach_notify_port_destroyed,
1810 ILL_RPC (do_mach_notify_send_once,
1816 S_proc_wait_reply (mach_port_t reply, error_t err,
1817 int status,
int sigcode, rusage_t rusage, pid_t pid)
1821 inf_debug (inf,
"err = %s, pid = %d, status = 0x%x, sigcode = %d",
1832 if (--proc_waits_pending == 0)
1837 inf_debug (inf,
"waits pending now: %d", proc_waits_pending);
1843 warning (
_(
"Can't wait for pid %d: %s"),
1858 inf_debug (inf,
"process has stopped itself");
1868 ILL_RPC (S_proc_setmsgport_reply,
1870 mach_port_t oldmsgport)
1871 ILL_RPC (S_proc_getmsgport_reply,
1873 mach_port_t msgports)
1874 ILL_RPC (S_proc_pid2task_reply,
1876 ILL_RPC (S_proc_task2pid_reply,
1878 ILL_RPC (S_proc_task2proc_reply,
1880 ILL_RPC (S_proc_proc2task_reply,
1882 ILL_RPC (S_proc_pid2proc_reply,
1884 ILL_RPC (S_proc_getprocinfo_reply,
1887 data_t
threadwaits, mach_msg_type_number_t threadwaitsCnt)
1888 ILL_RPC (S_proc_getprocargs_reply,
1890 data_t procargs, mach_msg_type_number_t procargsCnt)
1891 ILL_RPC (S_proc_getprocenv_reply,
1893 data_t
procenv, mach_msg_type_number_t procenvCnt)
1894 ILL_RPC (S_proc_getloginid_reply,
1896 ILL_RPC (S_proc_getloginpids_reply,
1898 pidarray_t
pids, mach_msg_type_number_t pidsCnt)
1899 ILL_RPC (S_proc_getlogin_reply,
1903 ILL_RPC (S_proc_getsessionpgids_reply,
1905 pidarray_t pgidset, mach_msg_type_number_t pgidsetCnt)
1906 ILL_RPC (S_proc_getsessionpids_reply,
1908 pidarray_t
pidset, mach_msg_type_number_t pidsetCnt)
1909 ILL_RPC (S_proc_getsidport_reply,
1911 mach_port_t sessport)
1912 ILL_RPC (S_proc_getpgrp_reply,
1914 ILL_RPC (S_proc_getpgrppids_reply,
1916 pidarray_t
pidset, mach_msg_type_number_t pidsetCnt)
1917 ILL_RPC (S_proc_get_tty_reply,
1919 ILL_RPC (S_proc_getnports_reply,
1921 mach_msg_type_number_t nports)
1922 ILL_RPC (S_proc_is_important_reply,
1924 boolean_t essential)
1925 ILL_RPC (S_proc_get_code_reply,
1927 vm_address_t start_code, vm_address_t end_code)
1932 S_msg_sig_post_untraced_reply (mach_port_t reply, error_t err)
1961 ILL_RPC (S_msg_sig_post_reply,
1962 mach_port_t reply, error_t err)
1965 static mach_port_msgcount_t
1966 port_msgs_queued (mach_port_t port)
1968 struct mach_port_status status;
1970 mach_port_get_receive_status (mach_task_self (), port, &status);
1975 return status.mps_msgcount;
1999 struct proc *step_thread = 0;
2003 inf_debug (inf,
"ptid = %s, step = %d, sig = %d",
2008 if (sig != GDB_SIGNAL_0 || inf->
stopped)
2010 if (sig == GDB_SIGNAL_0 && inf->
nomsg)
2020 warning (
_(
"Aborting %s with unforwarded exception %s."),
2038 inf_debug (inf,
"running all threads; tid = %d",
2049 error (
_(
"Can't run single thread id %s: no such thread!"),
2059 warning (
_(
"Can't step thread id %s: no such thread."),
2075 struct proc *task = gnu_current_inf->
task;
2080 task_terminate (task->
port);
2102 if (gnu_current_inf->
task && gnu_current_inf->
threads)
2113 if (!gnu_current_inf)
2120 char *exec_file,
char *allargs,
char **env,
2126 void trace_me (
void)
2130 if (
ptrace (PTRACE_TRACEME) != 0)
2131 error (
_(
"ptrace (PTRACE_TRACEME) failed!"));
2137 NULL, NULL, NULL, NULL);
2140 inf_debug (inf,
"attaching to child: %d", pid);
2186 if (pid == getpid ())
2187 error (
_(
"I refuse to debug myself!"));
2202 inf_debug (inf,
"attaching to pid: %d", pid);
2228 renumber_threads (0);
2251 exec_file, gnu_current_inf->
pid);
2257 pid = gnu_current_inf->
pid;
2277 error (
_(
"to_stop target function not implemented"));
2296 vm_address_t low_address = (vm_address_t) trunc_page (addr);
2297 vm_size_t aligned_length =
2298 (vm_size_t) round_page (addr + length) - low_address;
2300 mach_msg_type_number_t copy_count;
2303 err = vm_read (task, low_address, aligned_length, &copied, ©_count);
2307 err = hurd_safe_copyin (myaddr, (
void *) (addr - low_address + copied),
2315 err = vm_deallocate (mach_task_self (), copied, copy_count);
2317 warning (
_(
"gnu_read_inferior vm_deallocate failed: %s"),
2323 #define CHK_GOTO_OUT(str,ret) \
2324 do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0)
2340 const gdb_byte *myaddr,
int length)
2343 vm_address_t low_address = (vm_address_t) trunc_page (addr);
2344 vm_size_t aligned_length =
2345 (vm_size_t) round_page (addr + length) - low_address;
2347 mach_msg_type_number_t copy_count;
2350 char *errstr =
"Bug in gnu_write_inferior";
2356 err = vm_read (task,
2361 CHK_GOTO_OUT (
"gnu_write_inferior vm_read failed", err);
2365 err = hurd_safe_copyout ((
void *) (addr - low_address + copied),
2374 vm_size_t remaining_length = aligned_length;
2375 vm_address_t region_address = low_address;
2379 while (region_address < low_address + aligned_length)
2382 vm_prot_t max_protection;
2383 vm_inherit_t inheritance;
2385 mach_port_t object_name;
2387 vm_size_t region_length = remaining_length;
2388 vm_address_t old_address = region_address;
2390 err = vm_region (task,
2402 if (old_address != region_address)
2404 warning (
_(
"No memory at 0x%lx. Nothing written"),
2411 if (!(max_protection & VM_PROT_WRITE))
2413 warning (
_(
"Memory at address 0x%lx is unwritable. "
2427 region_element->
start = region_address;
2428 region_element->
length = region_length;
2431 region_element->
next = region_head;
2432 region_head = region_element;
2434 region_address += region_length;
2435 remaining_length = remaining_length - region_length;
2442 for (scan = region_head;
scan; scan = scan->
next)
2446 err = vm_protect (task,
2455 err = vm_write (task,
2462 for (scan = region_head;
scan; scan = scan->
next)
2466 err = vm_protect (task,
2481 (void) vm_deallocate (mach_task_self (),
2486 if (err != KERN_SUCCESS)
2488 warning (
_(
"%s: %s"), errstr, mach_error_string (err));
2504 task_t task = (gnu_current_inf
2505 ? (gnu_current_inf->
task
2510 if (task == MACH_PORT_NULL)
2513 if (writebuf != NULL)
2515 inf_debug (gnu_current_inf,
"writing %s[%s] <-- %s",
2522 inf_debug (gnu_current_inf,
"reading %s[%s] --> %s",
2541 const char *annex,
gdb_byte *readbuf,
2561 vm_address_t region_address, last_region_address, last_region_end;
2562 vm_prot_t last_protection;
2564 if (gnu_current_inf == 0 || gnu_current_inf->
task == 0)
2566 task = gnu_current_inf->
task->
port;
2567 if (task == MACH_PORT_NULL)
2570 region_address = last_region_address = last_region_end =
VM_MIN_ADDRESS;
2571 last_protection = VM_PROT_NONE;
2572 while (region_address < VM_MAX_ADDRESS)
2575 vm_prot_t max_protection;
2576 vm_inherit_t inheritance;
2578 mach_port_t object_name;
2580 vm_size_t region_length = VM_MAX_ADDRESS - region_address;
2581 vm_address_t old_address = region_address;
2583 err = vm_region (task,
2592 if (err == KERN_NO_SPACE)
2594 if (err != KERN_SUCCESS)
2596 warning (
_(
"vm_region failed: %s"), mach_error_string (err));
2600 if (protection == last_protection && region_address == last_region_end)
2603 last_region_end = region_address += region_length;
2608 if (last_protection != VM_PROT_NONE)
2609 (*func) (last_region_address,
2610 last_region_end - last_region_address,
2611 last_protection & VM_PROT_READ,
2612 last_protection & VM_PROT_WRITE,
2613 last_protection & VM_PROT_EXECUTE,
2616 last_region_address = region_address;
2617 last_region_end = region_address += region_length;
2623 if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
2624 (*func) (last_region_address, last_region_end - last_region_address,
2625 last_protection & VM_PROT_READ,
2626 last_protection & VM_PROT_WRITE,
2627 last_protection & VM_PROT_EXECUTE,
2639 static char tid_str[80];
2644 xsnprintf (tid_str,
sizeof (tid_str),
"Thread %d.%d",
2660 static char tid_str[80];
2662 xsnprintf (tid_str,
sizeof (tid_str),
"bogus thread id %d", tid);
2714 "name of a thread property, or \"default\".\n");
2721 "name of a thread property, or \"default\".\n");
2728 "by the name of a thread property.\n");
2735 "by the name of a thread property.\n");
2744 int val = strtoul (args, &arg_end, 10);
2746 if (*args && *arg_end ==
'\0')
2749 error (
_(
"Illegal argument for \"%s\" command, should be an integer."),
2756 if (!args || strcmp (args, t_val) == 0)
2758 else if (strcmp (args, f_val) == 0)
2761 error (
_(
"Illegal argument for \"%s\" command, "
2762 "should be \"%s\" or \"%s\"."),
2763 cmd_prefix, t_val, f_val);
2766 #define parse_bool_arg(args, cmd_prefix) \
2767 _parse_bool_arg (args, "on", "off", cmd_prefix)
2773 error (
_(
"Garbage after \"%s\" command: `%s'"), cmd_prefix, args);
2777 static struct proc *
2784 error (
_(
"No current thread."));
2795 error (
_(
"No current process."));
2808 if (old_sc == 0 && inf->
pause_sc != 0)
2822 ? (inf->
pause_sc == 0 ?
"isn't" :
"is")
2823 : (inf->
pause_sc == 0 ?
"won't be" :
"will be"));
2830 "set task detach-suspend-count");
2836 check_empty (args,
"show task detach-suspend-count");
2838 "suspend count of %d when detaching.\n",
2860 sc ?
"are" :
"aren't",
2861 !sc && inf->
pause_sc ?
" (but the task is)" :
"");
2887 parse_int_arg (args,
"set thread default detach-suspend-count");
2893 check_empty (args,
"show thread default detach-suspend-count");
2906 mach_msg_type_name_t port_type;
2908 if (!proc || !proc->
inf->
task)
2909 error (
_(
"No inferior task."));
2911 err = mach_port_extract_right (proc->
inf->
task->
port,
2912 name, MACH_MSG_TYPE_COPY_SEND,
2915 error (
_(
"Couldn't extract send right %lu from inferior: %s"),
2931 error (
_(
"Can't set exception port for %s: %s"),
2942 error (
_(
"No argument to \"set task exception-port\" command."));
2959 inf->
stopped ?
"is" :
"isn't");
2967 if (!args || (!isdigit (*args) && strcmp (args,
"none") != 0))
2968 error (
_(
"Illegal argument to \"set signal-thread\" command.\n"
2969 "Should be an integer thread ID, or `none'."));
2971 if (strcmp (args,
"none") == 0)
2978 error (
_(
"Thread ID %s not known. "
2979 "Use the \"info threads\" command to\n"
2980 "see the IDs of currently known threads."), args);
3019 ? (inf->
traced ?
"are" :
"aren't")
3052 " of a task property.\n");
3087 char *inv_args =
parse_bool_arg (args,
"set noninvasive") ?
"off" :
"on";
3109 print_port_info (right, 0, inf->
task->
port, PORTINFO_DETAILS,
3120 print_task_ports_info (inf->
task->
port, only, PORTINFO_DETAILS,
3164 Set whether the new threads are suspended while gdb has control.\n\
3165 This property normally has no effect because the whole task is\n\
3166 suspended, however, that may be disabled with \"set task pause off\".\n\
3167 The default value is \"off\"."),
3168 &set_thread_default_cmd_list);
3170 Show whether new threads are suspended while gdb has control."),
3171 &show_thread_default_cmd_list);
3174 Set whether new threads are allowed to run (once gdb has noticed them)."),
3175 &set_thread_default_cmd_list);
3177 Show whether new threads are allowed to run (once gdb has noticed them)."),
3178 &show_thread_default_cmd_list);
3181 _(
"Set the default detach-suspend-count value for new threads."),
3182 &set_thread_default_cmd_list);
3184 _(
"Show the default detach-suspend-count value for new threads."),
3185 &show_thread_default_cmd_list);
3188 Set whether the inferior process's signals will be intercepted.\n\
3189 Mach exceptions (such as breakpoint traps) are not affected."),
3193 Show whether the inferior process's signals will be intercepted."),
3198 Set the thread that gdb thinks is the libc signal thread.\n\
3199 This thread is run when delivering a signal to a non-stopped process."),
3203 Set the thread that gdb thinks is the libc signal thread."),
3208 Set whether gdb thinks the inferior process is stopped as with SIGSTOP.\n\
3209 Stopped process will be continued by sending them a signal."),
3212 Show whether gdb thinks the inferior process is stopped as with SIGSTOP."),
3216 Set whether exceptions in the inferior process will be trapped.\n\
3217 When exceptions are turned off, neither breakpoints nor single-stepping\n\
3223 Show whether exceptions in the inferior process will be trapped."),
3227 _(
"Command prefix for setting task attributes."),
3228 &set_task_cmd_list,
"set task ", 0, &
setlist);
3230 _(
"Command prefix for showing task attributes."),
3231 &show_task_cmd_list,
"show task ", 0, &
showlist);
3234 Set whether the task is suspended while gdb has control.\n\
3235 A value of \"on\" takes effect immediately, otherwise nothing happens\n\
3236 until the next time the program is continued.\n\
3237 When setting this to \"off\", \"set thread default pause on\" can be\n\
3238 used to pause individual threads by default instead."),
3239 &set_task_cmd_list);
3241 _(
"Show whether the task is suspended while gdb has control."),
3242 &show_task_cmd_list);
3245 _(
"Set the suspend count will leave on the thread when detaching."),
3246 &set_task_cmd_list);
3248 _(
"Show the suspend count will leave "
3249 "on the thread when detaching."),
3250 &show_task_cmd_list);
3253 Set the task exception port to which we forward exceptions.\n\
3254 The argument should be the value of the send right in the task."),
3255 &set_task_cmd_list);
3258 &set_task_cmd_list);
3263 Set task options so that we interfere as little as possible.\n\
3264 This is the same as setting `task pause', `exceptions', and\n\
3265 `signals' to the opposite value."),
3270 _(
"Show information about the task's send rights"),
3273 _(
"Show information about the task's receive rights"),
3276 _(
"Show information about the task's port rights"),
3279 _(
"Show information about the task's port sets"),
3282 _(
"Show information about the task's dead names"),
3312 sc ?
"is" :
"isn't",
3313 !sc && thread->
inf->
pause_sc ?
" (but the task is)" :
"");
3332 thread->
run_sc == 0 ?
"is" :
"isn't");
3339 "set thread detach-suspend-count");
3347 check_empty (args,
"show thread detach-suspend-count");
3349 " of %d when detaching.\n",
3360 error (
_(
"No argument to \"set thread exception-port\" command."));
3383 thread_basic_info_data_t _info;
3384 thread_basic_info_t info = &_info;
3385 mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT;
3387 thread_info (thread->
port, THREAD_BASIC_INFO, (
int *) &info, &info_len);
3390 thread->
sc = info->suspend_count;
3394 vm_deallocate (mach_task_self (), (vm_address_t) info,
3395 info_len *
sizeof (
int));
3403 _(
"Command prefix for setting thread properties."),
3404 &set_thread_cmd_list,
"set thread ", 0, &
setlist);
3406 _(
"Command prefix for setting default thread properties."),
3407 &set_thread_default_cmd_list,
"set thread default ", 0,
3408 &set_thread_cmd_list);
3410 _(
"Command prefix for showing thread properties."),
3411 &show_thread_cmd_list,
"show thread ", 0, &
showlist);
3413 _(
"Command prefix for showing default thread properties."),
3414 &show_thread_default_cmd_list,
"show thread default ", 0,
3415 &show_thread_cmd_list);
3418 Set whether the current thread is suspended while gdb has control.\n\
3419 A value of \"on\" takes effect immediately, otherwise nothing happens\n\
3420 until the next time the program is continued. This property normally\n\
3421 has no effect because the whole task is suspended, however, that may\n\
3422 be disabled with \"set task pause off\".\n\
3423 The default value is \"off\"."),
3424 &set_thread_cmd_list);
3426 Show whether the current thread is suspended while gdb has control."),
3427 &show_thread_cmd_list);
3430 _(
"Set whether the current thread is allowed to run."),
3431 &set_thread_cmd_list);
3433 _(
"Show whether the current thread is allowed to run."),
3434 &show_thread_cmd_list);
3437 Set the suspend count will leave on the thread when detaching.\n\
3438 Note that this is relative to suspend count when gdb noticed the thread;\n\
3439 use the `thread takeover-suspend-count' to force it to an absolute value."),
3440 &set_thread_cmd_list);
3442 Show the suspend count will leave on the thread when detaching.\n\
3443 Note that this is relative to suspend count when gdb noticed the thread;\n\
3444 use the `thread takeover-suspend-count' to force it to an absolute value."),
3445 &show_thread_cmd_list);
3448 Set the thread exception port to which we forward exceptions.\n\
3449 This overrides the task exception port.\n\
3450 The argument should be the value of the send right in the task."),
3451 &set_thread_cmd_list);
3454 &set_thread_cmd_list);
3457 Force the threads absolute suspend-count to be gdb's.\n\
3458 Prior to giving this command, gdb's thread suspend-counts are relative\n\
3459 to the thread's initial suspend-count when gdb notices the threads."),
3471 proc_server = getproc ();
3477 _(
"Set debugging output for the gnu backend."),
3478 _(
"Show debugging output for the gnu backend."),
3486 #ifdef FLUSH_INFERIOR_CACHE
3494 flush_inferior_icache (
CORE_ADDR pc,
int amount)
3496 vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
3499 ret = vm_machine_attribute (gnu_current_inf->
task->
port,
3504 if (ret != KERN_SUCCESS)
struct gdbarch * target_gdbarch(void)
static void set_task_detach_sc_cmd(char *args, int from_tty)
static void check_empty(char *args, char *cmd_prefix)
void target_terminal_ours(void)
static ptid_t gnu_wait(struct target_ops *ops, ptid_t ptid, struct target_waitstatus *status, int options)
struct value * value_mark(void)
void inf_set_pid(struct inf *inf, pid_t pid)
struct cmd_list_element * add_prefix_cmd(const char *name, enum command_class theclass, cmd_cfunc_ftype *fun, const char *doc, struct cmd_list_element **prefixlist, const char *prefixname, int allow_unknown, struct cmd_list_element **list)
static void thread_takeover_sc_cmd(char *args, int from_tty)
static void set_thread_pause_cmd(char *args, int from_tty)
struct thread_info * add_thread(ptid_t ptid)
static void set_thread_exc_port_cmd(char *args, int from_tty)
static void set_task_exc_port_cmd(char *args, int from_tty)
#define THREAD_STATE_CLEAR_TRACED(state)
static void set_sig_thread_cmd(char *args, int from_tty)
static void gnu_create_inferior(struct target_ops *ops, char *exec_file, char *allargs, char **env, int from_tty)
void value_free_to_mark(struct value *mark)
static int gnu_read_inferior(task_t task, CORE_ADDR addr, gdb_byte *myaddr, int length)
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
int(* to_find_memory_regions)(struct target_ops *, find_memory_region_ftype func, void *data) TARGET_DEFAULT_FUNC(dummy_find_memory_regions)
struct target_waitstatus status
static struct proc * inf_port_to_thread(struct inf *inf, mach_port_t port)
char * proc_string(struct proc *proc)
static void show_thread_default_detach_sc_cmd(char *args, int from_tty)
#define INF_MSGPORT_RPC(inf, rpc_expr)
void inf_set_threads_resume_sc(struct inf *inf, struct proc *run_thread, int run_others)
int __proc_pid(struct proc *proc)
LONGEST value_as_long(struct value *val)
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t data_t mach_msg_type_number_t threadwaitsCnt mach_port_t kern_return_t data_t mach_msg_type_number_t procenvCnt mach_port_t kern_return_t pidarray_t mach_msg_type_number_t pidsCnt mach_port_t kern_return_t pid_t sid mach_port_t kern_return_t pidarray_t pidset
static void info_port_rights(const char *args, mach_port_type_t only)
void warning(const char *fmt,...)
char *(* to_pid_to_str)(struct target_ops *, ptid_t) TARGET_DEFAULT_FUNC(default_pid_to_str)
static void scan(struct macro_buffer *dest, struct macro_buffer *src, struct macro_name_list *no_loop, macro_lookup_ftype *lookup_func, void *lookup_baton)
int query(const char *ctlstr,...)
static void set_signals_cmd(char *args, int from_tty)
void(* to_terminal_init)(struct target_ops *) TARGET_DEFAULT_IGNORE()
void push_target(struct target_ops *t)
static void info_port_rights_cmd(char *args, int from_tty)
static void steal_exc_port(struct proc *proc, mach_port_t name)
unsigned long fetched_regs
struct ui_file * gdb_stdout
void inf_continue(struct inf *inf)
static void info_recv_rights_cmd(char *args, int from_tty)
void( inf_threads_ftype)(struct proc *thread, void *arg)
static char * gnu_pid_to_str(struct target_ops *ops, ptid_t ptid)
static void set_task_pause_cmd(char *args, int from_tty)
static int gnu_find_memory_regions(struct target_ops *self, find_memory_region_ftype func, void *data)
void inf_attach(struct inf *inf, int pid)
void inf_startup(struct inf *inf, int pid)
static struct inf * cur_inf(void)
void inf_restore_exc_ports(struct inf *inf)
void inf_threads(struct inf *inf, inf_threads_ftype *f, void *arg)
ptid_t(* to_wait)(struct target_ops *, ptid_t, struct target_waitstatus *, int TARGET_DEBUG_PRINTER(target_debug_print_options)) TARGET_DEFAULT_NORETURN(noprocess())
static void show_stopped_cmd(char *args, int from_tty)
char * target_pid_to_str(ptid_t ptid)
#define THREAD_STATE_FLAVOR
#define inf_debug(_inf, msg, args...)
void inf_cleanup(struct inf *inf)
int default_thread_detach_sc
void inf_child_maybe_unpush_target(struct target_ops *ops)
#define INF_RESUME_MSGPORT_RPC(inf, rpc_expr)
void inf_clear_wait(struct inf *inf)
static void set_thread_default_pause_cmd(char *args, int from_tty)
static void info_port_sets_cmd(char *args, int from_tty)
void inf_resume(struct inf *inf)
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t data_t mach_msg_type_number_t threadwaitsCnt mach_port_t kern_return_t data_t procenv
static void show_thread_run_cmd(char *args, int from_tty)
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
static int _parse_bool_arg(char *args, char *t_val, char *f_val, char *cmd_prefix)
ptid_t ptid_build(int pid, long lwp, long tid)
int inf_set_threads_resume_sc_for_signal_thread(struct inf *inf)
struct proc * step_thread
static int parse_int_arg(char *args, char *cmd_prefix)
static void add_thread_commands(void)
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int flags
void proc_abort(struct proc *proc, int force)
mach_port_t kern_return_t return_code
struct cmd_list_element * infolist
struct cmd_list_element * setlist
static void show_task_pause_cmd(char *args, int from_tty)
ptid_t thread_id_to_pid(int)
void initialize_file_ftype(void)
static void gnu_mourn_inferior(struct target_ops *ops)
static process_t proc_server
void startup_inferior(int ntraps)
thread_state_data_t state
error_t S_exception_raise_request(mach_port_t port, mach_port_t reply_port, thread_t thread_port, task_t task_port, int exception, int code, int subcode)
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t err
static void gnu_terminal_init(struct target_ops *self)
void child_terminal_init_with_pgrp(int pgrp)
void inf_set_step_thread(struct inf *inf, struct proc *proc)
static void show_thread_default_cmd(char *args, int from_tty)
void inf_signal(struct inf *inf, enum gdb_signal sig)
static void set_task_cmd(char *args, int from_tty)
void target_terminal_inferior(void)
static void gnu_detach(struct target_ops *ops, const char *args, int from_tty)
void(* to_resume)(struct target_ops *, ptid_t, int TARGET_DEBUG_PRINTER(target_debug_print_step), enum gdb_signal) TARGET_DEFAULT_NORETURN(noprocess())
struct proc * _proc_free(struct proc *proc)
error_t proc_get_exception_port(struct proc *proc, mach_port_t *port)
struct cmd_list_element * showlist
struct target_ops * gnu_target(void)
#define CHK_GOTO_OUT(str, ret)
#define THREAD_STATE_SET_TRACED(state)
struct cmd_list_element * add_cmd(const char *name, enum command_class theclass, cmd_cfunc_ftype *fun, const char *doc, struct cmd_list_element **list)
#define parse_bool_arg(args, cmd_prefix)
ptid_t pid_to_ptid(int pid)
struct proc * signal_thread
void store_waitstatus(struct target_waitstatus *ourstatus, int hoststatus)
union target_waitstatus::@161 value
static void gnu_attach(struct target_ops *ops, const char *args, int from_tty)
char * pulongest(ULONGEST u)
int gdb_signal_to_host(enum gdb_signal)
enum gdb_signal gdb_signal_from_host(int)
static void show_sig_thread_cmd(char *args, int from_tty)
static void inf_validate_task_sc(struct inf *inf)
int inf_update_suspends(struct inf *inf)
void target_mourn_inferior(void)
void thread_change_ptid(ptid_t old_ptid, ptid_t new_ptid)
mach_port_t saved_exc_port
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t data_t threadwaits
static void set_thread_detach_sc_cmd(char *args, int from_tty)
struct vm_region_list * next
struct cmd_list_element * add_alias_cmd(const char *name, const char *oldname, enum command_class theclass, int abbrev_flag, struct cmd_list_element **list)
int fork_inferior(char *exec_file_arg, char *allargs, char **env, void(*traceme_fun)(void), void(*init_trace_fun)(int), void(*pre_trace_fun)(void), char *shell_file_arg, void(*exec_fun)(const char *file, char *const *argv, char *const *env))
struct thread_info * add_thread_silent(ptid_t ptid)
const char * gdb_signal_to_name(enum gdb_signal)
unsigned int pending_execs
static void set_thread_default_detach_sc_cmd(char *args, int from_tty)
enum target_xfer_status(* to_xfer_partial)(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) TARGET_DEFAULT_RETURN(TARGET_XFER_E_IO)
static struct inf * make_inf()
void printf_unfiltered(const char *format,...)
void inf_validate_procs(struct inf *inf)
struct cmd_list_element * setdebuglist
static void inf_set_traced(struct inf *inf, int on)
void(* to_detach)(struct target_ops *ops, const char *, int) TARGET_DEFAULT_IGNORE()
void inf_child_mourn_inferior(struct target_ops *ops)
static void gnu_kill_inferior(struct target_ops *ops)
static void set_stopped_cmd(char *args, int from_tty)
error_t proc_set_exception_port(struct proc *proc, mach_port_t port)
static void add_task_commands(void)
static void inf_task_died_status(struct inf *inf)
void inf_detach(struct inf *inf)
void proc_steal_exc_port(struct proc *proc, mach_port_t exc_port)
void inf_steal_exc_ports(struct inf *inf)
int inf_update_procs(struct inf *inf)
static void gnu_resume(struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal sig)
int ptid_get_pid(ptid_t ptid)
struct value * parse_to_comma_and_eval(const char **expp)
static int gnu_write_inferior(task_t task, CORE_ADDR addr, const gdb_byte *myaddr, int length)
static void show_signals_cmd(char *args, int from_tty)
void target_terminal_init(void)
static void show_thread_detach_sc_cmd(char *args, int from_tty)
struct inf * gnu_current_inf
static void show_task_cmd(char *args, int from_tty)
struct target_ops * inf_child_target(void)
void(* to_mourn_inferior)(struct target_ops *) TARGET_DEFAULT_FUNC(default_mourn_inferior)
static mach_port_t _proc_get_exc_port(struct proc *proc)
error_t do_mach_notify_dead_name(mach_port_t notify, mach_port_t dead_port)
void(* to_stop)(struct target_ops *, ptid_t) TARGET_DEFAULT_IGNORE()
static void set_thread_cmd(char *args, int from_tty)
int xsnprintf(char *str, size_t size, const char *format,...)
CORE_ADDR parse_and_eval_address(const char *exp)
#define START_INFERIOR_TRAPS_EXPECTED
enum target_waitkind kind
initialize_file_ftype _initialize_gnu_nat
void(* to_kill)(struct target_ops *) TARGET_DEFAULT_NORETURN(noprocess())
void detach_inferior(int pid)
char * safe_strerror(int)
const char * host_address_to_string(const void *addr)
static int inf_pick_first_thread(void)
static void show_task_detach_sc_cmd(char *args, int from_tty)
static void info_dead_names_cmd(char *args, int from_tty)
void(* to_create_inferior)(struct target_ops *, char *, char *, char **, int)
static void info_send_rights_cmd(char *args, int from_tty)
static void show_thread_default_run_cmd(char *args, int from_tty)
int parse_pid_to_attach(const char *args)
int default_thread_run_sc
struct obstack region_obstack
int proc_update_sc(struct proc *proc)
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t data_t mach_msg_type_number_t threadwaitsCnt mach_port_t kern_return_t data_t mach_msg_type_number_t procenvCnt mach_port_t kern_return_t pidarray_t pids
static void show_thread_default_pause_cmd(char *args, int from_tty)
void inf_suspend(struct inf *inf)
struct inferior * current_inferior(void)
struct cmd_list_element * add_info_alias(const char *name, const char *oldname, int abbrev_flag)
static void inf_validate_procinfo(struct inf *inf)
char * get_exec_file(int err)
unsigned long long ULONGEST
void proc_restore_exc_port(struct proc *proc)
#define proc_is_task(proc)
static void show_thread_pause_cmd(char *args, int from_tty)
long ptid_get_lwp(ptid_t ptid)
#define THREAD_STATE_SIZE
struct cmd_list_element * showdebuglist
#define proc_is_thread(proc)
struct proc * make_proc(struct inf *inf, mach_port_t port, int tid)
int proc_trace(struct proc *proc, int set)
int(* to_thread_alive)(struct target_ops *, ptid_t ptid) TARGET_DEFAULT_RETURN(0)
static void show_thread_cmd(char *args, int from_tty)
static void set_exceptions_cmd(char *args, int from_tty)
struct cmd_list_element * thread_cmd_list
void(* to_attach)(struct target_ops *ops, const char *, int)
void gdb_flush(struct ui_file *file)
mach_port_t kern_return_t mach_port_t msgports mach_port_t kern_return_t pid_t pid mach_port_t kern_return_t mach_port_t task mach_port_t kern_return_t int procinfo_t mach_msg_type_number_t procinfoCnt
static enum target_xfer_status gnu_xfer_memory(gdb_byte *readbuf, const gdb_byte *writebuf, CORE_ADDR memaddr, ULONGEST len, ULONGEST *xfered_len)
static enum target_xfer_status gnu_xfer_partial(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
static void set_noninvasive_cmd(char *args, int from_tty)
int(* find_memory_region_ftype)(CORE_ADDR addr, unsigned long size, int read, int write, int exec, int modified, void *data)
static void show_exceptions_cmd(char *args, int from_tty)
int default_thread_pause_sc
thread_state_t proc_get_state(struct proc *proc, int will_modify)
static void set_thread_run_cmd(char *args, int from_tty)
static void inf_update_signal_thread(struct inf *inf)
void error(const char *fmt,...)
static void set_thread_default_cmd(char *args, int from_tty)
static int next_thread_id
static void set_thread_default_run_cmd(char *args, int from_tty)
static struct inf * active_inf(void)
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int int rusage_t pid_t pid
static void gnu_stop(struct target_ops *self, ptid_t ptid)
void inferior_appeared(struct inferior *inf, int pid)
static struct proc * cur_thread(void)
void add_setshow_boolean_cmd(const char *name, enum command_class theclass, int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
struct proc * inf_tid_to_thread(struct inf *inf, int tid)
#define proc_debug(_proc, msg, args...)
static int gnu_thread_alive(struct target_ops *ops, ptid_t ptid)
const ULONGEST const LONGEST len