class RemoteCmd(gdb.Command):
self.tmp_file = f'/tmp/{uuid.uuid4().hex}'
gdb.write(f"Using tmp output file: {self.tmp_file}.\n")
gdb.execute("set detach-on-fork off")
gdb.execute("set follow-fork-mode parent")
gdb.execute("set max-value-size unlimited")
gdb.execute("set pagination off")
gdb.execute("set print elements 0")
gdb.execute("set print repeats 0")
super(RemoteCmd, self).__init__("rcmd", gdb.COMMAND_USER)
if symbol not in self.addresses:
address_string = gdb.execute(f"info address {symbol}", to_string=True)
f'Symbol "{symbol}" is at ([0-9a-fx]+) .*', address_string, re.IGNORECASE
if match and len(match.groups()) > 0:
self.addresses[symbol] = match.groups()[0]
raise RuntimeError(f'Could not retrieve address for symbol "{symbol}".')
return self.addresses[symbol]
f'set $fd = (int){self.load("open")}("{self.tmp_file}", {O_RDONLY})'
gdb.execute(f'set $len = (int){self.load("lseek")}($fd, 0, {SEEK_END})')
gdb.execute(f'call (int){self.load("lseek")}($fd, 0, {SEEK_SET})')
if int(gdb.convenience_variable("len")) <= 0:
gdb.write("No output was captured.")
gdb.execute(f'set $mem = (void*){self.load("malloc")}($len)')
gdb.execute(f'call (int){self.load("read")}($fd, $mem, $len)')
gdb.execute('printf "%s\\n", (char*) $mem')
gdb.execute(f'call (int){self.load("close")}($fd)')
gdb.execute(f'call (int){self.load("free")}($mem)')
def invoke(self, arg, from_tty):
is_auto_solib_add = gdb.parameter("auto-solib-add")
gdb.execute("set auto-solib-add off")
parent_inferior = gdb.selected_inferior()
gdb.execute(f'set $child_pid = (int){self.load("fork")}()')
child_pid = gdb.convenience_variable("child_pid")
filter(lambda x: x.pid == child_pid, gdb.inferiors())
gdb.execute(f"inferior {child_inferior.num}")
f'call (int){self.load("execl")}("/bin/sh", "sh", "-c", "exec {arg} >{self.tmp_file} 2>&1", (char*)0)'
"The program being debugged exited while in a function called from GDB"
gdb.execute(f"inferior {parent_inferior.num}")
gdb.execute(f"remove-inferiors {child_inferior.num}")
gdb.write("".join(traceback.TracebackException.from_exception(e).format()))
gdb.execute(f'set auto-solib-add {"on" if is_auto_solib_add else "off"}')