1""" Please make sure you read the README file COMPLETELY BEFORE reading anything below. 2 It is very critical that you read coding guidelines in Section E in README file. 3""" 4from xnu import * 5import sys, shlex 6from utils import * 7from process import * 8import xnudefines 9 10@header("{0: <20s} {1: <6s} {2: <6s} {3: <10s} {4: <15s}".format("task", "pid", '#acts', "tablesize", "command")) 11def GetTaskIPCSummary(task): 12 """ Display a task's ipc summary. 13 params: 14 task : core.value represeting a Task in kernel 15 returns 16 str - string of ipc info for the task 17 """ 18 out_string = '' 19 format_string = "{0: <#020x} {1: <6d} {2: <6d} {3: <10d} {4: <15s}" 20 pval = Cast(task.bsd_info, 'proc *') 21 table_size = int(task.itk_space.is_table_size) 22 proc_name = str(pval.p_comm) 23 out_string += format_string.format(task, pval.p_pid, task.thread_count, table_size, proc_name) 24 return out_string 25 26@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <4s} {5: <20s} {6: <4s}\n".format( 27 "port", "mqueue", "recvname", "flags", "refs", "recvname", "dest")) 28def GetPortSummary(port, show_kmsg_summary=True, prefix=""): 29 """ Display a port's summary 30 params: 31 port : core.value representing a port in the kernel 32 returns 33 str : string of ipc info for the given port 34 """ 35 out_string = "" 36 portp = Cast(port, 'struct ipc_port *') 37 destspacep = kern.GetValueFromAddress(0, 'struct ipc_space *') 38 spacep = portp.data.receiver 39 format_string = "{0: #019x} {1: #019x} {2: <8s} {3: #011x} {4: <5s} {5: #05x} {6: #019x} {7: <16s}\n" 40 if portp.ip_object.io_bits & 0x80000000: 41 out_string += prefix + format_string.format( 42 unsigned(portp), addressof(portp.ip_messages), ' '*8, 43 unsigned(portp.ip_messages.data.port.receiver_name), 44 "APort", portp.ip_object.io_references, 45 unsigned(portp.ip_messages.data.port.receiver_name), 46 GetPortDestProc(portp)) 47 else: 48 out_string += prefix + format_string.format( 49 unsigned(portp), addressof(portp.ip_messages), ' '*8, 50 unsigned(portp.ip_messages.data.port.receiver_name), 51 "DPort", portp.ip_object.io_references, unsigned(portp), 52 "inactive-port") 53 54 if show_kmsg_summary: 55 kmsgp = Cast(portp.ip_messages.data.port.messages.ikmq_base, 'ipc_kmsg_t') 56 out_string += prefix + GetKMsgSummary.header + prefix + GetKMsgSummary(kmsgp) 57 58 kmsgheadp = kmsgp 59 kmsgp = kmsgp.ikm_next 60 while (kmsgp) != (kmsgheadp): 61 out_string += prefix + GetKMsgSummary(kmsgp) 62 kmsgp = kmsgp.ikm_next 63 return out_string 64 65def GetPortDestProc(portp): 66 """ Display the name and pid of a given port's receiver 67 params: 68 portp : core.value representing a pointer to a port in the kernel 69 destspacep : core.value representing a pointer to an ipc_space 70 returns: 71 str : string containing receiver's name and pid 72 """ 73 spacep = portp.data.receiver 74 out_str = "Not found" 75 for tsk in kern.tasks: 76 if tsk.itk_space == spacep: 77 if tsk.bsd_info: 78 destprocp = Cast(tsk.bsd_info, 'struct proc *') 79 out_str = "{0:s}({1: <d})".format(destprocp.p_comm, destprocp.p_pid) 80 else: 81 out_str = "task {0: #019x}".format(desttaskp) 82 break 83 84 return out_str 85 86@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <6s} {5: <19s} {6: <6s}\n".format( 87 "dest-port", "kmsg", "msgid", "disp", "size", "reply-port", "source")) 88def GetKMsgSummary(kmsgp): 89 """ Display a summary for type ipc_kmsg_t 90 params: 91 kmsgp : core.value representing the given ipc_kmsg_t struct 92 returns: 93 str : string of summary info for the given ipc_kmsg_t instance 94 """ 95 kmsghp = kmsgp.ikm_header 96 kmsgh = dereference(kmsghp) 97 out_string = "" 98 out_string += "{0: <19s} {1: #019x} {2: <8s} {3: #011x} ".format( 99 ' '*19, unsigned(kmsgp), ' '*8, kmsgh.msgh_id) 100 101 if (kmsgh.msgh_bits & 0xff) == 19: 102 out_string += "{0: <2s}".format("rC") 103 else: 104 out_string += "{0: <2s}".format("rM") 105 106 if (kmsgh.msgh_bits & 0xff00) == (19 << 8): 107 out_string += "{0: <2s}".format("lC") 108 else: 109 out_string += "{0: <2s}".format("lM") 110 if kmsgh.msgh_bits & 0xf0000000: 111 out_string += "{0: <2s}".format("c") 112 else: 113 out_string += "{0: <2s}".format("s") 114 115 out_string += "{0: >5d} {1: #019x} {2: <16s}\n".format( 116 unsigned(kmsgh.msgh_size), kmsgh.msgh_local_port, 117 GetKMsgSrc(kmsgp)) 118 return out_string 119 120def GetKMsgSrc(kmsgp): 121 """ Routine that prints a kmsg's source process and pid details 122 params: 123 kmsgp : core.value representing the given ipc_kmsg_t struct 124 returns: 125 str : string containing the name and pid of the kmsg's source proc 126 """ 127 kmsgsrchp = Cast(kmsgp, 'ipc_kmsg_t').ikm_header 128 kmsgpid = int(Cast(kern.GetValueFromAddress(unsigned(kmsgsrchp) + kmsgsrchp.msgh_size, 'uint *')[10], 'pid_t')) 129 130 return "{0:s} ({1:d})".format(GetProcNameForPid(kmsgpid), kmsgpid) 131 132@header("{0: <20s} {1: <28s} {2: <12s} {3: <6s} {4: <6s} {5: <20s} {6: <7s}\n".format( 133 "portset", "waitqueue", "recvname", "flags", "refs", "recvname", "process")) 134def GetPortSetSummary(pset): 135 """ Display summary for a given struct ipc_pset * 136 params: 137 pset : core.value representing a pset in the kernel 138 returns: 139 str : string of summary information for the given pset 140 """ 141 out_str = "" 142 if pset.ips_object.io_bits & 0x80000000: 143 out_str += "{0: #019x} {1: #019x} {2: <7s} {3: #011x} {4: <4s} {5: >6d} {6: #019x} ".format( 144 unsigned(pset), addressof(pset.ips_messages), ' '*7, 145 pset.ips_messages.data.pset.local_name, "ASet", 146 pset.ips_object.io_references, 147 pset.ips_messages.data.pset.local_name) 148 149 else: 150 out_str += "{0: #019x} {1: #019x} {2: <7s} {3: #011x} {4: <4s} {5: >6d} {6: #019x} ".format( 151 unsigned(pset), addressof(pset.ips_messages), ' '*7, 152 pset.ips_messages.data.pset.local_name, "DSet", 153 pset.ips_object.io_references, 154 pset.ips_messages.data.pset.local_name) 155 156 once = True 157 setlinksp = addressof(pset.ips_messages.data.pset.set_queue.wqs_setlinks) 158 wql = Cast(pset.ips_messages.data.pset.set_queue.wqs_setlinks.next, 'WaitQueueLink *') 159 portoff = getfieldoffset('struct ipc_port', 'ip_messages') 160 prefix_str = "{0:<21s}".format(' '*21) 161 while unsigned(wql) != unsigned(Cast(setlinksp, 'void *')): 162 portp = kern.GetValueFromAddress(unsigned(wql.wql_element.wqe_queue) - portoff, 'ipc_port *') 163 if once: 164 once = False 165 out_str += "{0:s}\n{1:s}{2:s}".format(GetPortDestProc(portp), prefix_str, GetPortSummary.header) 166 out_str += GetPortSummary(portp, False, prefix_str) 167 wql = Cast(wql.wql_setlinks.next, 'WaitQueueLink *') 168 return out_str 169 170# Macro: showipc 171 172@lldb_command('showipc') 173def ShowIPC(cmd_args=None): 174 """ Routine to print data for the given IPC space 175 Usage: showipc <address of ipc space> 176 """ 177 if not cmd_args: 178 print "No arguments passed" 179 print ShowIPC.__doc__ 180 return False 181 ipc = kern.GetValueFromAddress(cmd_args[0], 'ipc_space *') 182 if not ipc: 183 print "unknown arguments:", str(cmd_args) 184 return False 185 print GetIPCInformation.header 186 print GetIPCInformation(ipc, False, False) 187 188# EndMacro: showipc 189 190# Macro: showtaskipc 191 192@lldb_command('showtaskipc') 193def ShowTaskIPC(cmd_args=None): 194 """ Routine to print IPC summary of given task 195 Usage: showtaskipc <address of task> 196 """ 197 if not cmd_args: 198 print "No arguments passed" 199 print ShowTaskIPC.__doc__ 200 return False 201 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 202 if not tval: 203 print "unknown arguments:", str(cmd_args) 204 return False 205 print GetTaskSummary.header + " " + GetProcSummary.header 206 pval = Cast(tval.bsd_info, 'proc *') 207 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 208 print GetTaskIPCSummary.header 209 print GetTaskIPCSummary(tval) 210 211# EndMacro: showtaskipc 212 213# Macro: showallipc 214 215@lldb_command('showallipc') 216def ShowAllIPC(cmd_args=None): 217 """ Routine to print IPC summary of all tasks 218 Usage: showallipc 219 """ 220 for t in kern.tasks: 221 print GetTaskSummary.header + " " + GetProcSummary.header 222 pval = Cast(t.bsd_info, 'proc *') 223 print GetTaskSummary(t) + " " + GetProcSummary(pval) 224 print GetIPCInformation.header 225 print GetIPCInformation(t.itk_space, False, False) + "\n\n" 226 227# EndMacro: showallipc 228 229@lldb_command('showipcsummary') 230def ShowIPCSummary(cmd_args=None): 231 """ Summarizes the IPC state of all tasks. 232 This is a convenient way to dump some basic clues about IPC messaging. You can use the output to determine 233 tasks that are candidates for further investigation. 234 """ 235 print GetTaskIPCSummary.header 236 for t in kern.tasks: 237 print GetTaskIPCSummary(t) 238 return 239 240def GetKObjectFromPort(portval): 241 """ Get Kobject description from the port. 242 params: portval - core.value representation of 'ipc_port *' object 243 returns: str - string of kobject information 244 """ 245 kobject_str = "{0: <#020x}".format(portval.kdata.kobject) 246 io_bits = unsigned(portval.ip_object.io_bits) 247 objtype_index = io_bits & 0xfff 248 if objtype_index < len(xnudefines.kobject_types) : 249 desc_str = "kobject({0:s})".format(xnudefines.kobject_types[objtype_index]) 250 else: 251 desc_str = "kobject(UNKNOWN) {:d}".format(objtype_index) 252 return kobject_str + " " + desc_str 253 254@static_var('destcache', {}) 255def GetDestinationProcessFromPort(port): 256 """ 257 params: port - core.value representation of 'ipc_port *' object 258 returns: str - name of process 259 """ 260 out_str = '' 261 dest_space = port.data.receiver 262 found_dest = False 263 #update destcache if data is not found 264 if hex(dest_space) not in GetDestinationProcessFromPort.destcache: 265 for t in kern.tasks: 266 if hex(t.itk_space) == hex(dest_space): 267 pval = Cast(t.bsd_info, 'proc *') 268 GetDestinationProcessFromPort.destcache[hex(dest_space)] = (t, pval) 269 found_dest = True 270 break 271 #end of for loop 272 else: found_dest = True 273 274 if found_dest: 275 (ftask , fproc) = GetDestinationProcessFromPort.destcache[hex(dest_space)] 276 if fproc: 277 out_str = "{0:s}({1:d})".format(fproc.p_comm, fproc.p_pid ) 278 else: 279 out_str = "task {0: <#020x}".format(ftask) 280 return out_str 281 282 283 284@header("{0: <20s} {1: <20s}".format("destname", "destination") ) 285def GetPortDestinationSummary(port): 286 """ Get destination information for a port. 287 params: port - core.value representation of 'ipc_port *' object 288 returns: str - string of info about ports destination 289 """ 290 out_str = '' 291 format_string = "{0: <20s} {1: <20s}" 292 destname_str = '' 293 destination_str = '' 294 ipc_space_kernel = unsigned(kern.globals.ipc_space_kernel) 295 target_spaceval = port.data.receiver 296 if unsigned(target_spaceval) == ipc_space_kernel : 297 destname_str = GetKObjectFromPort(port) 298 else: 299 if int(port.ip_object.io_bits) & 0x80000000 : 300 destname_str = "{0: <#020x}".format(port.ip_messages.data.port.receiver_name) 301 destination_str = GetDestinationProcessFromPort(port) 302 else: 303 destname_str = "{0: <#020x}".format(port) 304 destination_str = "inactive-port" 305 306 out_str += format_string.format(destname_str, destination_str) 307 return out_str 308 309@lldb_type_summary(['ipc_entry_t']) 310@header("{0: <20s} {1: <20s} {2: <8s} {3: <8s} {4: <20s} {5: <20s}".format("object", "name","rite", "urefs", "destname", "destination")) 311def GetIPCEntrySummary(entry, ipc_name=''): 312 """ Get summary of a ipc entry. 313 params: 314 entry - core.value representing ipc_entry_t in the kernel 315 ipc_name - str of format '0x0123' for display in summary. 316 returns: 317 str - string of ipc entry related information 318 """ 319 out_str = '' 320 entry_ptr = int(hex(entry), 16) 321 format_string = "{0: <#020x} {1: <12s} {2: <8s} {3: <8d} {4: <20s} {5: <20s}" 322 right_str = '' 323 destname_str = '' 324 destination_str = '' 325 326 ie_object = entry.ie_object 327 ie_bits = int(entry.ie_bits) 328 urefs = int(ie_bits & 0xffff) 329 if ie_bits & 0x00100000 : 330 right_str = 'Dead' 331 elif ie_bits & 0x00080000: 332 right_str = 'Set' 333 else: 334 if ie_bits & 0x00010000 : 335 if ie_bits & 0x00020000 : 336 right_str = 'SR' 337 else: 338 right_str = 'S' 339 elif ie_bits & 0x00020000: 340 right_str = 'R' 341 elif ie_bits & 0x00040000 : 342 right_str = 'O' 343 if int(entry.index.request) != 0: 344 portval = Cast(ie_object, 'ipc_port_t') 345 requestsval = portval.ip_requests 346 sorightval = requestsval[int(entry.index.request)].notify.port 347 soright_ptr = unsigned(sorightval) 348 if soright_ptr != 0: 349 if soright_ptr & 0x1 : right_str +='s' 350 elif soright_ptr & 0x2 : right_str +='d' 351 else : right_str +='n' 352 if ie_bits & 0x00800000 : right_str +='c' 353 # now show the port destination part 354 destname_str = GetPortDestinationSummary(Cast(ie_object, 'ipc_port_t')) 355 356 out_str = format_string.format(ie_object, ipc_name, right_str, urefs, destname_str, destination_str) 357 return out_str 358 359@header("{0: >20s}".format("user bt") ) 360def GetPortUserStack(port, task): 361 """ Get UserStack information for the given port & task. 362 params: port - core.value representation of 'ipc_port *' object 363 task - value representing 'task *' object 364 returns: str - string information on port's userstack 365 """ 366 out_str = '' 367 ie_port_callstack = port.ip_callstack 368 ie_port_spares = port.ip_spares[0] 369 proc_val = Cast(task.bsd_info, 'proc *') 370 if ie_port_callstack[0]: 371 out_str += "{: <10x}".format(ie_port_callstack[0]) 372 count = 1 373 while count < 16 and ie_port_callstack[count]: 374 out_str += ": <10x".format(ie_port_callstack[count]) 375 count = count + 1 376 if ie_port_spares != proc_val.p_pid: 377 out_str += " ({:<10d})".format(ie_port_spares) 378 out_str += '\n' 379 return out_str 380 381@lldb_type_summary(['ipc_space *']) 382@header("{0: <20s} {1: <20s} {2: <20s} {3: <8s} {4: <10s} {5: <16s} {6: <10s} {7: <7s}".format('ipc_space', 'is_task', 'is_table', 'flags', 'ports', 'table_next', 'low_mod', 'high_mod')) 383def GetIPCInformation(space, show_entries=False, show_userstack=False): 384 """ Provide a summary of the ipc space 385 """ 386 out_str = '' 387 format_string = "{0: <#020x} {1: <#020x} {2: <#020x} {3: <8s} {4: <10d} {5: <#01x} {6: >10d} {7: >10d}" 388 is_tableval = space.is_table 389 ports = int(space.is_table_size) 390 flags ='' 391 is_bits = int(space.is_bits) 392 if (is_bits & 0x40000000) == 0: flags +='A' 393 else: flags += ' ' 394 if (is_bits & 0x20000000) != 0: flags +='G' 395 out_str += format_string.format(space, space.is_task, space.is_table, flags, space.is_table_size, space.is_table_next, space.is_low_mod, space.is_high_mod) 396 397 #should show the each individual entries if asked. 398 if show_entries == True: 399 out_str += "\n\t" + GetIPCEntrySummary.header + "\n" 400 num_entries = ports 401 index = 0 402 while index < num_entries: 403 entryval = GetObjectAtIndexFromArray(is_tableval, index) 404 entry_ie_bits = unsigned(entryval.ie_bits) 405 if (int(entry_ie_bits) & 0x001f0000 ) != 0: 406 entry_name = "{0: <#020x}".format( (index <<8 | entry_ie_bits >> 24) ) 407 out_str += "\t" + GetIPCEntrySummary(entryval, entry_name) + "\n" 408 if show_userstack == True: 409 entryport = Cast(entryval.ie_object, 'ipc_port *') 410 if entryval.ie_object and (int(entry_ie_bits) & 0x00070000) and entryport.ip_callstack[0]: 411 out_str += GetPortUserStack.header 412 out_str += GetPortUserStack(entryport, space.is_task) 413 index +=1 414 #done with showing entries 415 return out_str 416 417# Macro: showrights 418 419@lldb_command('showrights') 420def ShowRights(cmd_args=None): 421 """ Routine to print rights information for the given IPC space 422 Usage: showrights <address of ipc space> 423 """ 424 if not cmd_args: 425 print "No arguments passed" 426 print ShowRights.__doc__ 427 return False 428 ipc = kern.GetValueFromAddress(cmd_args[0], 'ipc_space *') 429 if not ipc: 430 print "unknown arguments:", str(cmd_args) 431 return False 432 print GetIPCInformation.header 433 print GetIPCInformation(ipc, True, False) 434 435# EndMacro: showrights 436 437@lldb_command('showtaskrights') 438def ShowTaskRights(cmd_args=None): 439 """ Routine to ipc rights information for a task 440 Usage: showtaskrights <task address> 441 """ 442 if cmd_args == None: 443 print "No arguments passed" 444 print ShowTaskStacksCmdHelper.__doc__ 445 return False 446 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 447 if not tval: 448 print "unknown arguments:", str(cmd_args) 449 return False 450 print GetTaskSummary.header + " " + GetProcSummary.header 451 pval = Cast(tval.bsd_info, 'proc *') 452 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 453 print GetIPCInformation.header 454 print GetIPCInformation(tval.itk_space, True, False) 455 456# Macro: showataskrightsbt 457 458@lldb_command('showtaskrightsbt') 459def ShowTaskRightsBt(cmd_args=None): 460 """ Routine to ipc rights information with userstacks for a task 461 Usage: showtaskrightsbt <task address> 462 """ 463 if cmd_args == None: 464 print "No arguments passed" 465 print ShowTaskRightsBt.__doc__ 466 return False 467 tval = kern.GetValueFromAddress(cmd_args[0], 'task *') 468 if not tval: 469 print "unknown arguments:", str(cmd_args) 470 return False 471 print GetTaskSummary.header + " " + GetProcSummary.header 472 pval = Cast(tval.bsd_info, 'proc *') 473 print GetTaskSummary(tval) + " " + GetProcSummary(pval) 474 print GetIPCInformation.header 475 print GetIPCInformation(tval.itk_space, True, True) 476 477# EndMacro: showtaskrightsbt 478 479# Macro: showallrights 480 481@lldb_command('showallrights') 482def ShowAllRights(cmd_args=None): 483 """ Routine to print rights information for IPC space of all tasks 484 Usage: showallrights 485 """ 486 for t in kern.tasks: 487 print GetTaskSummary.header + " " + GetProcSummary.header 488 pval = Cast(t.bsd_info, 'proc *') 489 print GetTaskSummary(t) + " " + GetProcSummary(pval) 490 print GetIPCInformation.header 491 print GetIPCInformation(t.itk_space, True, False) + "\n\n" 492 493# EndMacro: showallrights 494 495# Macro: showpipestats 496@lldb_command('showpipestats') 497def ShowPipeStats(cmd_args=None): 498 """ Display pipes usage information in the kernel 499 """ 500 print "Number of pipes: {: d}".format(kern.globals.amountpipes) 501 print "Memory used by pipes: {:s}".format(sizeof_fmt(int(kern.globals.amountpipekva))) 502 print "Max memory allowed for pipes: {:s}".format(sizeof_fmt(int(kern.globals.maxpipekva))) 503# EndMacro: showpipestats 504 505# Macro: showtaskbusyports 506@lldb_command('showtaskbusyports') 507def ShowTaskBusyPorts(cmd_args=None): 508 """ Routine to print information about receive rights belonging to this task that 509 have enqueued messages. This is oten a sign of a blocked or hung process 510 Usage: showtaskbusyports <task address> 511 """ 512 if not cmd_args: 513 print "No arguments passed. Please pass in the address of a task" 514 print ShowTaskBusyPorts.__doc__ 515 return 516 task = kern.GetValueFromAddress(cmd_args[0], 'task_t') 517 print GetTaskBusyPorts(task) 518 return 519 520def GetTaskBusyPorts(task): 521 """ Prints all busy ports for a given task. ie. all receive rights belonging 522 to this task that have enqueued messages. 523 params: 524 task : core.value representing a task in kernel 525 returns: 526 str : String containing information about the given task's busy ports 527 """ 528 isp = task.itk_space 529 i = 0 530 out_string = "" 531 while i < isp.is_table_size: 532 iep = addressof(isp.is_table[i]) 533 if iep.ie_bits & 0x00020000: 534 port = Cast(iep.ie_object, 'ipc_port_t') 535 if port.ip_messages.data.port.msgcount > 0: 536 out_string += GetPortSummary.header + GetPortSummary(port) 537 i = i + 1 538 return out_string 539# EndMacro: showtaskbusyports 540 541# Macro: showallbusyports 542@lldb_command('showallbusyports') 543def ShowAllBusyPorts(cmd_args=None): 544 """ Routine to print information about all receive rights on the system that 545 have enqueued messages. 546 """ 547 task_queue_head = kern.globals.tasks 548 549 for tsk in kern.tasks: 550 print GetTaskBusyPorts(tsk) 551 return 552# EndMacro: showallbusyports 553 554# Macro: showmqueue: 555@lldb_command('showmqueue') 556def ShowMQueue(cmd_args=None): 557 """ Routine that lists details about a given mqueue 558 Syntax: (lldb) showmqueue 0xaddr 559 """ 560 if not cmd_args: 561 print "Please specify the address of the ipc_mqueue whose details you want to print" 562 print ShowMQueue.__doc__ 563 return 564 mqueue = kern.GetValueFromAddress(cmd_args[0], 'struct ipc_mqueue *') 565 wq_type = mqueue.data.pset.set_queue.wqs_wait_queue.wq_type 566 if int(wq_type) == 3: 567 psetoff = getfieldoffset('struct ipc_pset *', 'ips_messages') 568 pset = unsigned(ArgumentStringToInt(cmd_args[0])) - unsigned(psetoff) 569 print GetPortSetSummary.header + GetPortSetSummary(kern.GetValueFromAddress(pset, 'struct ipc_pset *')) 570 if int(wq_type) == 2: 571 portoff = getfieldoffset('struct ipc_port', 'ip_messages') 572 port = unsigned(ArgumentStringToInt(cmd_args[0])) - unsigned(portoff) 573 print GetPortSummary.header + GetPortSummary(kern.GetValueFromAddress(port, 'struct ipc_port *')) 574# EndMacro: showmqueue 575 576# Macro: showpset 577@lldb_command('showpset') 578def ShowPSet(cmd_args=None): 579 """ Routine that prints details for a given ipc_pset * 580 Syntax: (lldb) showpset 0xaddr 581 """ 582 if not cmd_args: 583 print "Please specify the address of the pset whose details you want to print" 584 print ShowPSet.__doc__ 585 return 586 587 print GetPortSetSummary.header + GetPortSetSummary(kern.GetValueFromAddress(cmd_args[0], 'ipc_pset *')) 588# EndMacro: showpset 589 590