38 #include <sys/sysctl.h>
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>
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); \
55 #define PRINT_FIELD(structure, field) \
56 printf_unfiltered(_(#field":\t%#lx\n"), (unsigned long) (structure)->field)
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)
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
74 struct kinfo_proc *procInfo;
76 sysControl[0] = CTL_KERN;
77 sysControl[1] = KERN_PROC;
78 sysControl[2] = KERN_PROC_ALL;
80 sysctl (sysControl, 3, NULL, &length, NULL, 0);
81 procInfo = (
struct kinfo_proc *)
xmalloc (length);
82 sysctl (sysControl, 3, procInfo, &length, NULL, 0);
84 count = (length /
sizeof (
struct kinfo_proc));
86 for (index = 0; index < count; ++index)
94 if (KERN_SUCCESS == result)
97 procInfo[index].kp_proc.p_comm,
98 procInfo[index].kp_proc.p_pid, taskPort);
103 procInfo[index].kp_proc.p_comm,
104 procInfo[index].kp_proc.p_pid);
117 if (args == NULL || *args == 0)
123 if (strcmp (args,
"gdb") == 0)
124 return mach_task_self ();
125 task = strtoul (args, &eptr, 0);
139 struct task_basic_info basic;
140 struct task_events_info events;
141 struct task_thread_times_info thread_times;
144 kern_return_t result;
145 unsigned int info_count;
149 if (task == TASK_NULL)
153 info_count = TASK_BASIC_INFO_COUNT;
154 result = task_info (task,
156 (task_info_t) & task_info_data.basic, &info_count);
159 PRINT_FIELD (&task_info_data.basic, suspend_count);
161 PRINT_FIELD (&task_info_data.basic, resident_size);
165 info_count = TASK_EVENTS_INFO_COUNT;
166 result = task_info (task,
168 (task_info_t) & task_info_data.events, &info_count);
174 PRINT_FIELD (&task_info_data.events, reactivations);
178 PRINT_FIELD (&task_info_data.events, messages_sent);
179 PRINT_FIELD (&task_info_data.events, messages_received);
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,
196 unsigned int name_count, type_count;
197 kern_return_t result;
202 if (task == TASK_NULL)
205 result = mach_port_names (task, &names, &name_count, &types, &type_count);
212 for (index = 0; index < name_count; ++index)
214 mach_port_t port = names[index];
218 mach_port_type_t
type;
220 mach_port_right_t right;
222 static struct type_descr descrs[] =
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}
232 for (j = 0; j <
sizeof(descrs) /
sizeof(*descrs); j++)
233 if (types[index] & descrs[j].
type)
235 mach_port_urefs_t ref;
239 ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
240 if (ret != KERN_SUCCESS)
277 if (inf->
priv->threads)
281 inf->
priv->threads, k, t);
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)));
307 mach_port_status_t
status;
308 mach_msg_type_number_t
len =
sizeof (
status);
310 kret = mach_port_get_attributes
311 (task, port, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, &len);
315 (
unsigned long) task);
335 sscanf (args,
"0x%x 0x%x", &task, &port);
343 thread_array_t threads;
345 kern_return_t result;
350 if (task == TASK_NULL)
353 result = task_threads (task, &threads, &thread_count);
360 mach_port_deallocate (
task_self (), threads[i]);
363 vm_deallocate (
task_self (), (vm_address_t) threads,
364 (thread_count *
sizeof (
thread_t)));
372 struct thread_basic_info basic;
376 kern_return_t result;
377 unsigned int info_count;
380 sscanf (args,
"0x%x", &thread);
383 info_count = THREAD_BASIC_INFO_COUNT;
386 (thread_info_t) & thread_info_data.basic,
392 PRINT_FIELD (&thread_info_data.basic, system_time);
397 PRINT_FIELD (&thread_info_data.basic, suspend_count);
412 case VM_PROT_READ | VM_PROT_WRITE:
414 case VM_PROT_EXECUTE:
416 case VM_PROT_EXECUTE | VM_PROT_READ:
418 case VM_PROT_EXECUTE | VM_PROT_WRITE:
420 case VM_PROT_EXECUTE | VM_PROT_WRITE | VM_PROT_READ:
432 case VM_INHERIT_SHARE:
434 case VM_INHERIT_COPY:
436 case VM_INHERIT_NONE:
457 return _(
"true-shrd");
458 case SM_PRIVATE_ALIASED:
459 return _(
"prv-alias");
460 case SM_SHARED_ALIASED:
461 return _(
"shr-alias");
474 case VM_MEMORY_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");
484 case VM_MEMORY_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:
494 case VM_MEMORY_STACK:
496 case VM_MEMORY_GUARD:
498 case VM_MEMORY_SHARED_PMAP:
499 return _(
"shared_pmap");
500 case VM_MEMORY_DYLIB:
502 case VM_MEMORY_APPKIT:
504 case VM_MEMORY_FOUNDATION:
505 return _(
"foundation");
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;
519 mach_port_t object_name;
520 mach_msg_type_number_t count;
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)
533 memcpy (&prev_info, &info,
sizeof (vm_region_basic_info_data_64_t));
534 prev_address = address;
543 address = prev_address + prev_size;
551 count = VM_REGION_BASIC_INFO_COUNT_64;
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)
562 if (address != prev_address + prev_size)
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))
580 prev_info.shared ?
_(
"shrd") :
_(
"priv"),
581 prev_info.reserved ?
_(
"reserved") :
_(
"not-rsvd"));
588 prev_address = address;
590 memcpy (&prev_info, &info,
sizeof (vm_region_basic_info_data_64_t));
601 if ((max > 0) && (num_printed >= max))
612 mach_vm_address_t r_addr;
613 mach_vm_address_t r_start;
614 mach_vm_size_t r_size;
616 mach_msg_type_number_t r_info_size;
617 vm_region_submap_short_info_data_64_t r_info;
652 r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
654 kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth,
655 (vm_region_recurse_info_t) &r_info,
657 if (kret != KERN_SUCCESS)
673 r_info.is_submap ?
_(
"sm ") :
_(
"obj"));
685 if (r_info.is_submap)
707 if (task == TASK_NULL)
719 if (task == TASK_NULL)
742 error (
_(
"Inferior not available"));
754 for (i = 0; i < info->
count; i++)
756 exception_mask_t mask = info->
masks[i];
761 case EXCEPTION_DEFAULT:
764 case EXCEPTION_STATE:
767 case EXCEPTION_STATE_IDENTITY:
774 if (mask & EXC_MASK_BAD_ACCESS)
776 if (mask & EXC_MASK_BAD_INSTRUCTION)
778 if (mask & EXC_MASK_ARITHMETIC)
780 if (mask & EXC_MASK_EMULATION)
782 if (mask & EXC_MASK_SOFTWARE)
784 if (mask & EXC_MASK_BREAKPOINT)
786 if (mask & EXC_MASK_SYSCALL)
788 if (mask & EXC_MASK_MACH_SYSCALL)
790 if (mask & EXC_MASK_RPC_ALERT)
792 if (mask & EXC_MASK_CRASH)
810 if (strcmp (args,
"saved") == 0)
817 else if (strcmp (args,
"host") == 0)
820 kret = host_get_exception_ports
827 error (
_(
"Parameter is saved, host or none"));
837 kret = task_get_exception_ports
852 _(
"Get list of tasks in system."));
854 _(
"Get list of ports in a task."));
856 _(
"Get info on a specific port."));
858 _(
"Get info on a specific task."));
860 _(
"Get list of threads in a task."));
862 _(
"Get info on a specific thread."));
865 _(
"Get information on all mach region for the task."));
867 _(
"Get information on all mach sub region for the task."));
869 _(
"Get information on mach region at given address."));
872 _(
"Disp mach exceptions."));
struct gdbarch * target_gdbarch(void)
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]
void ui_out_field_int(struct ui_out *uiout, const char *fldname, int value)
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
static const char * unparse_inheritance(vm_inherit_t i)
struct cleanup * make_cleanup_ui_out_table_begin_end(struct ui_out *ui_out, int nr_cols, int nr_rows, const char *tblid)
static const char * unparse_user_tag(unsigned int tag)
static void info_mach_port_command(char *args, int from_tty)
int ui_out_is_mi_like_p(struct ui_out *uiout)
exception_mask_t masks[EXC_TYPES_COUNT]
static void info_mach_threads_command(char *args, int from_tty)
struct value * value_ind(struct value *arg1)
exception_behavior_t behaviors[EXC_TYPES_COUNT]
mach_port_t darwin_ex_port
void ui_out_text(struct ui_out *uiout, const char *string)
mach_port_t ports[EXC_TYPES_COUNT]
void printf_filtered(const char *format,...)
#define MACH_CHECK_ERROR(ret)
const char * paddress(struct gdbarch *gdbarch, CORE_ADDR addr)
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
struct value * evaluate_expression(struct expression *exp)
#define VEC_iterate(T, V, I, P)
static void disp_exception(const darwin_exception_info *info)
static const char * unparse_protection(vm_prot_t p)
void initialize_file_ftype(void)
struct cleanup * make_cleanup_ui_out_tuple_begin_end(struct ui_out *uiout, const char *id)
mach_port_t darwin_host_self
static void darwin_debug_regions_recurse(task_t task)
#define port_type_array_t
#define CHECK_ARGS(what, args)
darwin_exception_info exception_info
mach_port_t mach_port_t name mach_port_t mach_port_t name error_t int status
static const char * unparse_share_mode(unsigned char p)
static void info_mach_exceptions_command(char *args, int from_tty)
struct cmd_list_element * add_info(const char *name, cmd_cfunc_ftype *fun, const char *doc)
#define PRINT_TV_FIELD(structure, field)
int gdbarch_addr_bit(struct gdbarch *gdbarch)
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,...)
struct expression * parse_expression(const char *)
static void info_mach_regions_command(char *args, int from_tty)
#define port_name_array_t
static void info_mach_task_command(char *args, int from_tty)
mach_port_t darwin_port_set
#define TYPE_CODE(thistype)
static void info_mach_regions_recurse_command(char *args, int from_tty)
static void darwin_debug_regions(task_t task, mach_vm_address_t address, int max)
void ui_out_table_header(struct ui_out *uiout, int width, enum ui_align alignment, const char *col_name, const char *colhdr)
struct inferior * current_inferior(void)
void ui_out_field_core_addr(struct ui_out *uiout, const char *fldname, struct gdbarch *gdbarch, CORE_ADDR address)
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)
struct private_inferior * priv
CORE_ADDR value_as_address(struct value *val)
void ui_out_field_string(struct ui_out *uiout, const char *fldname, const char *string)
void ui_out_table_body(struct ui_out *uiout)
struct ui_out * current_uiout
mach_msg_type_number_t count
void error(const char *fmt,...)
void do_cleanups(struct cleanup *old_chain)
static task_t get_task_from_args(char *args)
const ULONGEST const LONGEST len