Skip to content

Commit

Permalink
scripts: coredump: coredump_gdbserver in pipeline
Browse files Browse the repository at this point in the history
Add support to coredump_gdbserver.py for running in a pipeline,
communicating through stdin/stdout instead of a socket.

This allows starting it from inside gdb, with:

    target remote | coredump_gdbserver.py --pipe <elf_file>  <log_file>

Signed-off-by: Kevin ORourke <[email protected]>
  • Loading branch information
kevinior committed Feb 28, 2024
1 parent ff8c892 commit bcf98ea
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 10 deletions.
22 changes: 21 additions & 1 deletion doc/services/debugging/coredump.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ This usually involves the following steps:

3. Start the custom GDB server using the script
:zephyr_file:`scripts/coredump/coredump_gdbserver.py` with the core dump
binary log file, and the Zephyr ELF file as parameters.
binary log file, and the Zephyr ELF file as parameters. The GDB server
can also be started from within GDB, see below.

4. Start the debugger corresponding to the target architecture.

Expand Down Expand Up @@ -220,6 +221,25 @@ in :file:`coredump.log`:
#2 0x00100492 in func_1 (addr=0x0) at zephyr/rtos/zephyr/samples/hello_world/src/main.c:28
#3 0x001004c8 in main () at zephyr/rtos/zephyr/samples/hello_world/src/main.c:42

Starting the GDB server from within GDB
---------------------------------------

You can use ``target remote |`` to start the custom GDB server from inside
GDB, instead of in a separate shell.

1. Start GDB:

.. code-block:: console
<path to SDK>/x86_64-zephyr-elf/bin/x86_64-zephyr-elf-gdb build/zephyr/zephyr.elf
2. Inside GDB, start the GDB server using the ``--pipe`` option:

.. code-block:: console
(gdb) target remote | ./scripts/coredump/coredump_gdbserver.py --pipe build/zephyr/zephyr.elf coredump.bin
File Format
***********

Expand Down
41 changes: 32 additions & 9 deletions scripts/coredump/coredump_gdbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,23 @@
GDBSERVER_HOST = ""


class FakeSocket:
def __init__(self) -> None:
self.in_stream = sys.stdin.buffer
self.out_stream = sys.stdout.buffer

def recv(self, bufsize):
return self.in_stream.read(bufsize)

def send(self, data):
n = self.out_stream.write(data)
self.out_stream.flush()
return n

def close(self):
pass


def parse_args():
parser = argparse.ArgumentParser(allow_abbrev=False)

Expand All @@ -30,6 +47,8 @@ def parse_args():
help="Print extra debugging information")
parser.add_argument("--port", type=int, default=1234,
help="GDB server port")
parser.add_argument("--pipe", action="store_true",
help="Use stdio to communicate with gdb")
parser.add_argument("-v", "--verbose", action="store_true",
help="Print more information")

Expand Down Expand Up @@ -99,19 +118,23 @@ def main():

gdbstub = gdbstubs.get_gdbstub(logf, elff)

# Start a GDB server
gdbserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if not args.pipe:
# Start a GDB server
gdbserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Reuse address so we don't have to wait for socket to be
# close before we can bind to the port again
gdbserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Reuse address so we don't have to wait for socket to be
# close before we can bind to the port again
gdbserver.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

gdbserver.bind((GDBSERVER_HOST, args.port))
gdbserver.listen(1)
gdbserver.bind((GDBSERVER_HOST, args.port))
gdbserver.listen(1)

logger.info(f"Waiting GDB connection on port {args.port}...")
logger.info(f"Waiting GDB connection on port {args.port}...")

conn, remote = gdbserver.accept()
conn, remote = gdbserver.accept()
else:
conn = FakeSocket()
remote = "pipe"

if conn:
logger.info(f"Accepted GDB connection from {remote}")
Expand Down

0 comments on commit bcf98ea

Please sign in to comment.