chore(kernel): add custom pretty printer for std::string

This commit is contained in:
EnderIce2 2025-05-07 09:32:29 +00:00
parent 2791a602b5
commit 527ad803d3
Signed by: enderice2
GPG Key ID: FEB6B8A8507BA62E
3 changed files with 55 additions and 91 deletions

View File

@ -9,5 +9,9 @@ insert_final_newline = true
indent_style = tab
indent_size = 4
[*.py]
indent_size = 4
indent_style = space
[Makefile]
indent_style = tab

View File

@ -1,91 +0,0 @@
# Usage: add-symbol-file-all <filename> [<offset>]
# remove-symbol-file-all <filename> [<offset>]
#
# Credit: https://stackoverflow.com/a/33087762/9352057
# CC BY-SA 4.0
python
import subprocess
import re
def relocatesections(filename, addr):
p = subprocess.Popen(["readelf", "-S", filename], stdout = subprocess.PIPE)
sections = []
textaddr = '0'
for line in p.stdout.readlines():
line = line.decode("utf-8").strip()
if not line.startswith('[') or line.startswith('[Nr]'):
continue
line = re.sub(r' +', ' ', line)
line = re.sub(r'\[ *(\d+)\]', '\g<1>', line)
fieldsvalue = line.split(' ')
fieldsname = ['number', 'name', 'type', 'addr', 'offset', 'size', 'entsize', 'flags', 'link', 'info', 'addralign']
sec = dict(zip(fieldsname, fieldsvalue))
if sec['number'] == '0':
continue
sections.append(sec)
if sec['name'] == '.text':
textaddr = sec['addr']
return (textaddr, sections)
class AddSymbolFileAll(gdb.Command):
"""The right version for add-symbol-file"""
def __init__(self):
super(AddSymbolFileAll, self).__init__("add-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]
if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0
(textaddr, sections) = relocatesections(filename, offset)
cmd = "add-symbol-file %s 0x%08x" % (filename, int(textaddr, 16) + offset)
for s in sections:
addr = int(s['addr'], 16)
if s['name'] == '.text' or addr == 0:
continue
cmd += " -s %s 0x%08x" % (s['name'], addr + offset)
gdb.execute(cmd)
class RemoveSymbolFileAll(gdb.Command):
"""The right version for remove-symbol-file"""
def __init__(self):
super(RemoveSymbolFileAll, self).__init__("remove-symbol-file-all", gdb.COMMAND_USER)
self.dont_repeat()
def invoke(self, arg, from_tty):
argv = gdb.string_to_argv(arg)
filename = argv[0]
if len(argv) > 1:
offset = int(str(gdb.parse_and_eval(argv[1])), 0)
else:
offset = 0
(textaddr, _) = relocatesections(filename, offset)
cmd = "remove-symbol-file -a 0x%08x" % (int(textaddr, 16) + offset)
gdb.execute(cmd)
AddSymbolFileAll()
RemoveSymbolFileAll()
end

51
Kernel/gdb_printers.py Normal file
View File

@ -0,0 +1,51 @@
import gdb
class BasicStringPrinter:
def __init__(self, val):
self.val = val
def to_string(self):
try:
data = self.val['_data']
size = int(self.val['_size'])
capacity = int(self.val['_capacity'])
if int(data) == 0:
return '<null>'
content = data.string(length=size)
return f"'{content}' (size={size}, cap={capacity})"
except gdb.error:
return '<invalid string>'
def children(self):
try:
data = self.val['_data']
size = int(self.val['_size'])
if int(data) == 0:
return
for i in range(size):
yield (f'[{i}]', (data + i).dereference())
except gdb.error:
return
def display_hint(self):
return 'array'
def lookup_fennix_string(val):
try:
typename = str(val.type.strip_typedefs())
fields = val.type.fields()
field_names = [f.name for f in fields]
if '_data' in field_names and '_size' in field_names and '_capacity' in field_names:
return BasicStringPrinter(val)
except:
pass
return None
gdb.pretty_printers.append(lookup_fennix_string)
def build_pretty_printers():
pp = gdb.printing.RegexpCollectionPrettyPrinter("fennix")
pp.add_printer('std::string', '^std::string$', BasicStringPrinter)
return pp
gdb.printing.register_pretty_printer(None, build_pretty_printers(), replace=True)