better gdb dashboard setup

This commit is contained in:
Cyryl Płotnicki 2021-01-30 15:56:36 +00:00
parent 65a409781c
commit b32077e245
2 changed files with 32 additions and 15 deletions

View file

@ -412,7 +412,9 @@ class Dashboard(gdb.Command):
def on_continue(self, _):
# try to contain the GDB messages in a specified area unless the
# dashboard is printed to a separate file (dashboard -output ...)
if self.is_running() and not self.output:
# or there are no modules to display in the main terminal
enabled_modules = list(filter(lambda m: not m.output and m.enabled, self.modules))
if self.is_running() and not self.output and len(enabled_modules) > 0:
width, _ = Dashboard.get_term_size()
gdb.write(Dashboard.clear_screen())
gdb.write(divider(width, 'Output/messages', True))
@ -514,6 +516,9 @@ class Dashboard(gdb.Command):
buf += Dashboard.clear_screen()
# show message if all the modules in this output are disabled
if not any(instances):
# skip the main terminal
if fs is gdb:
continue
# write the error message
buf += divider(width, 'Warning', True)
buf += '\n'
@ -521,11 +526,7 @@ class Dashboard(gdb.Command):
buf += 'No module to display (see `dashboard -layout`)'
else:
buf += 'No module loaded'
# write the terminator only in the main terminal
buf += '\n'
if fs is gdb:
buf += divider(width, primary=True)
buf += '\n'
fs.write(buf)
continue
# process all the modules for that output
@ -1306,16 +1307,8 @@ The instructions constituting the current statement are marked, if available.'''
frame = gdb.selected_frame() # PC is here
height = self.height or (term_height - 1)
try:
# disassemble the current block (if function information is
# available then try to obtain the boundaries by looking at the
# superblocks)
block = frame.block()
if frame.function():
while block and (not block.function or block.function.name != frame.function().name):
block = block.superblock
block = block or frame.block()
asm_start = block.start
asm_end = block.end - 1
# disassemble the current block
asm_start, asm_end = self.fetch_function_boundaries()
asm = self.fetch_asm(asm_start, asm_end, False, highlighter)
# find the location of the PC
pc_index = next(index for index, instr in enumerate(asm)
@ -1471,6 +1464,26 @@ A value of 0 uses the whole height.''',
else:
self.offset = 0
def fetch_function_boundaries(self):
frame = gdb.selected_frame()
# parse the output of the disassemble GDB command to find the function
# boundaries, this should handle cases in which a function spans
# multiple discontinuous blocks
disassemble = run('disassemble')
for block_start, block_end in re.findall(r'Address range 0x([0-9a-f]+) to 0x([0-9a-f]+):', disassemble):
block_start = int(block_start, 16)
block_end = int(block_end, 16)
if block_start <= frame.pc() < block_end:
return block_start, block_end - 1 # need to be inclusive
# if function information is available then try to obtain the
# boundaries by looking at the superblocks
block = frame.block()
if frame.function():
while block and (not block.function or block.function.name != frame.function().name):
block = block.superblock
block = block or frame.block()
return block.start, block.end - 1
def fetch_asm(self, start, end_or_count, relative, highlighter):
# fetch asm from cache or disassemble
if self.cache_key == (start, end_or_count):

View file

@ -8,4 +8,8 @@
set auto-load safe-path /
source /home/cyryl/dev/dotfiles/.gdbinit
'';
home.file.".gdbinit.d/dashboard".text = ''
dashboard -layout breakpoints source expressions stack threads variables
dashboard variables -style compact 0
'';
}