xref: /freebsd/sys/tools/gdb/acttrace.py (revision ea675a43f09ba569adf1dd17b4f1ced970e48de4)
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