1*2524b7dfSMark Johnston#- 2*2524b7dfSMark Johnston# Copyright (c) 2022 The FreeBSD Foundation 3*2524b7dfSMark Johnston# 4*2524b7dfSMark Johnston# This software was developed by Mark Johnston under sponsorship from the 5*2524b7dfSMark Johnston# FreeBSD Foundation. 6*2524b7dfSMark Johnston# 7*2524b7dfSMark Johnston 8*2524b7dfSMark Johnstonimport gdb 9*2524b7dfSMark Johnston 10*2524b7dfSMark Johnston 11*2524b7dfSMark Johnstondef symval(name): 12*2524b7dfSMark Johnston return gdb.lookup_global_symbol(name).value() 13*2524b7dfSMark Johnston 14*2524b7dfSMark Johnston 15*2524b7dfSMark Johnstondef tid_to_gdb_thread(tid): 16*2524b7dfSMark Johnston for thread in gdb.inferiors()[0].threads(): 17*2524b7dfSMark Johnston if thread.ptid[2] == tid: 18*2524b7dfSMark Johnston return thread 19*2524b7dfSMark Johnston else: 20*2524b7dfSMark Johnston return None 21*2524b7dfSMark Johnston 22*2524b7dfSMark Johnston 23*2524b7dfSMark Johnstondef all_pcpus(): 24*2524b7dfSMark Johnston mp_maxid = symval("mp_maxid") 25*2524b7dfSMark Johnston cpuid_to_pcpu = symval("cpuid_to_pcpu") 26*2524b7dfSMark Johnston 27*2524b7dfSMark Johnston cpu = 0 28*2524b7dfSMark Johnston while cpu <= mp_maxid: 29*2524b7dfSMark Johnston pcpu = cpuid_to_pcpu[cpu] 30*2524b7dfSMark Johnston if pcpu: 31*2524b7dfSMark Johnston yield pcpu 32*2524b7dfSMark Johnston cpu = cpu + 1 33*2524b7dfSMark Johnston 34*2524b7dfSMark Johnston 35*2524b7dfSMark Johnstonclass acttrace(gdb.Command): 36*2524b7dfSMark Johnston def __init__(self): 37*2524b7dfSMark Johnston super(acttrace, self).__init__("acttrace", gdb.COMMAND_USER) 38*2524b7dfSMark Johnston 39*2524b7dfSMark Johnston def invoke(self, arg, from_tty): 40*2524b7dfSMark Johnston # Save the current thread so that we can switch back after. 41*2524b7dfSMark Johnston curthread = gdb.selected_thread() 42*2524b7dfSMark Johnston 43*2524b7dfSMark Johnston for pcpu in all_pcpus(): 44*2524b7dfSMark Johnston td = pcpu['pc_curthread'] 45*2524b7dfSMark Johnston tid = td['td_tid'] 46*2524b7dfSMark Johnston 47*2524b7dfSMark Johnston gdb_thread = tid_to_gdb_thread(tid) 48*2524b7dfSMark Johnston if gdb_thread is None: 49*2524b7dfSMark Johnston print("failed to find GDB thread with TID {}".format(tid)) 50*2524b7dfSMark Johnston else: 51*2524b7dfSMark Johnston gdb_thread.switch() 52*2524b7dfSMark Johnston 53*2524b7dfSMark Johnston p = td['td_proc'] 54*2524b7dfSMark Johnston print("Tracing command {} pid {} tid {} (CPU {})".format( 55*2524b7dfSMark Johnston p['p_comm'], p['p_pid'], td['td_tid'], pcpu['pc_cpuid'])) 56*2524b7dfSMark Johnston gdb.execute("bt") 57*2524b7dfSMark Johnston print() 58*2524b7dfSMark Johnston 59*2524b7dfSMark Johnston curthread.switch() 60*2524b7dfSMark Johnston 61*2524b7dfSMark Johnston 62*2524b7dfSMark Johnston# Registers the command with gdb, doesn't do anything. 63*2524b7dfSMark Johnstonacttrace() 64