xref: /xnu-8019.80.24/tools/lldbmacros/turnstile.py (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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