Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 142 additions & 0 deletions pykdebugparser/trace_handlers/mach.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,22 @@ def __str__(self):
return f'INTERRUPT, pc: {hex(self.pc)}, is_user: {self.is_user}, type: {InterruptType(self.type).name}'


@dataclass
class UserInstrAbortLowerElExcArm:
ktraces: List
esr: int
far: int
pc: int

def __str__(self):
esr_class = self.esr >> 26
try:
esr_class = ExceptionSyndromeRegisterClass(esr_class).name
except ValueError:
pass
return f'User_Instr_Abort_Lower_EL_Exc_ARM, class: {esr_class}, far: {hex(self.far)}, pc: {hex(self.pc)}'


@dataclass
class UserDataAbortLowerElExcArm:
ktraces: List
Expand All @@ -328,6 +344,17 @@ def __str__(self):
return f'User_Data_Abort_Lower_EL_Exc_ARM, class: {esr_class}, far: {hex(self.far)}, pc: {hex(self.pc)}'


@dataclass
class DecrTrap:
ktraces: List
latency: int
pc: int
user_mode: bool

def __str__(self):
return f'DecrTrap, latency: {self.latency}, pc: {hex(self.pc)}, user_mode: {self.user_mode}'


@dataclass
class DecrSet:
ktraces: List
Expand Down Expand Up @@ -489,6 +516,33 @@ def __str__(self):
return f'mach_port_destruct({self.target}, {hex(self.name)}, {hex(self.srdelta)}, {hex(self.guard)})'


@dataclass
class MachReplyPort:
ktraces: List
result: int

def __str__(self):
return f'mach_reply_port(), result: {hex(self.result)}'


@dataclass
class MachThreadSelf:
ktraces: List
result: int

def __str__(self):
return f'mach_thread_self(), result: {hex(self.result)}'


@dataclass
class TaskSelf:
ktraces: List
result: int

def __str__(self):
return f'task_self(), result: {self.result}'


@dataclass
class HostSelf:
ktraces: List
Expand Down Expand Up @@ -553,6 +607,17 @@ def __str__(self):
return f'mach_port_guard({self.target}, {hex(self.name)}, {hex(self.guard)}, {str(self.strict).lower()})'


@dataclass
class MachPortUnguard:
ktraces: List
target: int
name: int
guard: int

def __str__(self):
return f'mach_port_unguard({self.target}, {hex(self.name)}, {hex(self.guard)})'


@dataclass
class MachGenerateActivityId:
ktraces: List
Expand Down Expand Up @@ -632,6 +697,15 @@ def __str__(self):
return f'mach_port_request_notification({self.task}, {hex(self.name)}, {hex(self.msgid)}, {self.sync})'


@dataclass
class MachTimebaseInfo:
ktraces: List
info: int

def __str__(self):
return f'mach_timebase_info({hex(self.info)})'


@dataclass
class MachWaitUntil:
ktraces: List
Expand Down Expand Up @@ -704,6 +778,28 @@ def __str__(self):
return f'iokit_user_client({hex(self.user_client_ref)}, {self.index}, {hex(self.p1)}, {hex(self.p2)})'


@dataclass
class ThreadSetVoucher:
ktraces: List
tid: int
port: int
voucher: int
persona_id: int

def __str__(self):
return (f'thread_set_voucher, tid: {self.tid}, port: {hex(self.port)}, voucher: {hex(self.voucher)}, '
f'persona_id: {self.persona_id}')


@dataclass
class MachPageout:
ktraces: List
size: int

def __str__(self):
return f'MACH_Pageout, size: {hex(self.size)}'


@dataclass
class MachVmfault:
ktraces: List
Expand Down Expand Up @@ -905,6 +1001,10 @@ def handle_user_svc64_exc_arm(parser, events):
return UserSvc64ExcArm(events, *events[0].values[:3])


def handle_user_instr_abort_lower_el_exc_arm(parser, events):
return UserInstrAbortLowerElExcArm(events, *events[0].values[:3])


def handle_user_data_abort_lower_el_exc_arm(parser, events):
args = events[0].values
return UserDataAbortLowerElExcArm(events, args[0], args[1], args[2])
Expand All @@ -915,6 +1015,11 @@ def handle_interrupt(parser, events):
return Interrupt(events, args[1], bool(args[2]), args[3])


def handle_decr_trap(parser, events):
args = events[0].values
return DecrTrap(events, ctypes.c_int64(args[0]).value, args[1], bool(args[2]))


def handle_decr_set(parser, events):
args = events[0].values
return DecrSet(events, args[0], args[2], args[3])
Expand Down Expand Up @@ -974,6 +1079,18 @@ def handle_msc_mach_port_destruct_trap(parser, events):
return MachPortDestruct(events, *events[0].values)


def handle_msc_mach_reply_port(parser, events):
return MachReplyPort(events, events[-1].values[0])


def handle_msc_thread_self_trap(parser, events):
return MachThreadSelf(events, events[-1].values[0])


def handle_msc_task_self_port(parser, events):
return TaskSelf(events, events[-1].values[0])


def handle_msc_host_self_port(parser, events):
return HostSelf(events, events[-1].values[0])

Expand All @@ -1000,6 +1117,10 @@ def handle_msc_mach_port_guard_trap(parser, events):
return MachPortGuard(events, *events[0].values[:3], bool(events[0].values[3]))


def handle_msc_mach_port_unguard_trap(parser, events):
return MachPortUnguard(events, *events[0].values[:3])


def handle_msc_mach_generate_activity_id(parser, events):
return MachGenerateActivityId(events, *events[0].values[:3])

Expand Down Expand Up @@ -1029,6 +1150,10 @@ def handle_msc_mach_port_request_notification_trap(parser, events):
return MachPortRequestNotification(events, *events[0].values)


def handle_msc_mach_timebase_info(parser, events):
return MachTimebaseInfo(events, events[0].values[0])


def handle_msc_mach_wait_until(parser, events):
return MachWaitUntil(events, events[0].values[0])

Expand Down Expand Up @@ -1058,6 +1183,14 @@ def handle_msc_iokit_user_client(parser, events):
return IokitUserClient(events, *events[0].values)


def handle_mach_thread_set_voucher(parser, events):
return ThreadSetVoucher(events, *events[0].values)


def handle_mach_pageout(parser, events):
return MachPageout(events, events[0].values[0])


def handle_mach_vmfault(parser, events):
args = events[0].values
is_kernel = bool(args[2])
Expand Down Expand Up @@ -1136,8 +1269,10 @@ def handle_sched_clutch_tg_bucket_pri(parser, events):
'Kernel_Uncategorized_Exc_ARM': handle_kernel_uncategorized_exc_arm,
'Kernel_Data_Abort_Same_EL_Exc_ARM': handle_kernel_data_abort_same_el_exc_arm,
'User_SVC64_Exc_ARM': handle_user_svc64_exc_arm,
'User_Instr_Abort_Lower_EL_Exc_ARM': handle_user_instr_abort_lower_el_exc_arm,
'User_Data_Abort_Lower_EL_Exc_ARM': handle_user_data_abort_lower_el_exc_arm,
'INTERRUPT': handle_interrupt,
'DecrTrap': handle_decr_trap,
'DecrSet': handle_decr_set,
'MSC_mach_vm_allocate_trap': handle_msc_mach_vm_allocate_trap,
'MSC_kern_mach_vm_purgable_control_trap': handle_msc_kern_mach_vm_purgable_control_trap,
Expand All @@ -1152,26 +1287,33 @@ def handle_sched_clutch_tg_bucket_pri(parser, events):
'MSC_mach_port_extract_member_trap': handle_msc_mach_port_extract_member_trap,
'MSC_mach_port_construct_trap': handle_msc_mach_port_construct_trap,
'MSC_mach_port_destruct_trap': handle_msc_mach_port_destruct_trap,
'MSC_mach_reply_port': handle_msc_mach_reply_port,
'MSC_thread_self_trap': handle_msc_thread_self_trap,
'MSC_task_self_trap': handle_msc_task_self_port,
'MSC_host_self_trap': handle_msc_host_self_port,
'MSC_semaphore_signal_trap': handle_msc_semaphore_signal_trap,
'MSC_semaphore_wait_trap': handle_msc_semaphore_wait_trap,
'MSC_semaphore_timedwait_trap': handle_msc_semaphore_timedwait_trap,
'MSC_mach_port_get_attributes_trap': handle_msc_mach_port_get_attributes_trap,
'MSC_mach_port_guard_trap': handle_msc_mach_port_guard_trap,
'MSC_mach_port_unguard_trap': handle_msc_mach_port_unguard_trap,
'MSC_mach_generate_activity_id': handle_msc_mach_generate_activity_id,
'MSC_mach_msg2_trap': handle_msc_mach_msg2_trap,
'MSC_thread_get_special_reply_port': handle_msc_thread_get_special_reply_port,
'MSC_thread_switch': handle_msc_thread_switch,
'MSC_host_create_mach_voucher_trap': handle_msc_host_create_mach_voucher_trap,
'MSC_mach_port_type_trap': handle_msc_mach_port_type_trap,
'MSC_mach_port_request_notification_trap': handle_msc_mach_port_request_notification_trap,
'MSC_mach_timebase_info': handle_msc_mach_timebase_info,
'MSC_mach_wait_until': handle_msc_mach_wait_until,
'MSC_mk_timer_create': handle_msc_mk_timer_create,
'MSC_mk_timer_destroy': handle_msc_mk_timer_destroy,
'MSC_mk_timer_arm': handle_msc_mk_timer_arm,
'MSC_mk_timer_cancel': handle_msc_mk_timer_cancel,
'MSC_mk_timer_arm_leeway': handle_msc_mk_timer_arm_leeway,
'MSC_iokit_user_client': handle_msc_iokit_user_client,
'MACH_thread_set_voucher': handle_mach_thread_set_voucher,
'MACH_Pageout': handle_mach_pageout,
'MACH_vmfault': handle_mach_vmfault,
'RealFaultAddressInternal': partial(handle_real_fault_address, RealFaultAddressInternal),
'RealFaultAddressExternal': partial(handle_real_fault_address, RealFaultAddressExternal),
Expand Down
97 changes: 97 additions & 0 deletions tests/traces/test_mach.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,21 @@ def test_user_data_abort_lower_el_exc_arm(traces_parser):
assert abort.pc == 6762552612


def test_decr_trap(traces_parser):
events = [
Kevent(timestamp=5453855881172,
data=(b'\xe3\xff\xff\xff\xff\xff\xff\xff\xc4\x9dt\xac\x01\x00\x00\x00\x01\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(18446744073709551587, 7188291012, 1, 0), tid=941745, debugid=17367040, eventid=17367040,
func_qualifier=0)
]
ret = list(traces_parser.feed_generator(events))
trace = ret[0]
assert trace.latency == -29
assert trace.pc == 0x1ac749dc4
assert trace.user_mode


def test_decr_set(traces_parser):
events = [
Kevent(timestamp=10041923525014,
Expand Down Expand Up @@ -153,6 +168,88 @@ def test_msc_mach_vm_map_trap(traces_parser):
assert mach.mask == 0


def test_msc_mach_reply_port(traces_parser):
events = [
Kevent(timestamp=5453890497755,
data=(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(0, 0, 0, 0), tid=941818, debugid=17563753, eventid=17563752, func_qualifier=1),
Kevent(timestamp=5453890497771,
data=(b'\x03\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(771, 0, 0, 0), tid=941818, debugid=17563754, eventid=17563752, func_qualifier=2)
]
ret = list(traces_parser.feed_generator(events))
mach = ret[0]
assert mach.result == 0x303


def test_msc_thread_self_trap(traces_parser):
events = [
Kevent(timestamp=5453890560892,
data=(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(0, 0, 0, 0), tid=941536, debugid=17563757, eventid=17563756, func_qualifier=1),
Kevent(timestamp=5453890560912,
data=(b'\x0b\xa6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(42507, 0, 0, 0), tid=941536, debugid=17563758, eventid=17563756, func_qualifier=2)
]
ret = list(traces_parser.feed_generator(events))
mach = ret[0]
assert mach.result == 0xa60b


def test_msc_task_self_trap(traces_parser):
events = [
Kevent(timestamp=5453890600244,
data=(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(0, 0, 0, 0), tid=941827, debugid=17563761, eventid=17563760, func_qualifier=1),
Kevent(timestamp=5453890600265,
data=(b'\x03\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(515, 0, 0, 0), tid=941827, debugid=17563762, eventid=17563760, func_qualifier=2)
]
ret = list(traces_parser.feed_generator(events))
mach = ret[0]
assert mach.result == 515


def test_msc_mach_port_unguard_trap(traces_parser):
events = [
Kevent(timestamp=5453890742696,
data=(b'\x03\x02\x00\x00\x00\x00\x00\x00\x03\x8e\n\x00\x00\x00\x00\x000j\xd2G\x01\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(515, 691715, 5499939376, 0), tid=941734, debugid=17563817, eventid=17563816, func_qualifier=1),
Kevent(timestamp=5453890742704,
data=(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(0, 0, 0, 0), tid=941734, debugid=17563818, eventid=17563816, func_qualifier=2)
]
ret = list(traces_parser.feed_generator(events))
mach = ret[0]
assert mach.target == 515
assert mach.name == 0xa8e03
assert mach.guard == 0x147d26a30


def test_msc_mach_timebase_info(traces_parser):
events = [
Kevent(timestamp=5453890643526,
data=(b'\xc4F\n\x0e\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(8825489092, 0, 0, 0), tid=941827, debugid=17564005, eventid=17564004, func_qualifier=1),
Kevent(timestamp=5453890643529,
data=(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'),
values=(0, 0, 0, 0), tid=941827, debugid=17564006, eventid=17564004, func_qualifier=2)
]
ret = list(traces_parser.feed_generator(events))
mach = ret[0]
assert mach.info == 0x20e0a46c4


def test_mach_vmfault(traces_parser):
events = [
Kevent(timestamp=10533581994269,
Expand Down