Reputation: 428
It is well documented in the manual, that gdb writes the command history after exiting (https://sourceware.org/gdb/onlinedocs/gdb/Command-History.html).
However, I would like to obtain the complete command history without exiting to fill it on demand into a scratch buffer for editing or convenient re-running from within neovim with gdb -x FILE
in another gdb instance.
What ways exist to get the info out from a running gdb instance?
Upvotes: 1
Views: 441
Reputation: 4751
Since GDB 9 you can achieve what you want using the pipe
command, which is documented here, along with some basic shell commands.
$ gdb -q
(gdb) p 1
$1 = 1
(gdb) p 2
$2 = 2
(gdb) pipe show commands | sed -e 's/[[:space:]]\+[0-9]\+[[:space:]]\+//' | head -n -1 | tee /tmp/commands
p 1
p 2
(gdb) q
$ cat /tmp/commands
p 1
p 2
GDB's pipe
command arranges to send the command output to a shell command. I pass the output through sed
to strip off the command index, then through head
to drop the last command, which is going to be the pipe
command that is currently running, and finally, I use tee
to send the output to a file.
It was pointed out in the comments that show commands
only shows the last 10 commands. However, show commands
also takes some arguments, these are documented here.
With this, we could add a new command to GDB using the Python API. Here's the contents of show-all-commands.py
:
import re
class ShowAllCommands(gdb.Command):
"""
show all-commands
Show GDB's complete command history. Unlike 'show commands' this
lists everything in GDB's command history.
"""
def __init__(self):
super().__init__("show all-commands", gdb.COMMAND_OBSCURE)
def invoke(self, arg, from_tty):
start = 1
last_command_number = 0
all_commands = []
get_more = True
while get_more:
found_new_line = False
output = gdb.execute(f"show commands {start}", False, True)
for line in output.splitlines():
g = re.search(r'^\s+(\d+)', line).group(1)
if not g:
break
if int(g) <= last_command_number:
continue
last_command_number = int(g)
all_commands.append(line)
found_new_line = True
if not found_new_line:
break
start = "+"
for line in all_commands:
print(line)
ShowAllCommands()
Then in GDB (or from the .gdbinit file) we can do this:
source show-all-commands.py
You might need to add the path to that Python script in the source
line so GDB can find it.
Then, just as before, we can use the new command:
pipe show all-commands | sed -e 's/[[:space:]]\+[0-9]\+[[:space:]]\+//' | head -n -1 | tee /tmp/commands
If you were feeling super keen then you could, of course, make the new Python command smarter, maybe it could write the commands directly to the output file, but I've left that as an exercise for the reader.
Upvotes: 2
Reputation: 213476
What ways exist to get the info out from a running gdb instance?
You can see the history with (gdb) show commands
.
You could save the output into a file with:
(gdb) set logging file /tmp/gdb-history
(gdb) set logging on
(gdb) show commands
(gdb) set logging off
Unfortunately the history has sequence numbers, which you'll have to strip before you could use gdb -x /tmp/gdb-history
.
Upvotes: 1