* linux-low.c (regsets_fetch_inferior_registers): Fix memory leak.
[gdb/SamB.git] / gdb / darwin-nat-info.c
blob93a1779386b3d24d4606738ddf8ae756a870fe67
1 /* Darwin support for GDB, the GNU debugger.
2 Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2008, 2009
3 Free Software Foundation, Inc.
5 Contributed by Apple Computer, Inc.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 /* The name of the ppc_thread_state structure, and the names of its
23 members, have been changed for Unix conformance reasons. The easiest
24 way to have gdb build on systems with the older names and systems
25 with the newer names is to build this compilation unit with the
26 non-conformant define below. This doesn't seem to cause the resulting
27 binary any problems but it seems like it could cause us problems in
28 the future. It'd be good to remove this at some point when compiling on
29 Tiger is no longer important. */
31 #include "defs.h"
32 #include "symtab.h"
33 #include "gdbtypes.h"
34 #include "gdbcore.h"
35 #include "value.h"
36 #include "gdbcmd.h"
37 #include "inferior.h"
39 #include <sys/param.h>
40 #include <sys/sysctl.h>
42 #include "darwin-nat.h"
44 #include <mach/thread_info.h>
45 #include <mach/thread_act.h>
46 #include <mach/task.h>
47 #include <mach/vm_map.h>
48 #include <mach/mach_port.h>
49 #include <mach/mach_init.h>
50 #include <mach/mach_vm.h>
52 #define CHECK_ARGS(what, args) do { \
53 if ((NULL == args) || ((args[0] != '0') && (args[1] != 'x'))) \
54 error("%s must be specified with 0x...", what); \
55 } while (0)
57 #define PRINT_FIELD(structure, field) \
58 printf_unfiltered(_(#field":\t%#lx\n"), (unsigned long) (structure)->field)
60 #define PRINT_TV_FIELD(structure, field) \
61 printf_unfiltered(_(#field":\t%u.%06u sec\n"), \
62 (unsigned) (structure)->field.seconds, \
63 (unsigned) (structure)->field.microseconds)
65 #define task_self mach_task_self
66 #define task_by_unix_pid task_for_pid
67 #define port_name_array_t mach_port_array_t
68 #define port_type_array_t mach_port_array_t
70 static void
71 info_mach_tasks_command (char *args, int from_tty)
73 int sysControl[4];
74 int count, index;
75 size_t length;
76 struct kinfo_proc *procInfo;
78 sysControl[0] = CTL_KERN;
79 sysControl[1] = KERN_PROC;
80 sysControl[2] = KERN_PROC_ALL;
82 sysctl (sysControl, 3, NULL, &length, NULL, 0);
83 procInfo = (struct kinfo_proc *) xmalloc (length);
84 sysctl (sysControl, 3, procInfo, &length, NULL, 0);
86 count = (length / sizeof (struct kinfo_proc));
87 printf_unfiltered (_("%d processes:\n"), count);
88 for (index = 0; index < count; ++index)
90 kern_return_t result;
91 mach_port_t taskPort;
93 result =
94 task_by_unix_pid (mach_task_self (), procInfo[index].kp_proc.p_pid,
95 &taskPort);
96 if (KERN_SUCCESS == result)
98 printf_unfiltered (_(" %s is %d has task %#x\n"),
99 procInfo[index].kp_proc.p_comm,
100 procInfo[index].kp_proc.p_pid, taskPort);
102 else
104 printf_unfiltered (_(" %s is %d unknown task port\n"),
105 procInfo[index].kp_proc.p_comm,
106 procInfo[index].kp_proc.p_pid);
110 xfree (procInfo);
113 static task_t
114 get_task_from_args (char *args)
116 task_t task;
117 char *eptr;
119 if (args == NULL || *args == 0)
121 if (darwin_inf->task == TASK_NULL)
122 printf_unfiltered (_("No inferior running\n"));
123 return darwin_inf->task;
125 if (strcmp (args, "gdb") == 0)
126 return mach_task_self ();
127 task = strtoul (args, &eptr, 0);
128 if (*eptr)
130 printf_unfiltered (_("cannot parse task id '%s'\n"), args);
131 return TASK_NULL;
133 return task;
136 static void
137 info_mach_task_command (char *args, int from_tty)
139 union
141 struct task_basic_info basic;
142 struct task_events_info events;
143 struct task_thread_times_info thread_times;
144 } task_info_data;
146 kern_return_t result;
147 unsigned int info_count;
148 task_t task;
150 task = get_task_from_args (args);
151 if (task == TASK_NULL)
152 return;
154 printf_unfiltered (_("TASK_BASIC_INFO for 0x%x:\n"), task);
155 info_count = TASK_BASIC_INFO_COUNT;
156 result = task_info (task,
157 TASK_BASIC_INFO,
158 (task_info_t) & task_info_data.basic, &info_count);
159 MACH_CHECK_ERROR (result);
161 PRINT_FIELD (&task_info_data.basic, suspend_count);
162 PRINT_FIELD (&task_info_data.basic, virtual_size);
163 PRINT_FIELD (&task_info_data.basic, resident_size);
164 PRINT_TV_FIELD (&task_info_data.basic, user_time);
165 PRINT_TV_FIELD (&task_info_data.basic, system_time);
166 printf_unfiltered (_("\nTASK_EVENTS_INFO:\n"));
167 info_count = TASK_EVENTS_INFO_COUNT;
168 result = task_info (task,
169 TASK_EVENTS_INFO,
170 (task_info_t) & task_info_data.events, &info_count);
171 MACH_CHECK_ERROR (result);
173 PRINT_FIELD (&task_info_data.events, faults);
174 #if 0
175 PRINT_FIELD (&task_info_data.events, zero_fills);
176 PRINT_FIELD (&task_info_data.events, reactivations);
177 #endif
178 PRINT_FIELD (&task_info_data.events, pageins);
179 PRINT_FIELD (&task_info_data.events, cow_faults);
180 PRINT_FIELD (&task_info_data.events, messages_sent);
181 PRINT_FIELD (&task_info_data.events, messages_received);
182 printf_unfiltered (_("\nTASK_THREAD_TIMES_INFO:\n"));
183 info_count = TASK_THREAD_TIMES_INFO_COUNT;
184 result = task_info (task,
185 TASK_THREAD_TIMES_INFO,
186 (task_info_t) & task_info_data.thread_times,
187 &info_count);
188 MACH_CHECK_ERROR (result);
189 PRINT_TV_FIELD (&task_info_data.thread_times, user_time);
190 PRINT_TV_FIELD (&task_info_data.thread_times, system_time);
193 static void
194 info_mach_ports_command (char *args, int from_tty)
196 port_name_array_t names;
197 port_type_array_t types;
198 unsigned int name_count, type_count;
199 kern_return_t result;
200 int index;
201 task_t task;
203 task = get_task_from_args (args);
204 if (task == TASK_NULL)
205 return;
207 result = mach_port_names (task, &names, &name_count, &types, &type_count);
208 MACH_CHECK_ERROR (result);
210 gdb_assert (name_count == type_count);
212 printf_unfiltered (_("Ports for task 0x%x:\n"), task);
213 printf_unfiltered (_("port type\n"));
214 for (index = 0; index < name_count; ++index)
216 mach_port_t port = names[index];
217 unsigned int j;
218 struct type_descr
220 mach_port_type_t type;
221 const char *name;
222 mach_port_right_t right;
224 static struct type_descr descrs[] =
226 {MACH_PORT_TYPE_SEND, "send", MACH_PORT_RIGHT_SEND},
227 {MACH_PORT_TYPE_SEND_ONCE, "send-once", MACH_PORT_RIGHT_SEND_ONCE},
228 {MACH_PORT_TYPE_RECEIVE, "receive", MACH_PORT_RIGHT_RECEIVE},
229 {MACH_PORT_TYPE_PORT_SET, "port-set", MACH_PORT_RIGHT_PORT_SET},
230 {MACH_PORT_TYPE_DEAD_NAME, "dead", MACH_PORT_RIGHT_DEAD_NAME}
233 printf_unfiltered (_("%04x: %08x "), port, types[index]);
234 for (j = 0; j < sizeof(descrs) / sizeof(*descrs); j++)
235 if (types[index] & descrs[j].type)
237 mach_port_urefs_t ref;
238 kern_return_t ret;
240 printf_unfiltered (_(" %s("), descrs[j].name);
241 ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
242 if (ret != KERN_SUCCESS)
243 printf_unfiltered (_("??"));
244 else
245 printf_unfiltered (_("%u"), ref);
246 printf_unfiltered (_(" refs)"));
249 if (task == task_self ())
251 if (port == task_self())
252 printf_unfiltered (_(" gdb-task"));
253 else if (port == darwin_host_self)
254 printf_unfiltered (_(" host-self"));
255 else if (port == darwin_not_port)
256 printf_unfiltered (_(" gdb-notifier"));
257 else if (port == darwin_ex_port)
258 printf_unfiltered (_(" gdb-exception"));
259 else if (port == darwin_port_set)
260 printf_unfiltered (_(" gdb-port_set"));
261 else if (darwin_inf && port == darwin_inf->task)
262 printf_unfiltered (_(" inferior-task"));
263 else if (darwin_inf && darwin_inf->threads)
265 int k;
266 thread_t t;
267 for (k = 0; VEC_iterate(thread_t, darwin_inf->threads, k, t); k++)
268 if (port == t)
270 printf_unfiltered (_(" inferior-thread for 0x%x"),
271 darwin_inf->task);
272 break;
276 printf_unfiltered (_("\n"));
279 vm_deallocate (task_self (), (vm_address_t) names,
280 (name_count * sizeof (mach_port_t)));
281 vm_deallocate (task_self (), (vm_address_t) types,
282 (type_count * sizeof (mach_port_type_t)));
286 void
287 darwin_debug_port_info (task_t task, mach_port_t port)
289 kern_return_t kret;
290 mach_port_status_t status;
291 mach_msg_type_number_t len = sizeof (status);
293 kret = mach_port_get_attributes
294 (task, port, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, &len);
295 MACH_CHECK_ERROR (kret);
297 printf_unfiltered (_("Port 0x%lx in task 0x%lx:\n"), (unsigned long) port,
298 (unsigned long) task);
299 printf_unfiltered (_(" port set: 0x%x\n"), status.mps_pset);
300 printf_unfiltered (_(" seqno: 0x%x\n"), status.mps_seqno);
301 printf_unfiltered (_(" mscount: 0x%x\n"), status.mps_mscount);
302 printf_unfiltered (_(" qlimit: 0x%x\n"), status.mps_qlimit);
303 printf_unfiltered (_(" msgcount: 0x%x\n"), status.mps_msgcount);
304 printf_unfiltered (_(" sorights: 0x%x\n"), status.mps_sorights);
305 printf_unfiltered (_(" srights: 0x%x\n"), status.mps_srights);
306 printf_unfiltered (_(" pdrequest: 0x%x\n"), status.mps_pdrequest);
307 printf_unfiltered (_(" nsrequest: 0x%x\n"), status.mps_nsrequest);
308 printf_unfiltered (_(" flags: 0x%x\n"), status.mps_flags);
311 static void
312 info_mach_port_command (char *args, int from_tty)
314 task_t task;
315 mach_port_t port;
317 CHECK_ARGS (_("Task and port"), args);
318 sscanf (args, "0x%x 0x%x", &task, &port);
320 darwin_debug_port_info (task, port);
323 static void
324 info_mach_threads_command (char *args, int from_tty)
326 thread_array_t threads;
327 unsigned int thread_count;
328 kern_return_t result;
329 task_t task;
330 int i;
332 task = get_task_from_args (args);
333 if (task == TASK_NULL)
334 return;
336 result = task_threads (task, &threads, &thread_count);
337 MACH_CHECK_ERROR (result);
339 printf_unfiltered (_("Threads in task %#x:\n"), task);
340 for (i = 0; i < thread_count; ++i)
342 printf_unfiltered (_(" %#x\n"), threads[i]);
343 mach_port_deallocate (task_self (), threads[i]);
346 vm_deallocate (task_self (), (vm_address_t) threads,
347 (thread_count * sizeof (thread_t)));
350 static void
351 info_mach_thread_command (char *args, int from_tty)
353 union
355 struct thread_basic_info basic;
356 } thread_info_data;
358 thread_t thread;
359 kern_return_t result;
360 unsigned int info_count;
362 CHECK_ARGS (_("Thread"), args);
363 sscanf (args, "0x%x", &thread);
365 printf_unfiltered (_("THREAD_BASIC_INFO\n"));
366 info_count = THREAD_BASIC_INFO_COUNT;
367 result = thread_info (thread,
368 THREAD_BASIC_INFO,
369 (thread_info_t) & thread_info_data.basic,
370 &info_count);
371 MACH_CHECK_ERROR (result);
373 #if 0
374 PRINT_FIELD (&thread_info_data.basic, user_time);
375 PRINT_FIELD (&thread_info_data.basic, system_time);
376 #endif
377 PRINT_FIELD (&thread_info_data.basic, cpu_usage);
378 PRINT_FIELD (&thread_info_data.basic, run_state);
379 PRINT_FIELD (&thread_info_data.basic, flags);
380 PRINT_FIELD (&thread_info_data.basic, suspend_count);
381 PRINT_FIELD (&thread_info_data.basic, sleep_time);
384 static const char *
385 unparse_protection (vm_prot_t p)
387 switch (p)
389 case VM_PROT_NONE:
390 return "---";
391 case VM_PROT_READ:
392 return "r--";
393 case VM_PROT_WRITE:
394 return "-w-";
395 case VM_PROT_READ | VM_PROT_WRITE:
396 return "rw-";
397 case VM_PROT_EXECUTE:
398 return "--x";
399 case VM_PROT_EXECUTE | VM_PROT_READ:
400 return "r-x";
401 case VM_PROT_EXECUTE | VM_PROT_WRITE:
402 return "-wx";
403 case VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ:
404 return "rwx";
405 default:
406 return "???";
410 static const char *
411 unparse_inheritance (vm_inherit_t i)
413 switch (i)
415 case VM_INHERIT_SHARE:
416 return _("share");
417 case VM_INHERIT_COPY:
418 return _("copy ");
419 case VM_INHERIT_NONE:
420 return _("none ");
421 default:
422 return _("??? ");
426 static const char *
427 unparse_share_mode (unsigned char p)
429 switch (p)
431 case SM_COW:
432 return _("cow");
433 case SM_PRIVATE:
434 return _("private");
435 case SM_EMPTY:
436 return _("empty");
437 case SM_SHARED:
438 return _("shared");
439 case SM_TRUESHARED:
440 return _("true-shrd");
441 case SM_PRIVATE_ALIASED:
442 return _("prv-alias");
443 case SM_SHARED_ALIASED:
444 return _("shr-alias");
445 default:
446 return _("???");
450 static const char *
451 unparse_user_tag (unsigned int tag)
453 switch (tag)
455 case 0:
456 return _("default");
457 case VM_MEMORY_MALLOC:
458 return _("malloc");
459 case VM_MEMORY_MALLOC_SMALL:
460 return _("malloc_small");
461 case VM_MEMORY_MALLOC_LARGE:
462 return _("malloc_large");
463 case VM_MEMORY_MALLOC_HUGE:
464 return _("malloc_huge");
465 case VM_MEMORY_SBRK:
466 return _("sbrk");
467 case VM_MEMORY_REALLOC:
468 return _("realloc");
469 case VM_MEMORY_MALLOC_TINY:
470 return _("malloc_tiny");
471 case VM_MEMORY_ANALYSIS_TOOL:
472 return _("analysis_tool");
473 case VM_MEMORY_MACH_MSG:
474 return _("mach_msg");
475 case VM_MEMORY_IOKIT:
476 return _("iokit");
477 case VM_MEMORY_STACK:
478 return _("stack");
479 case VM_MEMORY_GUARD:
480 return _("guard");
481 case VM_MEMORY_SHARED_PMAP:
482 return _("shared_pmap");
483 case VM_MEMORY_DYLIB:
484 return _("dylib");
485 case VM_MEMORY_APPKIT:
486 return _("appkit");
487 case VM_MEMORY_FOUNDATION:
488 return _("foundation");
489 default:
490 return NULL;
494 static void
495 darwin_debug_regions (task_t task, mach_vm_address_t address, int max)
497 kern_return_t kret;
498 vm_region_basic_info_data_64_t info, prev_info;
499 mach_vm_address_t prev_address;
500 mach_vm_size_t size, prev_size;
502 mach_port_t object_name;
503 mach_msg_type_number_t count;
505 int nsubregions = 0;
506 int num_printed = 0;
508 count = VM_REGION_BASIC_INFO_COUNT_64;
509 kret = mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO_64,
510 (vm_region_info_t) &info, &count, &object_name);
511 if (kret != KERN_SUCCESS)
513 printf_filtered (_("No memory regions."));
514 return;
516 memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
517 prev_address = address;
518 prev_size = size;
519 nsubregions = 1;
521 for (;;)
523 int print = 0;
524 int done = 0;
526 address = prev_address + prev_size;
528 /* Check to see if address space has wrapped around. */
529 if (address == 0)
530 print = done = 1;
532 if (!done)
534 count = VM_REGION_BASIC_INFO_COUNT_64;
535 kret =
536 mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO_64,
537 (vm_region_info_t) &info, &count, &object_name);
538 if (kret != KERN_SUCCESS)
540 size = 0;
541 print = done = 1;
545 if (address != prev_address + prev_size)
546 print = 1;
548 if ((info.protection != prev_info.protection)
549 || (info.max_protection != prev_info.max_protection)
550 || (info.inheritance != prev_info.inheritance)
551 || (info.shared != prev_info.reserved)
552 || (info.reserved != prev_info.reserved))
553 print = 1;
555 if (print)
557 printf_filtered (_("%s-%s %s/%s %s %s %s"),
558 paddr(prev_address),
559 paddr(prev_address + prev_size),
560 unparse_protection (prev_info.protection),
561 unparse_protection (prev_info.max_protection),
562 unparse_inheritance (prev_info.inheritance),
563 prev_info.shared ? _("shrd") : _("priv"),
564 prev_info.reserved ? _("reserved") : _("not-rsvd"));
566 if (nsubregions > 1)
567 printf_filtered (_(" (%d sub-rgn)"), nsubregions);
569 printf_filtered (_("\n"));
571 prev_address = address;
572 prev_size = size;
573 memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
574 nsubregions = 1;
576 num_printed++;
578 else
580 prev_size += size;
581 nsubregions++;
584 if ((max > 0) && (num_printed >= max))
585 done = 1;
587 if (done)
588 break;
592 static void
593 darwin_debug_regions_recurse (task_t task)
595 mach_vm_address_t r_addr;
596 mach_vm_address_t r_start;
597 mach_vm_size_t r_size;
598 natural_t r_depth;
599 mach_msg_type_number_t r_info_size;
600 vm_region_submap_short_info_data_64_t r_info;
601 kern_return_t kret;
602 int ret;
604 r_start = 0;
605 r_depth = 0;
606 while (1)
608 const char *tag;
610 r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
611 r_size = -1;
612 kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth,
613 (vm_region_recurse_info_t) &r_info,
614 &r_info_size);
615 if (kret != KERN_SUCCESS)
616 break;
617 printf_filtered (_("%s-%s %s/%s %-5s %-10s %2d %s"),
618 paddr(r_start),
619 paddr(r_start + r_size),
620 unparse_protection (r_info.protection),
621 unparse_protection (r_info.max_protection),
622 unparse_inheritance (r_info.inheritance),
623 unparse_share_mode (r_info.share_mode),
624 r_depth,
625 r_info.is_submap ? _("sm ") : _("obj"));
626 tag = unparse_user_tag (r_info.user_tag);
627 if (tag)
628 printf_unfiltered (_(" %s\n"), tag);
629 else
630 printf_unfiltered (_(" %u\n"), r_info.user_tag);
631 if (r_info.is_submap)
632 r_depth++;
633 else
634 r_start += r_size;
639 static void
640 darwin_debug_region (task_t task, mach_vm_address_t address)
642 darwin_debug_regions (task, address, 1);
645 static void
646 info_mach_regions_command (char *args, int from_tty)
648 task_t task;
650 task = get_task_from_args (args);
651 if (task == TASK_NULL)
652 return;
654 darwin_debug_regions (task, 0, -1);
657 static void
658 info_mach_regions_recurse_command (char *args, int from_tty)
660 task_t task;
662 task = get_task_from_args (args);
663 if (task == TASK_NULL)
664 return;
666 darwin_debug_regions_recurse (task);
669 static void
670 info_mach_region_command (char *exp, int from_tty)
672 struct expression *expr;
673 struct value *val;
674 mach_vm_address_t address;
676 expr = parse_expression (exp);
677 val = evaluate_expression (expr);
678 if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
680 val = value_ind (val);
682 /* In rvalue contexts, such as this, functions are coerced into
683 pointers to functions. */
684 if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
685 && VALUE_LVAL (val) == lval_memory)
687 address = VALUE_ADDRESS (val);
689 else
691 address = value_as_address (val);
694 if ((!darwin_inf) || (darwin_inf->task == TASK_NULL))
695 error (_("Inferior not available"));
697 darwin_debug_region (darwin_inf->task, address);
700 static void
701 disp_exception (const darwin_exception_info *info)
703 int i;
705 printf_filtered (_("%d exceptions:\n"), info->count);
706 for (i = 0; i < info->count; i++)
708 exception_mask_t mask = info->masks[i];
710 printf_filtered (_("port 0x%04x, behavior: "), info->ports[i]);
711 switch (info->behaviors[i])
713 case EXCEPTION_DEFAULT:
714 printf_unfiltered (_("default"));
715 break;
716 case EXCEPTION_STATE:
717 printf_unfiltered (_("state"));
718 break;
719 case EXCEPTION_STATE_IDENTITY:
720 printf_unfiltered (_("state-identity"));
721 break;
722 default:
723 printf_unfiltered (_("0x%x"), info->behaviors[i]);
725 printf_unfiltered (_(", masks:"));
726 if (mask & EXC_MASK_BAD_ACCESS)
727 printf_unfiltered (_(" BAD_ACCESS"));
728 if (mask & EXC_MASK_BAD_INSTRUCTION)
729 printf_unfiltered (_(" BAD_INSTRUCTION"));
730 if (mask & EXC_MASK_ARITHMETIC)
731 printf_unfiltered (_(" ARITHMETIC"));
732 if (mask & EXC_MASK_EMULATION)
733 printf_unfiltered (_(" EMULATION"));
734 if (mask & EXC_MASK_SOFTWARE)
735 printf_unfiltered (_(" SOFTWARE"));
736 if (mask & EXC_MASK_BREAKPOINT)
737 printf_unfiltered (_(" BREAKPOINT"));
738 if (mask & EXC_MASK_SYSCALL)
739 printf_unfiltered (_(" SYSCALL"));
740 if (mask & EXC_MASK_MACH_SYSCALL)
741 printf_unfiltered (_(" MACH_SYSCALL"));
742 if (mask & EXC_MASK_RPC_ALERT)
743 printf_unfiltered (_(" RPC_ALERT"));
744 if (mask & EXC_MASK_CRASH)
745 printf_unfiltered (_(" CRASH"));
746 printf_unfiltered (_("\n"));
750 static void
751 info_mach_exceptions_command (char *args, int from_tty)
753 int i;
754 task_t task;
755 kern_return_t kret;
756 darwin_exception_info info;
758 info.count = sizeof (info.ports) / sizeof (info.ports[0]);
760 if (args != NULL)
762 if (strcmp (args, "saved") == 0)
764 if (darwin_inf->task == TASK_NULL)
765 error (_("No inferior running\n"));
766 disp_exception (&darwin_inf->exception_info);
767 return;
769 else if (strcmp (args, "host") == 0)
771 /* FIXME: This need a the privilegied host port! */
772 kret = host_get_exception_ports
773 (darwin_host_self, EXC_MASK_ALL, info.masks,
774 &info.count, info.ports, info.behaviors, info.flavors);
775 MACH_CHECK_ERROR (kret);
776 disp_exception (&info);
778 else
779 error (_("Parameter is saved, host or none"));
781 else
783 if (darwin_inf->task == TASK_NULL)
784 error (_("No inferior running\n"));
786 kret = task_get_exception_ports
787 (darwin_inf->task, EXC_MASK_ALL, info.masks,
788 &info.count, info.ports, info.behaviors, info.flavors);
789 MACH_CHECK_ERROR (kret);
790 disp_exception (&info);
794 static void
795 darwin_list_gdb_ports (const char *msg)
797 mach_port_name_array_t names;
798 mach_port_type_array_t types;
799 unsigned int name_count, type_count;
800 kern_return_t result;
801 int i;
803 result = mach_port_names (mach_task_self (),
804 &names, &name_count, &types, &type_count);
805 MACH_CHECK_ERROR (result);
807 gdb_assert (name_count == type_count);
809 printf_unfiltered (_("Ports for %s:"), msg);
810 for (i = 0; i < name_count; ++i)
811 printf_unfiltered (_(" 0x%04x"), names[i]);
812 printf_unfiltered (_("\n"));
814 vm_deallocate (mach_task_self (), (vm_address_t) names,
815 (name_count * sizeof (mach_port_t)));
816 vm_deallocate (mach_task_self (), (vm_address_t) types,
817 (type_count * sizeof (mach_port_type_t)));
820 void
821 _initialize_darwin_info_commands (void)
823 add_info ("mach-tasks", info_mach_tasks_command,
824 _("Get list of tasks in system."));
825 add_info ("mach-ports", info_mach_ports_command,
826 _("Get list of ports in a task."));
827 add_info ("mach-port", info_mach_port_command,
828 _("Get info on a specific port."));
829 add_info ("mach-task", info_mach_task_command,
830 _("Get info on a specific task."));
831 add_info ("mach-threads", info_mach_threads_command,
832 _("Get list of threads in a task."));
833 add_info ("mach-thread", info_mach_thread_command,
834 _("Get info on a specific thread."));
836 add_info ("mach-regions", info_mach_regions_command,
837 _("Get information on all mach region for the task."));
838 add_info ("mach-regions-rec", info_mach_regions_recurse_command,
839 _("Get information on all mach sub region for the task."));
840 add_info ("mach-region", info_mach_region_command,
841 _("Get information on mach region at given address."));
843 add_info ("mach-exceptions", info_mach_exceptions_command,
844 _("Disp mach exceptions."));