better gdb dashboard setup
This commit is contained in:
parent
65a409781c
commit
b32077e245
2 changed files with 32 additions and 15 deletions
43
.gdbinit
43
.gdbinit
|
@ -412,7 +412,9 @@ class Dashboard(gdb.Command):
|
||||||
def on_continue(self, _):
|
def on_continue(self, _):
|
||||||
# try to contain the GDB messages in a specified area unless the
|
# try to contain the GDB messages in a specified area unless the
|
||||||
# dashboard is printed to a separate file (dashboard -output ...)
|
# 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()
|
width, _ = Dashboard.get_term_size()
|
||||||
gdb.write(Dashboard.clear_screen())
|
gdb.write(Dashboard.clear_screen())
|
||||||
gdb.write(divider(width, 'Output/messages', True))
|
gdb.write(divider(width, 'Output/messages', True))
|
||||||
|
@ -514,6 +516,9 @@ class Dashboard(gdb.Command):
|
||||||
buf += Dashboard.clear_screen()
|
buf += Dashboard.clear_screen()
|
||||||
# show message if all the modules in this output are disabled
|
# show message if all the modules in this output are disabled
|
||||||
if not any(instances):
|
if not any(instances):
|
||||||
|
# skip the main terminal
|
||||||
|
if fs is gdb:
|
||||||
|
continue
|
||||||
# write the error message
|
# write the error message
|
||||||
buf += divider(width, 'Warning', True)
|
buf += divider(width, 'Warning', True)
|
||||||
buf += '\n'
|
buf += '\n'
|
||||||
|
@ -521,11 +526,7 @@ class Dashboard(gdb.Command):
|
||||||
buf += 'No module to display (see `dashboard -layout`)'
|
buf += 'No module to display (see `dashboard -layout`)'
|
||||||
else:
|
else:
|
||||||
buf += 'No module loaded'
|
buf += 'No module loaded'
|
||||||
# write the terminator only in the main terminal
|
|
||||||
buf += '\n'
|
buf += '\n'
|
||||||
if fs is gdb:
|
|
||||||
buf += divider(width, primary=True)
|
|
||||||
buf += '\n'
|
|
||||||
fs.write(buf)
|
fs.write(buf)
|
||||||
continue
|
continue
|
||||||
# process all the modules for that output
|
# 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
|
frame = gdb.selected_frame() # PC is here
|
||||||
height = self.height or (term_height - 1)
|
height = self.height or (term_height - 1)
|
||||||
try:
|
try:
|
||||||
# disassemble the current block (if function information is
|
# disassemble the current block
|
||||||
# available then try to obtain the boundaries by looking at the
|
asm_start, asm_end = self.fetch_function_boundaries()
|
||||||
# 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
|
|
||||||
asm = self.fetch_asm(asm_start, asm_end, False, highlighter)
|
asm = self.fetch_asm(asm_start, asm_end, False, highlighter)
|
||||||
# find the location of the PC
|
# find the location of the PC
|
||||||
pc_index = next(index for index, instr in enumerate(asm)
|
pc_index = next(index for index, instr in enumerate(asm)
|
||||||
|
@ -1471,6 +1464,26 @@ A value of 0 uses the whole height.''',
|
||||||
else:
|
else:
|
||||||
self.offset = 0
|
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):
|
def fetch_asm(self, start, end_or_count, relative, highlighter):
|
||||||
# fetch asm from cache or disassemble
|
# fetch asm from cache or disassemble
|
||||||
if self.cache_key == (start, end_or_count):
|
if self.cache_key == (start, end_or_count):
|
||||||
|
|
|
@ -8,4 +8,8 @@
|
||||||
set auto-load safe-path /
|
set auto-load safe-path /
|
||||||
source /home/cyryl/dev/dotfiles/.gdbinit
|
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
|
||||||
|
'';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue