39#include <sys/sysctl.h>
43#include <mach/thread_info.h>
44#include <mach/thread_act.h>
46#include <mach/vm_map.h>
47#include <mach/mach_port.h>
48#include <mach/mach_init.h>
49#include <mach/mach_vm.h>
51#define CHECK_ARGS(what, args) do { \
52 if ((NULL == args) || ((args[0] != '0') && (args[1] != 'x'))) \
53 error(_("%s must be specified with 0x..."), what); \
56#define PRINT_FIELD(structure, field) \
57 gdb_printf(_(#field":\t%#lx\n"), (unsigned long) (structure)->field)
59#define PRINT_TV_FIELD(structure, field) \
60 gdb_printf(_(#field":\t%u.%06u sec\n"), \
61 (unsigned) (structure)->field.seconds, \
62 (unsigned) (structure)->field.microseconds)
64#define task_self mach_task_self
65#define task_by_unix_pid task_for_pid
66#define port_name_array_t mach_port_array_t
67#define port_type_array_t mach_port_array_t
75 struct kinfo_proc *procInfo;
77 sysControl[0] = CTL_KERN;
78 sysControl[1] = KERN_PROC;
79 sysControl[2] = KERN_PROC_ALL;
81 sysctl (sysControl, 3, NULL, &length, NULL, 0);
82 procInfo = (
struct kinfo_proc *)
xmalloc (length);
83 sysctl (sysControl, 3, procInfo, &length, NULL, 0);
85 count = (length /
sizeof (
struct kinfo_proc));
87 for (index = 0; index < count; ++index)
95 if (KERN_SUCCESS == result)
98 procInfo[index].kp_proc.p_comm,
99 procInfo[index].kp_proc.p_pid, taskPort);
103 gdb_printf (_(
" %s is %d unknown task port\n"),
104 procInfo[index].kp_proc.p_comm,
105 procInfo[index].kp_proc.p_pid);
118 if (args == NULL || *args == 0)
127 if (strcmp (args,
"gdb") == 0)
128 return mach_task_self ();
129 task = strtoul (args, &eptr, 0);
132 gdb_printf (_(
"cannot parse task id '%s'\n"), args);
143 struct task_basic_info basic;
144 struct task_events_info events;
145 struct task_thread_times_info thread_times;
148 kern_return_t result;
149 unsigned int info_count;
153 if (task == TASK_NULL)
156 gdb_printf (_(
"TASK_BASIC_INFO for 0x%x:\n"), task);
157 info_count = TASK_BASIC_INFO_COUNT;
158 result = task_info (task,
160 (task_info_t) & task_info_data.basic, &info_count);
163 PRINT_FIELD (&task_info_data.basic, suspend_count);
165 PRINT_FIELD (&task_info_data.basic, resident_size);
169 info_count = TASK_EVENTS_INFO_COUNT;
170 result = task_info (task,
172 (task_info_t) & task_info_data.events, &info_count);
178 PRINT_FIELD (&task_info_data.events, reactivations);
182 PRINT_FIELD (&task_info_data.events, messages_sent);
183 PRINT_FIELD (&task_info_data.events, messages_received);
184 gdb_printf (_(
"\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,
200 unsigned int name_count, type_count;
201 kern_return_t result;
206 if (task == TASK_NULL)
209 result = mach_port_names (task, &names, &name_count, &types, &type_count);
212 gdb_assert (name_count == type_count);
214 gdb_printf (_(
"Ports for task 0x%x:\n"), task);
216 for (index = 0; index < name_count; ++index)
218 mach_port_t port = names[index];
222 mach_port_type_t
type;
224 mach_port_right_t right;
226 static struct type_descr descrs[] =
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}
235 gdb_printf (_(
"%04x: %08x "), port, types[index]);
236 for (j = 0; j <
sizeof(descrs) /
sizeof(*descrs); j++)
237 if (types[index] & descrs[j].
type)
239 mach_port_urefs_t ref;
243 ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
244 if (ret != KERN_SUCCESS)
266 if (port ==
priv->task)
268 else if (port ==
priv->notify_port)
272 for (
int k = 0; k <
priv->exception_info.count; k++)
273 if (port ==
priv->exception_info.ports[k])
281 if (port == t->gdb_port)
295 vm_deallocate (
task_self (), (vm_address_t) names,
296 (name_count *
sizeof (mach_port_t)));
297 vm_deallocate (
task_self (), (vm_address_t) types,
298 (type_count *
sizeof (mach_port_type_t)));
306 mach_port_status_t
status;
307 mach_msg_type_number_t len =
sizeof (
status);
309 kret = mach_port_get_attributes
310 (task, port, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&
status, &len);
313 gdb_printf (_(
"Port 0x%lx in task 0x%lx:\n"), (
unsigned long) port,
314 (
unsigned long) task);
334 sscanf (
args,
"0x%x 0x%x", &task, &port);
344 kern_return_t result;
349 if (task == TASK_NULL)
355 gdb_printf (_(
"Threads in task %#x:\n"), task);
359 mach_port_deallocate (
task_self (), threads[i]);
362 vm_deallocate (
task_self (), (vm_address_t) threads,
371 struct thread_basic_info basic;
375 kern_return_t result;
376 unsigned int info_count;
379 sscanf (args,
"0x%x", &thread);
382 info_count = THREAD_BASIC_INFO_COUNT;
385 (thread_info_t) & thread_info_data.basic,
391 PRINT_FIELD (&thread_info_data.basic, system_time);
396 PRINT_FIELD (&thread_info_data.basic, suspend_count);
411 case VM_PROT_READ | VM_PROT_WRITE:
413 case VM_PROT_EXECUTE:
415 case VM_PROT_EXECUTE | VM_PROT_READ:
417 case VM_PROT_EXECUTE | VM_PROT_WRITE:
419 case VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ:
431 case VM_INHERIT_SHARE:
433 case VM_INHERIT_COPY:
435 case VM_INHERIT_NONE:
456 return _(
"true-shrd");
457 case SM_PRIVATE_ALIASED:
458 return _(
"prv-alias");
459 case SM_SHARED_ALIASED:
460 return _(
"shr-alias");
473 case VM_MEMORY_MALLOC:
475 case VM_MEMORY_MALLOC_SMALL:
476 return _(
"malloc_small");
477 case VM_MEMORY_MALLOC_LARGE:
478 return _(
"malloc_large");
479 case VM_MEMORY_MALLOC_HUGE:
480 return _(
"malloc_huge");
483 case VM_MEMORY_REALLOC:
485 case VM_MEMORY_MALLOC_TINY:
486 return _(
"malloc_tiny");
487 case VM_MEMORY_ANALYSIS_TOOL:
488 return _(
"analysis_tool");
489 case VM_MEMORY_MACH_MSG:
490 return _(
"mach_msg");
491 case VM_MEMORY_IOKIT:
493 case VM_MEMORY_STACK:
495 case VM_MEMORY_GUARD:
497 case VM_MEMORY_SHARED_PMAP:
498 return _(
"shared_pmap");
499 case VM_MEMORY_DYLIB:
501 case VM_MEMORY_APPKIT:
503 case VM_MEMORY_FOUNDATION:
504 return _(
"foundation");
514 vm_region_basic_info_data_64_t info, prev_info;
515 mach_vm_address_t prev_address;
516 mach_vm_size_t
size, prev_size;
518 mach_port_t object_name;
519 mach_msg_type_number_t count;
524 count = VM_REGION_BASIC_INFO_COUNT_64;
525 kret = mach_vm_region (task, &address, &
size, VM_REGION_BASIC_INFO_64,
526 (vm_region_info_t) &info, &count, &object_name);
527 if (kret != KERN_SUCCESS)
532 memcpy (&prev_info, &info,
sizeof (vm_region_basic_info_data_64_t));
533 prev_address = address;
542 address = prev_address + prev_size;
550 count = VM_REGION_BASIC_INFO_COUNT_64;
552 mach_vm_region (task, &address, &
size, VM_REGION_BASIC_INFO_64,
553 (vm_region_info_t) &info, &count, &object_name);
554 if (kret != KERN_SUCCESS)
561 if (address != prev_address + prev_size)
564 if ((info.protection != prev_info.protection)
565 || (info.max_protection != prev_info.max_protection)
566 || (info.inheritance != prev_info.inheritance)
567 || (info.shared != prev_info.reserved)
568 || (info.reserved != prev_info.reserved))
579 prev_info.shared ? _(
"shrd") : _(
"priv"),
580 prev_info.reserved ? _(
"reserved") : _(
"not-rsvd"));
587 prev_address = address;
589 memcpy (&prev_info, &info,
sizeof (vm_region_basic_info_data_64_t));
600 if ((max > 0) && (num_printed >= max))
611 mach_vm_address_t r_start;
612 mach_vm_size_t r_size;
614 mach_msg_type_number_t r_info_size;
615 vm_region_submap_short_info_data_64_t r_info;
647 r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
649 kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth,
650 (vm_region_recurse_info_t) &r_info,
652 if (kret != KERN_SUCCESS)
670 r_info.is_submap ? _(
"sm ") : _(
"obj"));
680 if (r_info.is_submap)
700 if (task == TASK_NULL)
712 if (task == TASK_NULL)
726 val =
expr->evaluate ();
734 error (_(
"Inferior not available"));
746 gdb_printf (_(
"%d exceptions:\n"), info->count);
747 for (i = 0; i < info->count; i++)
749 exception_mask_t mask = info->masks[i];
751 gdb_printf (_(
"port 0x%04x, behavior: "), info->ports[i]);
752 switch (info->behaviors[i])
754 case EXCEPTION_DEFAULT:
757 case EXCEPTION_STATE:
760 case EXCEPTION_STATE_IDENTITY:
767 if (mask & EXC_MASK_BAD_ACCESS)
769 if (mask & EXC_MASK_BAD_INSTRUCTION)
771 if (mask & EXC_MASK_ARITHMETIC)
773 if (mask & EXC_MASK_EMULATION)
775 if (mask & EXC_MASK_SOFTWARE)
777 if (mask & EXC_MASK_BREAKPOINT)
779 if (mask & EXC_MASK_SYSCALL)
781 if (mask & EXC_MASK_MACH_SYSCALL)
783 if (mask & EXC_MASK_RPC_ALERT)
785 if (mask & EXC_MASK_CRASH)
797 info.count =
sizeof (info.ports) /
sizeof (info.ports[0]);
801 if (strcmp (
args,
"saved") == 0)
811 else if (strcmp (
args,
"host") == 0)
814 kret = host_get_exception_ports
816 &info.count, info.ports, info.behaviors, info.flavors);
821 error (_(
"Parameter is saved, host or none"));
833 kret = task_get_exception_ports
834 (
priv->task, EXC_MASK_ALL, info.masks,
835 &info.count, info.ports, info.behaviors, info.flavors);
846 _(
"Get list of tasks in system."));
848 _(
"Get list of ports in a task."));
850 _(
"Get info on a specific port."));
852 _(
"Get info on a specific task."));
854 _(
"Get list of threads in a task."));
856 _(
"Get info on a specific thread."));
859 _(
"Get information on all mach region for the task."));
861 _(
"Get information on all mach sub region for the task."));
863 _(
"Get information on mach region at given address."));
866 _(
"Disp mach exceptions."));
struct gdbarch * target_gdbarch(void)
std::unique_ptr< private_inferior > priv
const std::string & args() const
inf_threads_range threads()
void field_core_addr(const char *fldname, struct gdbarch *gdbarch, CORE_ADDR address)
void field_string(const char *fldname, const char *string, const ui_file_style &style=ui_file_style())
void field_signed(const char *fldname, LONGEST value)
void text(const char *string)
void table_header(int width, ui_align align, const std::string &col_name, const std::string &col_hdr)
struct cmd_list_element * add_info(const char *name, cmd_simple_func_ftype *fun, const char *doc)
#define port_type_array_t
#define PRINT_FIELD(structure, field)
static void info_mach_regions_command(const char *args, int from_tty)
static const char * unparse_share_mode(unsigned char p)
static void darwin_debug_regions(task_t task, mach_vm_address_t address, int max)
static void darwin_debug_region(task_t task, mach_vm_address_t address)
static void info_mach_thread_command(const char *args, int from_tty)
static void info_mach_region_command(const char *exp, int from_tty)
static task_t get_task_from_args(const char *args)
static const char * unparse_user_tag(unsigned int tag)
static const char * unparse_inheritance(vm_inherit_t i)
#define port_name_array_t
static void darwin_debug_port_info(task_t task, mach_port_t port)
static void disp_exception(const darwin_exception_info *info)
static void info_mach_port_command(const char *args, int from_tty)
static void info_mach_regions_recurse_command(const char *args, int from_tty)
void _initialize_darwin_info_commands()
static const char * unparse_protection(vm_prot_t p)
static void info_mach_task_command(const char *args, int from_tty)
static void info_mach_threads_command(const char *args, int from_tty)
static void info_mach_exceptions_command(const char *args, int from_tty)
static void info_mach_ports_command(const char *args, int from_tty)
#define PRINT_TV_FIELD(structure, field)
static void info_mach_tasks_command(const char *args, int from_tty)
static void darwin_debug_regions_recurse(task_t task)
#define CHECK_ARGS(what, args)
mach_port_t darwin_host_self
mach_port_t darwin_ex_port
mach_port_t darwin_port_set
static darwin_inferior * get_darwin_inferior(inferior *inf)
#define MACH_CHECK_ERROR(ret)
std::unique_ptr< expression > expression_up
expression_up parse_expression(const char *, innermost_block_tracker *=nullptr, parser_flags flags=0)
int gdbarch_addr_bit(struct gdbarch *gdbarch)
int thread_count(process_stratum_target *proc_target)
#define TYPE_IS_REFERENCE(t)
mach_port_t kern_return_t mach_port_t mach_msg_type_name_t msgportsPoly 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
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
struct inferior * current_inferior(void)
struct type * type() const
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
void gdb_printf(struct ui_file *stream, const char *format,...)
struct value * value_ind(struct value *arg1)
CORE_ADDR value_as_address(struct value *val)