tools/minudumpserver: support auto start GDB and execute some commands

VELAPLATFO-16485

like
```bash
./nuttx/tools/minidumpserver.py -l log.log -e vela_ap.elf -a arm --gdb prebuilts/gcc/linux/arm/bin/arm-none-eabi-gdb -i
```

Signed-off-by: xinbingnan <xinbingnan@xiaomi.com>
This commit is contained in:
xinbingnan 2023-09-12 20:09:08 +08:00 committed by Xiang Xiao
parent 8d1cb466f4
commit a104fdc3a5

View File

@ -20,11 +20,13 @@
import argparse
import binascii
import logging
import multiprocessing
import os
import re
import shutil
import socket
import struct
import subprocess
import sys
import elftools
@ -39,6 +41,9 @@ SHF_ALLOC_EXEC = SHF_ALLOC | SHF_EXEC
GDB_SIGNAL_DEFAULT = 7
DEFAULT_GDB_INIT_CMD = "-ex 'bt full' -ex 'info reg' -ex 'display /40i $pc-40'"
logger = logging.getLogger()
reg_table = {
@ -605,7 +610,26 @@ def arg_parser():
choices=[arch for arch in reg_table.keys()],
)
parser.add_argument("-p", "--port", help="gdbport", type=int, default=1234)
parser.add_argument("--debug", action="store_true", default=False)
parser.add_argument(
"-g",
"--gdb",
help="provided a custom GDB path, automatically start GDB session and exit minidumpserver when exit GDB. ",
type=str,
)
parser.add_argument(
"-i",
"--init-cmd",
nargs="?",
default=argparse.SUPPRESS,
help="provided a custom GDB init command, automatically start GDB sessions and input what you provide. "
f"if you don't provide any command, it will use default command [{DEFAULT_GDB_INIT_CMD}]. ",
)
parser.add_argument(
"--debug",
action="store_true",
default=False,
help="if enabled, it will show more logs.",
)
return parser.parse_args()
@ -675,9 +699,9 @@ def main(args):
config_log(args.debug)
res = auto_parse_log_file(args.logfile)
selected_log = auto_parse_log_file(args.logfile)
log = DumpLogFile(res)
log = DumpLogFile(selected_log)
log.parse(args.arch)
elf = DumpELFFile(args.elffile)
elf.parse()
@ -693,9 +717,34 @@ def main(args):
gdbserver.bind(("", args.port))
gdbserver.listen(1)
gdb_exec = "gdb" if not args.gdb else args.gdb
gdb_init_cmd = ""
if hasattr(args, "init_cmd"):
if args.init_cmd is not None:
gdb_init_cmd = args.init_cmd.strip()
else:
gdb_init_cmd = DEFAULT_GDB_INIT_CMD
gdb_cmd = (
f"{gdb_exec} {args.elffile} -ex 'target remote localhost:{args.port}' "
f"{gdb_init_cmd}"
)
logger.info(f"Waiting GDB connection on port {args.port} ...")
logger.info("Press Ctrl+C to stop ...")
logger.info(f'Hint: gdb {args.elffile} -ex "target remote localhost:{args.port}"')
if not args.gdb:
logger.info("Press Ctrl+C to stop ...")
logger.info(f"Hint: {gdb_cmd}")
else:
logger.info(f"Run GDB command: {gdb_cmd}")
def gdb_run(cmd):
try:
subprocess.run(cmd, shell=True)
except KeyboardInterrupt:
pass
multiprocessing.Process(target=gdb_run, args=(gdb_cmd,)).start()
while True:
try: