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