GDB (xrefs)
/tmp/gdb-8.1/gdb/darwin-nat-info.c
Go to the documentation of this file.
1 /* Darwin support for GDB, the GNU debugger.
2  Copyright (C) 1997-2018 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 (const 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 (const 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 
123 
124  return priv->task;
125  }
126  if (strcmp (args, "gdb") == 0)
127  return mach_task_self ();
128  task = strtoul (args, &eptr, 0);
129  if (*eptr)
130  {
131  printf_unfiltered (_("cannot parse task id '%s'\n"), args);
132  return TASK_NULL;
133  }
134  return task;
135 }
136 
137 static void
138 info_mach_task_command (const char *args, int from_tty)
139 {
140  union
141  {
142  struct task_basic_info basic;
143  struct task_events_info events;
144  struct task_thread_times_info thread_times;
145  } task_info_data;
146 
147  kern_return_t result;
148  unsigned int info_count;
149  task_t task;
150 
151  task = get_task_from_args (args);
152  if (task == TASK_NULL)
153  return;
154 
155  printf_unfiltered (_("TASK_BASIC_INFO for 0x%x:\n"), task);
156  info_count = TASK_BASIC_INFO_COUNT;
157  result = task_info (task,
158  TASK_BASIC_INFO,
159  (task_info_t) & task_info_data.basic, &info_count);
160  MACH_CHECK_ERROR (result);
161 
162  PRINT_FIELD (&task_info_data.basic, suspend_count);
163  PRINT_FIELD (&task_info_data.basic, virtual_size);
164  PRINT_FIELD (&task_info_data.basic, resident_size);
165  PRINT_TV_FIELD (&task_info_data.basic, user_time);
166  PRINT_TV_FIELD (&task_info_data.basic, system_time);
167  printf_unfiltered (_("\nTASK_EVENTS_INFO:\n"));
168  info_count = TASK_EVENTS_INFO_COUNT;
169  result = task_info (task,
170  TASK_EVENTS_INFO,
171  (task_info_t) & task_info_data.events, &info_count);
172  MACH_CHECK_ERROR (result);
173 
174  PRINT_FIELD (&task_info_data.events, faults);
175 #if 0
176  PRINT_FIELD (&task_info_data.events, zero_fills);
177  PRINT_FIELD (&task_info_data.events, reactivations);
178 #endif
179  PRINT_FIELD (&task_info_data.events, pageins);
180  PRINT_FIELD (&task_info_data.events, cow_faults);
181  PRINT_FIELD (&task_info_data.events, messages_sent);
182  PRINT_FIELD (&task_info_data.events, messages_received);
183  printf_unfiltered (_("\nTASK_THREAD_TIMES_INFO:\n"));
184  info_count = TASK_THREAD_TIMES_INFO_COUNT;
185  result = task_info (task,
186  TASK_THREAD_TIMES_INFO,
187  (task_info_t) & task_info_data.thread_times,
188  &info_count);
189  MACH_CHECK_ERROR (result);
190  PRINT_TV_FIELD (&task_info_data.thread_times, user_time);
191  PRINT_TV_FIELD (&task_info_data.thread_times, system_time);
192 }
193 
194 static void
195 info_mach_ports_command (const char *args, int from_tty)
196 {
197  port_name_array_t names;
198  port_type_array_t types;
199  unsigned int name_count, type_count;
200  kern_return_t result;
201  int index;
202  task_t task;
203 
204  task = get_task_from_args (args);
205  if (task == TASK_NULL)
206  return;
207 
208  result = mach_port_names (task, &names, &name_count, &types, &type_count);
209  MACH_CHECK_ERROR (result);
210 
211  gdb_assert (name_count == type_count);
212 
213  printf_unfiltered (_("Ports for task 0x%x:\n"), task);
214  printf_unfiltered (_("port type\n"));
215  for (index = 0; index < name_count; ++index)
216  {
217  mach_port_t port = names[index];
218  unsigned int j;
219  struct type_descr
220  {
221  mach_port_type_t type;
222  const char *name;
223  mach_port_right_t right;
224  };
225  static struct type_descr descrs[] =
226  {
227  {MACH_PORT_TYPE_SEND, "send", MACH_PORT_RIGHT_SEND},
228  {MACH_PORT_TYPE_SEND_ONCE, "send-once", MACH_PORT_RIGHT_SEND_ONCE},
229  {MACH_PORT_TYPE_RECEIVE, "receive", MACH_PORT_RIGHT_RECEIVE},
230  {MACH_PORT_TYPE_PORT_SET, "port-set", MACH_PORT_RIGHT_PORT_SET},
231  {MACH_PORT_TYPE_DEAD_NAME, "dead", MACH_PORT_RIGHT_DEAD_NAME}
232  };
233 
234  printf_unfiltered (_("%04x: %08x "), port, types[index]);
235  for (j = 0; j < sizeof(descrs) / sizeof(*descrs); j++)
236  if (types[index] & descrs[j].type)
237  {
238  mach_port_urefs_t ref;
239  kern_return_t ret;
240 
241  printf_unfiltered (_(" %s("), descrs[j].name);
242  ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
243  if (ret != KERN_SUCCESS)
244  printf_unfiltered (_("??"));
245  else
246  printf_unfiltered (_("%u"), ref);
247  printf_unfiltered (_(" refs)"));
248  }
249 
250  if (task == task_self ())
251  {
252  if (port == task_self())
253  printf_unfiltered (_(" gdb-task"));
254  else if (port == darwin_host_self)
255  printf_unfiltered (_(" host-self"));
256  else if (port == darwin_ex_port)
257  printf_unfiltered (_(" gdb-exception"));
258  else if (port == darwin_port_set)
259  printf_unfiltered (_(" gdb-port_set"));
260  else if (!ptid_equal (inferior_ptid, null_ptid))
261  {
262  struct inferior *inf = current_inferior ();
264 
265  if (port == priv->task)
266  printf_unfiltered (_(" inferior-task"));
267  else if (port == priv->notify_port)
268  printf_unfiltered (_(" inferior-notify"));
269  else
270  {
271  for (int k = 0; k < priv->exception_info.count; k++)
272  if (port == priv->exception_info.ports[k])
273  {
274  printf_unfiltered (_(" inferior-excp-port"));
275  break;
276  }
277 
278  for (darwin_thread_t *t : priv->threads)
279  {
280  if (port == t->gdb_port)
281  {
282  printf_unfiltered (_(" inferior-thread for 0x%x"),
283  priv->task);
284  break;
285  }
286  }
287 
288  }
289  }
290  }
291  printf_unfiltered (_("\n"));
292  }
293 
294  vm_deallocate (task_self (), (vm_address_t) names,
295  (name_count * sizeof (mach_port_t)));
296  vm_deallocate (task_self (), (vm_address_t) types,
297  (type_count * sizeof (mach_port_type_t)));
298 }
299 
300 
301 static void
302 darwin_debug_port_info (task_t task, mach_port_t port)
303 {
304  kern_return_t kret;
305  mach_port_status_t status;
306  mach_msg_type_number_t len = sizeof (status);
307 
308  kret = mach_port_get_attributes
309  (task, port, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, &len);
310  MACH_CHECK_ERROR (kret);
311 
312  printf_unfiltered (_("Port 0x%lx in task 0x%lx:\n"), (unsigned long) port,
313  (unsigned long) task);
314  printf_unfiltered (_(" port set: 0x%x\n"), status.mps_pset);
315  printf_unfiltered (_(" seqno: 0x%x\n"), status.mps_seqno);
316  printf_unfiltered (_(" mscount: 0x%x\n"), status.mps_mscount);
317  printf_unfiltered (_(" qlimit: 0x%x\n"), status.mps_qlimit);
318  printf_unfiltered (_(" msgcount: 0x%x\n"), status.mps_msgcount);
319  printf_unfiltered (_(" sorights: 0x%x\n"), status.mps_sorights);
320  printf_unfiltered (_(" srights: 0x%x\n"), status.mps_srights);
321  printf_unfiltered (_(" pdrequest: 0x%x\n"), status.mps_pdrequest);
322  printf_unfiltered (_(" nsrequest: 0x%x\n"), status.mps_nsrequest);
323  printf_unfiltered (_(" flags: 0x%x\n"), status.mps_flags);
324 }
325 
326 static void
327 info_mach_port_command (const char *args, int from_tty)
328 {
329  task_t task;
330  mach_port_t port;
331 
332  CHECK_ARGS (_("Task and port"), args);
333  sscanf (args, "0x%x 0x%x", &task, &port);
334 
335  darwin_debug_port_info (task, port);
336 }
337 
338 static void
339 info_mach_threads_command (const char *args, int from_tty)
340 {
341  thread_array_t threads;
342  unsigned int thread_count;
343  kern_return_t result;
344  task_t task;
345  int i;
346 
347  task = get_task_from_args (args);
348  if (task == TASK_NULL)
349  return;
350 
351  result = task_threads (task, &threads, &thread_count);
352  MACH_CHECK_ERROR (result);
353 
354  printf_unfiltered (_("Threads in task %#x:\n"), task);
355  for (i = 0; i < thread_count; ++i)
356  {
357  printf_unfiltered (_(" %#x\n"), threads[i]);
358  mach_port_deallocate (task_self (), threads[i]);
359  }
360 
361  vm_deallocate (task_self (), (vm_address_t) threads,
362  (thread_count * sizeof (thread_t)));
363 }
364 
365 static void
366 info_mach_thread_command (const char *args, int from_tty)
367 {
368  union
369  {
370  struct thread_basic_info basic;
371  } thread_info_data;
372 
373  thread_t thread;
374  kern_return_t result;
375  unsigned int info_count;
376 
377  CHECK_ARGS (_("Thread"), args);
378  sscanf (args, "0x%x", &thread);
379 
380  printf_unfiltered (_("THREAD_BASIC_INFO\n"));
381  info_count = THREAD_BASIC_INFO_COUNT;
382  result = thread_info (thread,
383  THREAD_BASIC_INFO,
384  (thread_info_t) & thread_info_data.basic,
385  &info_count);
386  MACH_CHECK_ERROR (result);
387 
388 #if 0
389  PRINT_FIELD (&thread_info_data.basic, user_time);
390  PRINT_FIELD (&thread_info_data.basic, system_time);
391 #endif
392  PRINT_FIELD (&thread_info_data.basic, cpu_usage);
393  PRINT_FIELD (&thread_info_data.basic, run_state);
394  PRINT_FIELD (&thread_info_data.basic, flags);
395  PRINT_FIELD (&thread_info_data.basic, suspend_count);
396  PRINT_FIELD (&thread_info_data.basic, sleep_time);
397 }
398 
399 static const char *
400 unparse_protection (vm_prot_t p)
401 {
402  switch (p)
403  {
404  case VM_PROT_NONE:
405  return "---";
406  case VM_PROT_READ:
407  return "r--";
408  case VM_PROT_WRITE:
409  return "-w-";
410  case VM_PROT_READ | VM_PROT_WRITE:
411  return "rw-";
412  case VM_PROT_EXECUTE:
413  return "--x";
414  case VM_PROT_EXECUTE | VM_PROT_READ:
415  return "r-x";
416  case VM_PROT_EXECUTE | VM_PROT_WRITE:
417  return "-wx";
418  case VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ:
419  return "rwx";
420  default:
421  return "???";
422  }
423 }
424 
425 static const char *
426 unparse_inheritance (vm_inherit_t i)
427 {
428  switch (i)
429  {
430  case VM_INHERIT_SHARE:
431  return _("share");
432  case VM_INHERIT_COPY:
433  return _("copy ");
434  case VM_INHERIT_NONE:
435  return _("none ");
436  default:
437  return _("??? ");
438  }
439 }
440 
441 static const char *
442 unparse_share_mode (unsigned char p)
443 {
444  switch (p)
445  {
446  case SM_COW:
447  return _("cow");
448  case SM_PRIVATE:
449  return _("private");
450  case SM_EMPTY:
451  return _("empty");
452  case SM_SHARED:
453  return _("shared");
454  case SM_TRUESHARED:
455  return _("true-shrd");
456  case SM_PRIVATE_ALIASED:
457  return _("prv-alias");
458  case SM_SHARED_ALIASED:
459  return _("shr-alias");
460  default:
461  return _("???");
462  }
463 }
464 
465 static const char *
466 unparse_user_tag (unsigned int tag)
467 {
468  switch (tag)
469  {
470  case 0:
471  return _("default");
472  case VM_MEMORY_MALLOC:
473  return _("malloc");
474  case VM_MEMORY_MALLOC_SMALL:
475  return _("malloc_small");
476  case VM_MEMORY_MALLOC_LARGE:
477  return _("malloc_large");
478  case VM_MEMORY_MALLOC_HUGE:
479  return _("malloc_huge");
480  case VM_MEMORY_SBRK:
481  return _("sbrk");
482  case VM_MEMORY_REALLOC:
483  return _("realloc");
484  case VM_MEMORY_MALLOC_TINY:
485  return _("malloc_tiny");
486  case VM_MEMORY_ANALYSIS_TOOL:
487  return _("analysis_tool");
488  case VM_MEMORY_MACH_MSG:
489  return _("mach_msg");
490  case VM_MEMORY_IOKIT:
491  return _("iokit");
492  case VM_MEMORY_STACK:
493  return _("stack");
494  case VM_MEMORY_GUARD:
495  return _("guard");
496  case VM_MEMORY_SHARED_PMAP:
497  return _("shared_pmap");
498  case VM_MEMORY_DYLIB:
499  return _("dylib");
500  case VM_MEMORY_APPKIT:
501  return _("appkit");
502  case VM_MEMORY_FOUNDATION:
503  return _("foundation");
504  default:
505  return NULL;
506  }
507 }
508 
509 static void
510 darwin_debug_regions (task_t task, mach_vm_address_t address, int max)
511 {
512  kern_return_t kret;
513  vm_region_basic_info_data_64_t info, prev_info;
514  mach_vm_address_t prev_address;
515  mach_vm_size_t size, prev_size;
516 
517  mach_port_t object_name;
518  mach_msg_type_number_t count;
519 
520  int nsubregions = 0;
521  int num_printed = 0;
522 
523  count = VM_REGION_BASIC_INFO_COUNT_64;
524  kret = mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO_64,
525  (vm_region_info_t) &info, &count, &object_name);
526  if (kret != KERN_SUCCESS)
527  {
528  printf_filtered (_("No memory regions."));
529  return;
530  }
531  memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
532  prev_address = address;
533  prev_size = size;
534  nsubregions = 1;
535 
536  for (;;)
537  {
538  int print = 0;
539  int done = 0;
540 
541  address = prev_address + prev_size;
542 
543  /* Check to see if address space has wrapped around. */
544  if (address == 0)
545  print = done = 1;
546 
547  if (!done)
548  {
549  count = VM_REGION_BASIC_INFO_COUNT_64;
550  kret =
551  mach_vm_region (task, &address, &size, VM_REGION_BASIC_INFO_64,
552  (vm_region_info_t) &info, &count, &object_name);
553  if (kret != KERN_SUCCESS)
554  {
555  size = 0;
556  print = done = 1;
557  }
558  }
559 
560  if (address != prev_address + prev_size)
561  print = 1;
562 
563  if ((info.protection != prev_info.protection)
564  || (info.max_protection != prev_info.max_protection)
565  || (info.inheritance != prev_info.inheritance)
566  || (info.shared != prev_info.reserved)
567  || (info.reserved != prev_info.reserved))
568  print = 1;
569 
570  if (print)
571  {
572  printf_filtered (_("%s-%s %s/%s %s %s %s"),
573  paddress (target_gdbarch (), prev_address),
574  paddress (target_gdbarch (), prev_address + prev_size),
575  unparse_protection (prev_info.protection),
576  unparse_protection (prev_info.max_protection),
577  unparse_inheritance (prev_info.inheritance),
578  prev_info.shared ? _("shrd") : _("priv"),
579  prev_info.reserved ? _("reserved") : _("not-rsvd"));
580 
581  if (nsubregions > 1)
582  printf_filtered (_(" (%d sub-rgn)"), nsubregions);
583 
584  printf_filtered (_("\n"));
585 
586  prev_address = address;
587  prev_size = size;
588  memcpy (&prev_info, &info, sizeof (vm_region_basic_info_data_64_t));
589  nsubregions = 1;
590 
591  num_printed++;
592  }
593  else
594  {
595  prev_size += size;
596  nsubregions++;
597  }
598 
599  if ((max > 0) && (num_printed >= max))
600  done = 1;
601 
602  if (done)
603  break;
604  }
605 }
606 
607 static void
609 {
610  mach_vm_address_t r_addr;
611  mach_vm_address_t r_start;
612  mach_vm_size_t r_size;
613  natural_t r_depth;
614  mach_msg_type_number_t r_info_size;
615  vm_region_submap_short_info_data_64_t r_info;
616  kern_return_t kret;
617  int ret;
618  struct ui_out *uiout = current_uiout;
619 
620  ui_out_emit_table table_emitter (uiout, 9, -1, "regions");
621 
622  if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
623  {
624  uiout->table_header (10, ui_left, "start", "Start");
625  uiout->table_header (10, ui_left, "end", "End");
626  }
627  else
628  {
629  uiout->table_header (18, ui_left, "start", "Start");
630  uiout->table_header (18, ui_left, "end", "End");
631  }
632  uiout->table_header (3, ui_left, "min-prot", "Min");
633  uiout->table_header (3, ui_left, "max-prot", "Max");
634  uiout->table_header (5, ui_left, "inheritence", "Inh");
635  uiout->table_header (9, ui_left, "share-mode", "Shr");
636  uiout->table_header (1, ui_left, "depth", "D");
637  uiout->table_header (3, ui_left, "submap", "Sm");
638  uiout->table_header (0, ui_noalign, "tag", "Tag");
639 
640  uiout->table_body ();
641 
642  r_start = 0;
643  r_depth = 0;
644  while (1)
645  {
646  const char *tag;
647 
648  r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
649  r_size = -1;
650  kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth,
651  (vm_region_recurse_info_t) &r_info,
652  &r_info_size);
653  if (kret != KERN_SUCCESS)
654  break;
655 
656  {
657  ui_out_emit_tuple tuple_emitter (uiout, "regions-row");
658 
659  uiout->field_core_addr ("start", target_gdbarch (), r_start);
660  uiout->field_core_addr ("end", target_gdbarch (), r_start + r_size);
661  uiout->field_string ("min-prot",
662  unparse_protection (r_info.protection));
663  uiout->field_string ("max-prot",
664  unparse_protection (r_info.max_protection));
665  uiout->field_string ("inheritence",
666  unparse_inheritance (r_info.inheritance));
667  uiout->field_string ("share-mode",
668  unparse_share_mode (r_info.share_mode));
669  uiout->field_int ("depth", r_depth);
670  uiout->field_string ("submap",
671  r_info.is_submap ? _("sm ") : _("obj"));
672  tag = unparse_user_tag (r_info.user_tag);
673  if (tag)
674  uiout->field_string ("tag", tag);
675  else
676  uiout->field_int ("tag", r_info.user_tag);
677  }
678 
679  if (!uiout->is_mi_like_p ())
680  uiout->text ("\n");
681 
682  if (r_info.is_submap)
683  r_depth++;
684  else
685  r_start += r_size;
686  }
687 }
688 
689 
690 static void
691 darwin_debug_region (task_t task, mach_vm_address_t address)
692 {
693  darwin_debug_regions (task, address, 1);
694 }
695 
696 static void
697 info_mach_regions_command (const char *args, int from_tty)
698 {
699  task_t task;
700 
701  task = get_task_from_args (args);
702  if (task == TASK_NULL)
703  return;
704 
705  darwin_debug_regions (task, 0, -1);
706 }
707 
708 static void
709 info_mach_regions_recurse_command (const char *args, int from_tty)
710 {
711  task_t task;
712 
713  task = get_task_from_args (args);
714  if (task == TASK_NULL)
715  return;
716 
718 }
719 
720 static void
721 info_mach_region_command (const char *exp, int from_tty)
722 {
723  struct value *val;
724  mach_vm_address_t address;
725  struct inferior *inf;
726 
727  expression_up expr = parse_expression (exp);
728  val = evaluate_expression (expr.get ());
729  if (TYPE_IS_REFERENCE (value_type (val)))
730  {
731  val = value_ind (val);
732  }
733  address = value_as_address (val);
734 
736  error (_("Inferior not available"));
737 
738  inf = current_inferior ();
740  darwin_debug_region (priv->task, address);
741 }
742 
743 static void
745 {
746  int i;
747 
748  printf_filtered (_("%d exceptions:\n"), info->count);
749  for (i = 0; i < info->count; i++)
750  {
751  exception_mask_t mask = info->masks[i];
752 
753  printf_filtered (_("port 0x%04x, behavior: "), info->ports[i]);
754  switch (info->behaviors[i])
755  {
756  case EXCEPTION_DEFAULT:
757  printf_unfiltered (_("default"));
758  break;
759  case EXCEPTION_STATE:
760  printf_unfiltered (_("state"));
761  break;
762  case EXCEPTION_STATE_IDENTITY:
763  printf_unfiltered (_("state-identity"));
764  break;
765  default:
766  printf_unfiltered (_("0x%x"), info->behaviors[i]);
767  }
768  printf_unfiltered (_(", masks:"));
769  if (mask & EXC_MASK_BAD_ACCESS)
770  printf_unfiltered (_(" BAD_ACCESS"));
771  if (mask & EXC_MASK_BAD_INSTRUCTION)
772  printf_unfiltered (_(" BAD_INSTRUCTION"));
773  if (mask & EXC_MASK_ARITHMETIC)
774  printf_unfiltered (_(" ARITHMETIC"));
775  if (mask & EXC_MASK_EMULATION)
776  printf_unfiltered (_(" EMULATION"));
777  if (mask & EXC_MASK_SOFTWARE)
778  printf_unfiltered (_(" SOFTWARE"));
779  if (mask & EXC_MASK_BREAKPOINT)
780  printf_unfiltered (_(" BREAKPOINT"));
781  if (mask & EXC_MASK_SYSCALL)
782  printf_unfiltered (_(" SYSCALL"));
783  if (mask & EXC_MASK_MACH_SYSCALL)
784  printf_unfiltered (_(" MACH_SYSCALL"));
785  if (mask & EXC_MASK_RPC_ALERT)
786  printf_unfiltered (_(" RPC_ALERT"));
787  if (mask & EXC_MASK_CRASH)
788  printf_unfiltered (_(" CRASH"));
789  printf_unfiltered (_("\n"));
790  }
791 }
792 
793 static void
794 info_mach_exceptions_command (const char *args, int from_tty)
795 {
796  int i;
797  task_t task;
798  kern_return_t kret;
800 
801  info.count = sizeof (info.ports) / sizeof (info.ports[0]);
802 
803  if (args != NULL)
804  {
805  if (strcmp (args, "saved") == 0)
806  {
808  printf_unfiltered (_("No inferior running\n"));
809 
811 
812  disp_exception (&priv->exception_info);
813  return;
814  }
815  else if (strcmp (args, "host") == 0)
816  {
817  /* FIXME: This need a privilegied host port! */
818  kret = host_get_exception_ports
819  (darwin_host_self, EXC_MASK_ALL, info.masks,
820  &info.count, info.ports, info.behaviors, info.flavors);
821  MACH_CHECK_ERROR (kret);
822  disp_exception (&info);
823  }
824  else
825  error (_("Parameter is saved, host or none"));
826  }
827  else
828  {
829  struct inferior *inf;
830 
832  printf_unfiltered (_("No inferior running\n"));
833  inf = current_inferior ();
834 
836 
837  kret = task_get_exception_ports
838  (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 void
847 {
848  add_info ("mach-tasks", info_mach_tasks_command,
849  _("Get list of tasks in system."));
850  add_info ("mach-ports", info_mach_ports_command,
851  _("Get list of ports in a task."));
852  add_info ("mach-port", info_mach_port_command,
853  _("Get info on a specific port."));
854  add_info ("mach-task", info_mach_task_command,
855  _("Get info on a specific task."));
856  add_info ("mach-threads", info_mach_threads_command,
857  _("Get list of threads in a task."));
858  add_info ("mach-thread", info_mach_thread_command,
859  _("Get info on a specific thread."));
860 
861  add_info ("mach-regions", info_mach_regions_command,
862  _("Get information on all mach region for the task."));
863  add_info ("mach-regions-rec", info_mach_regions_recurse_command,
864  _("Get information on all mach sub region for the task."));
865  add_info ("mach-region", info_mach_region_command,
866  _("Get information on mach region at given address."));
867 
868  add_info ("mach-exceptions", info_mach_exceptions_command,
869  _("Disp mach exceptions."));
870 }
struct gdbarch * target_gdbarch(void)
Definition: gdbarch.c:5467
thread_state_flavor_t flavors[EXC_TYPES_COUNT]
Definition: darwin-nat.h:39
static void info_mach_region_command(const char *exp, int from_tty)
void field_core_addr(const char *fldname, struct gdbarch *gdbarch, CORE_ADDR address)
Definition: ui-out.c:513
void field_string(const char *fldname, const char *string)
Definition: ui-out.c:544
gdb::unique_xmalloc_ptr< expression > expression_up
Definition: expression.h:87
void xfree(void *)
static const char * unparse_inheritance(vm_inherit_t i)
static const char * unparse_user_tag(unsigned int tag)
struct cmd_list_element * add_info(const char *name, cmd_const_cfunc_ftype *fun, const char *doc)
Definition: cli-decode.c:886
static void info_mach_task_command(const char *args, int from_tty)
void table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr)
Definition: ui-out.c:365
exception_mask_t masks[EXC_TYPES_COUNT]
Definition: darwin-nat.h:30
struct value * value_ind(struct value *arg1)
Definition: valops.c:1542
static void info_mach_regions_command(const char *args, int from_tty)
exception_behavior_t behaviors[EXC_TYPES_COUNT]
Definition: darwin-nat.h:36
#define _(String)
Definition: gdb_locale.h:35
Definition: ui-out.h:44
void text(const char *string)
Definition: ui-out.c:581
mach_port_t darwin_ex_port
Definition: darwin-nat.c:134
mach_port_t ports[EXC_TYPES_COUNT]
Definition: darwin-nat.h:33
void printf_filtered(const char *format,...)
Definition: utils.c:2045
#define MACH_CHECK_ERROR(ret)
Definition: darwin-nat.h:152
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
Definition: utils.c:2745
#define TYPE_IS_REFERENCE(t)
Definition: gdbtypes.h:332
static void info_mach_exceptions_command(const char *args, int from_tty)
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:1891
struct value * evaluate_expression(struct expression *exp)
Definition: eval.c:144
int thread_count(void)
Definition: thread.c:567
const char *const name
Definition: aarch64-tdep.c:76
static void disp_exception(const darwin_exception_info *info)
static task_t get_task_from_args(const char *args)
static const char * unparse_protection(vm_prot_t p)
mach_port_t darwin_host_self
Definition: darwin-nat.c:131
static void darwin_debug_regions_recurse(task_t task)
static void info_mach_port_command(const char *args, int from_tty)
void _initialize_darwin_info_commands(void)
#define port_type_array_t
#define CHECK_ARGS(what, args)
static const char * unparse_share_mode(unsigned char p)
#define current_uiout
Definition: ui-out.h:39
Definition: gdbtypes.h:749
static darwin_inferior * get_darwin_inferior(inferior *inf)
Definition: darwin-nat.h:133
static void info_mach_threads_command(const char *args, int from_tty)
Definition: gnu-nat.c:174
#define task_by_unix_pid
static const char * type
Definition: language.c:113
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
Definition: gnu-nat.c:1822
#define PRINT_TV_FIELD(structure, field)
int gdbarch_addr_bit(struct gdbarch *gdbarch)
Definition: gdbarch.c:1848
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:2056
void * xmalloc(YYSIZE_T)
pthread_t thread_t
#define gdb_assert(expr)
Definition: gdb_assert.h:32
Definition: value.c:169
Definition: ui-out.h:77
#define port_name_array_t
ptid_t null_ptid
Definition: ptid.c:25
mach_port_t darwin_port_set
Definition: darwin-nat.c:137
std::unique_ptr< private_inferior > priv
Definition: inferior.h:411
static void info_mach_regions_recurse_command(const char *args, int from_tty)
void field_int(const char *fldname, int value)
Definition: ui-out.c:486
ptid_t inferior_ptid
Definition: infcmd.c:94
static void info_mach_ports_command(const char *args, int from_tty)
void table_body()
Definition: ui-out.c:379
static void darwin_debug_regions(task_t task, mach_vm_address_t address, int max)
static void info_mach_thread_command(const char *args, int from_tty)
thread_t gdb_port
Definition: darwin-nat.h:76
int ptid_equal(const ptid_t &ptid1, const ptid_t &ptid2)
Definition: ptid.c:71
struct inferior * current_inferior(void)
Definition: inferior.c:58
#define task_self
expression_up parse_expression(const char *)
Definition: parse.c:1237
#define PRINT_FIELD(structure, field)
struct type * value_type(const struct value *value)
Definition: value.c:1095
CORE_ADDR value_as_address(struct value *val)
Definition: value.c:2762
char * args
Definition: inferior.h:352
static void info_mach_tasks_command(const char *args, int from_tty)
CORE_ADDR address
Definition: value.c:208
mach_msg_type_number_t count
Definition: darwin-nat.h:42
void error(const char *fmt,...)
Definition: errors.c:38
size_t size
Definition: go32-nat.c:242
bool is_mi_like_p()
Definition: ui-out.c:622