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