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