1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
#
# gdb helper commands and functions for uftrace debugging
#
# mcount tools
#
# Copyright (c) LG Electronics, 2018
#
# Authors:
# Namhyung Kim <namhyung.kim@lge.com>
#
# This work is licensed under the terms of the GNU GPL version 2.
#
import gdb
from uftrace import rbtree, trigger, utils
filter_type = utils.CachedType("struct uftrace_filter")
def get_symbol_name(addr):
try:
block = gdb.block_for_pc(int(addr))
except:
try:
return gdb.execute('info symbol ' + hex(addr), False, True).split(' ')[0]
except:
return '<unknown>'
while block and not block.function:
block = block.superblock
if block is None:
return '<unknown>'
return block.function.print_name
class UftMcountData(gdb.Command):
"""Find mcount thread data of current thread and show return stacks."""
def __init__(self):
super(UftMcountData, self).__init__("uft-mcount-data", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
mtd = utils.gdb_eval_or_none("mtd")
if mtd is None:
gdb.write("no mtd found\n")
return
mtd_idx = mtd['idx']
gdb.write("mtd: tid = {tid}, idx = {idx}\n".format(
tid=mtd['tid'], idx=mtd_idx))
rstack = mtd['rstack']
for i in range(0, mtd_idx):
cip = rstack[i]['child_ip']
pip = rstack[i]['parent_ip']
csym = get_symbol_name(cip)
psym = get_symbol_name(pip)
gdb.write("[{ind}] {child} <== {parent}\n".format(
ind=i, child=csym, parent=psym))
UftMcountData()
class UftMcountFilter(gdb.Command):
"""List mcount filters."""
def __init__(self):
super(UftMcountFilter, self).__init__("uft-mcount-filters", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
tr = utils.gdb_eval_or_none("mcount_triggers")
if tr is None:
gdb.write("no filter/trigger found\n")
return
filter_ptr_type = filter_type.get_type().pointer()
trigger.filter_print(None)
for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"):
trigger.filter_print(filt)
UftMcountFilter()
class UftMcountTrigger(gdb.Command):
"""List mcount triggers."""
def __init__(self):
super(UftMcountTrigger, self).__init__("uft-mcount-triggers", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
tr = utils.gdb_eval_or_none("mcount_triggers")
if tr is None:
gdb.write("no filter/trigger found\n")
return
verbose = len(arg) > 0
filter_ptr_type = filter_type.get_type().pointer()
trigger.trigger_print(None, False)
for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"):
trigger.trigger_print(filt, verbose)
UftMcountTrigger()
class UftMcountArgspec(gdb.Command):
"""List mcount arguments and return values."""
def __init__(self):
super(UftMcountArgspec, self).__init__("uft-mcount-args", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty):
tr = utils.gdb_eval_or_none("mcount_triggers")
if tr is None:
gdb.write("no filter/trigger found\n")
return
verbose = len(arg) > 0
filter_ptr_type = filter_type.get_type().pointer()
trigger.argspec_print(None, False)
for filt in rbtree.rb_for_each_entry(tr, filter_ptr_type, "node"):
trigger.argspec_print(filt, verbose)
UftMcountArgspec()
|