1*ea675a43SMark Johnston# 2*ea675a43SMark Johnston# Copyright (c) 2022 The FreeBSD Foundation 3*ea675a43SMark Johnston# 4*ea675a43SMark Johnston# This software was developed by Mark Johnston under sponsorship from the 5*ea675a43SMark Johnston# FreeBSD Foundation. 6*ea675a43SMark Johnston# 7*ea675a43SMark Johnston# SPDX-License-Identifier: BSD-2-Clause 8*ea675a43SMark Johnston# 9*ea675a43SMark Johnston 10*ea675a43SMark Johnstonimport gdb 11*ea675a43SMark Johnstonfrom freebsd import * 12*ea675a43SMark Johnstonfrom pcpu import * 13*ea675a43SMark Johnston 14*ea675a43SMark Johnstonclass acttrace(gdb.Command): 15*ea675a43SMark Johnston """ 16*ea675a43SMark Johnston Register an acttrace command with gdb. 17*ea675a43SMark Johnston 18*ea675a43SMark Johnston When run, acttrace prints the stack trace of all threads that were on-CPU 19*ea675a43SMark Johnston at the time of the panic. 20*ea675a43SMark Johnston """ 21*ea675a43SMark Johnston def __init__(self): 22*ea675a43SMark Johnston super(acttrace, self).__init__("acttrace", gdb.COMMAND_USER) 23*ea675a43SMark Johnston 24*ea675a43SMark Johnston def invoke(self, arg, from_tty): 25*ea675a43SMark Johnston # Save the current thread so that we can switch back after. 26*ea675a43SMark Johnston curthread = gdb.selected_thread() 27*ea675a43SMark Johnston 28*ea675a43SMark Johnston for pcpu in pcpu_foreach(): 29*ea675a43SMark Johnston td = pcpu['pc_curthread'] 30*ea675a43SMark Johnston tid = td['td_tid'] 31*ea675a43SMark Johnston 32*ea675a43SMark Johnston gdb_thread = tid_to_gdb_thread(tid) 33*ea675a43SMark Johnston if gdb_thread is None: 34*ea675a43SMark Johnston raise gdb.error(f"failed to find GDB thread with TID {tid}") 35*ea675a43SMark Johnston else: 36*ea675a43SMark Johnston gdb_thread.switch() 37*ea675a43SMark Johnston 38*ea675a43SMark Johnston p = td['td_proc'] 39*ea675a43SMark Johnston print("Tracing command {} pid {} tid {} (CPU {})".format( 40*ea675a43SMark Johnston p['p_comm'], p['p_pid'], td['td_tid'], pcpu['pc_cpuid'])) 41*ea675a43SMark Johnston gdb.execute("bt") 42*ea675a43SMark Johnston print() 43*ea675a43SMark Johnston 44*ea675a43SMark Johnston curthread.switch() 45*ea675a43SMark Johnston 46*ea675a43SMark Johnston 47*ea675a43SMark Johnston# Registers the command with gdb, doesn't do anything. 48*ea675a43SMark Johnstonacttrace() 49