1from __future__ import absolute_import, print_function 2 3from builtins import range 4 5from xnu import * 6import sys, shlex 7from utils import * 8from waitq import * 9import xnudefines 10 11@lldb_type_summary(['struct turnstile *']) 12@header("{0: <20s} {1: <5s} {2: <20s} {3: <8s} {4: <8s} {5: <23s} {6: <20s} {7: <16s} {8: <20s} {9: <20s}".format("turnstile", "pri", "waitq", "type", "state", "inheritor", "proprietor", "gen count", "thread", "prev_thread")) 13def GetTurnstileSummary(turnstile): 14 """ Summarizes the turnstile 15 params: turnstile = value of the object of type struct turnstile * 16 returns: String with summary of the type. 17 """ 18 19 type_and_gencount = Cast(addressof(turnstile.ts_type_gencount), 'union turnstile_type_gencount *') 20 turnstile_type = "" 21 22 if type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_NONE'): 23 turnstile_type = "none " 24 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_KERNEL_MUTEX'): 25 turnstile_type = "knl_mtx" 26 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_ULOCK'): 27 turnstile_type = "ulock " 28 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_PTHREAD_MUTEX'): 29 turnstile_type = "pth_mtx" 30 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_SYNC_IPC'): 31 turnstile_type = "syn_ipc" 32 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_WORKLOOPS'): 33 turnstile_type = "kqwl " 34 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_WORKQS'): 35 turnstile_type = "workq " 36 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_KNOTE'): 37 turnstile_type = "knote " 38 elif type_and_gencount.ts_type == GetEnumValue('turnstile_type_t::TURNSTILE_SLEEP_INHERITOR'): 39 turnstile_type = "slp_inh" 40 41 turnstile_state = "" 42 if turnstile.ts_state & 0x1: 43 turnstile_state += "T" 44 elif turnstile.ts_state & 0x2: 45 turnstile_state += "F" 46 elif turnstile.ts_state & 0x4: 47 turnstile_state += "H" 48 elif turnstile.ts_state & 0x8: 49 turnstile_state += "P" 50 51 if turnstile.ts_inheritor_flags & 0x4: 52 inheritor_type = "th" 53 elif turnstile.ts_inheritor_flags & 0x8: 54 inheritor_type = "ts" 55 elif turnstile.ts_inheritor_flags & 0x40: 56 inheritor_type = "wq" 57 else: 58 inheritor_type = "--" 59 60 format_str = "{0: <#020x} {1: <5d} {2: <#020x} {3: <8s} {4: <8s} {6: <2s}:{5: <#020x} {7: <#020x} {8: <16d}" 61 out_string = format_str.format(turnstile, turnstile.ts_priority, addressof(turnstile.ts_waitq), 62 turnstile_type, turnstile_state, turnstile.ts_waitq.waitq_inheritor, inheritor_type, 63 turnstile.ts_proprietor, type_and_gencount.ts_gencount) 64 65 #if DEVELOPMENT 66 format_str = " {0: <#020x} {1: <#020x}" 67 if hasattr(turnstile, 'ts_thread'): 68 out_string += format_str.format(turnstile.ts_thread, turnstile.ts_prev_thread) 69 #endif 70 return out_string 71 72def PrintTurnstile(turnstile): 73 """ print turnstile and it's free list. 74 params: 75 turnstile - turnstile to print 76 """ 77 print(GetTurnstileSummary(turnstile)) 78 79 """ print turnstile freelist if its not on a thread or freelist """ 80 if turnstile.ts_state & 0x3 == 0: 81 needsHeader = True 82 for free_turnstile in IterateListEntry(turnstile.ts_free_turnstiles, 'struct turnstile *', 'ts_free_elm', 's'): 83 if needsHeader: 84 print(" Turnstile free List") 85 header_str = " " + GetTurnstileSummary.header 86 print(header_str) 87 needsHeader = False 88 print(" " + GetTurnstileSummary(free_turnstile)) 89 print("") 90 return 91 92# Macro: showturnstile 93@lldb_command('showturnstile') 94def ShowTurnstile(cmd_args=None, cmd_options={}): 95 """ show the turnstile and all free turnstiles hanging off the turnstile. 96 Usage: (lldb)showturnstile <struct turnstile *> 97 """ 98 if not cmd_args: 99 raise ArgumentError("Please provide arguments") 100 101 turnstile = kern.GetValueFromAddress(cmd_args[0], 'struct turnstile *') 102 print(GetTurnstileSummary.header) 103 PrintTurnstile(turnstile) 104 return 105# EndMacro: showturnstile 106 107@lldb_command('showturnstilehashtable') 108def ShowTurnstileHashTable(cmd_args=None, cmd_options={}): 109 """ show the global hash table for turnstiles. 110 Usage: (lldb)showturnstilehashtable 111 """ 112 print(GetTurnstileSummary.header) 113 turnstile_htable_buckets = kern.globals.ts_htable_buckets 114 for index in range(0, turnstile_htable_buckets): 115 turnstile_bucket = GetObjectAtIndexFromArray(kern.globals.turnstile_htable, index) 116 for turnstile in IterateQueue(turnstile_bucket.ts_ht_bucket_list, 'struct turnstile *', 'ts_htable_link'): 117 PrintTurnstile(turnstile) 118 return True 119 120#if DEVELOPMENT 121# Macro: showallturnstiles 122@lldb_command('showallturnstiles') 123def ShowAllTurnstiles(cmd_args=None, cmd_options={}): 124 """ A DEVELOPMENT macro that walks the list of all allocated turnstile objects 125 and prints them. 126 usage: (lldb) showallturnstiles 127 """ 128 if not hasattr(kern.globals, 'turnstiles_list'): 129 print("It seems you are running a build of kernel that does not have the list of all turnstiles.") 130 return False 131 print(GetTurnstileSummary.header) 132 for turnstile in IterateQueue(kern.globals.turnstiles_list, 'struct turnstile *', 'ts_global_elm'): 133 PrintTurnstile(turnstile) 134 return True 135# EndMacro showallturnstiles 136 137# Macro: showallbusyturnstiles 138@lldb_command('showallbusyturnstiles') 139def ShowAllTurnstiles(cmd_args=None, cmd_options={}): 140 """ A DEVELOPMENT macro that walks the list of all allocated turnstile objects 141 and prints them. 142 usage: (lldb) showallbusyturnstiles 143 """ 144 if not hasattr(kern.globals, 'turnstiles_list'): 145 print("It seems you are running a build of kernel that does not have the list of all turnstiles.") 146 return False 147 print(GetTurnstileSummary.header) 148 for turnstile in IterateQueue(kern.globals.turnstiles_list, 'struct turnstile *', 'ts_global_elm'): 149 if turnstile.ts_state & 0x3 == 0: 150 PrintTurnstile(turnstile) 151 return True 152# EndMacro showallbusyturnstiles 153 154@lldb_command('showthreadbaseturnstiles', fancy=True) 155def ShowThreadInheritorBase(cmd_args=None, cmd_options={}, O=None): 156 """ A DEVELOPMENT macro that walks the list of userspace turnstiles pushing on a thread 157 and prints them. 158 usage: (lldb) showthreadbaseturnstiles thread_pointer 159 """ 160 if not cmd_args: 161 return O.error('invalid thread pointer') 162 163 thread = kern.GetValueFromAddress(cmd_args[0], "thread_t") 164 with O.table(GetTurnstileSummary.header): 165 for turnstile in IterateSchedPriorityQueue(thread.base_inheritor_queue, 'struct turnstile', 'ts_inheritor_links'): 166 PrintTurnstile(turnstile) 167 168@lldb_command('showthreadschedturnstiles', fancy=True) 169def ShowThreadInheritorSched(cmd_args=None, cmd_options={}, O=None): 170 """ A DEVELOPMENT macro that walks the list of kernelspace turnstiles pushing on a thread 171 and prints them. 172 usage: (lldb) showthreadschedturnstiles thread_pointer 173 """ 174 if not cmd_args: 175 return O.error('invalid thread pointer') 176 177 thread = kern.GetValueFromAddress(cmd_args[0], "thread_t") 178 with O.table(GetTurnstileSummary.header): 179 for turnstile in IterateSchedPriorityQueue(thread.sched_inheritor_queue, 'struct turnstile', 'ts_inheritor_links'): 180 PrintTurnstile(turnstile) 181#endif 182