From b32077e24586813267bc201068bfecf79666792e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cyryl=20P=C5=82otnicki?= Date: Sat, 30 Jan 2021 15:56:36 +0000 Subject: [PATCH] better gdb dashboard setup --- .gdbinit | 43 +++++++++++++++++++++++------------- nixos/home-manager/links.nix | 4 ++++ 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/.gdbinit b/.gdbinit index 993a3f6d..defb8da2 100644 --- a/.gdbinit +++ b/.gdbinit @@ -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): diff --git a/nixos/home-manager/links.nix b/nixos/home-manager/links.nix index 1e72463b..5a0d3907 100644 --- a/nixos/home-manager/links.nix +++ b/nixos/home-manager/links.nix @@ -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 + ''; }