mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-05-07 04:58:57 +00:00
4526637250
Returning from the finally block at the end of the start_fvp() function is discarding exceptions. Since start_fvp() is near to the top off the call tree, this hides uncaught exceptions thrown by most of the code, which makes detecting and debugging issues hard. This is resolved by removing the return statement from the finally block, allowing exceptions to propagate normally. Signed-off-by: Gyorgy Szing <gyorgy.szing@arm.com> Signed-off-by: Jon Mason <jon.mason@arm.com>
118 lines
4.1 KiB
Python
Executable File
118 lines
4.1 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
|
|
import itertools
|
|
import os
|
|
import pathlib
|
|
import signal
|
|
import sys
|
|
import threading
|
|
|
|
import logging
|
|
logger = logging.getLogger("RunFVP")
|
|
|
|
# Add meta-arm/lib/ to path
|
|
libdir = pathlib.Path(__file__).parents[1] / "meta-arm" / "lib"
|
|
sys.path.insert(0, str(libdir))
|
|
|
|
from fvp import conffile, terminal, runner
|
|
|
|
def parse_args(arguments):
|
|
import argparse
|
|
terminals = terminal.terminals
|
|
|
|
parser = argparse.ArgumentParser(description="Run images in a FVP")
|
|
parser.add_argument("config", nargs="?", help="Machine name or path to .fvpconf file")
|
|
group = parser.add_mutually_exclusive_group()
|
|
available_terminals=",".join(terminals.available_terminals())
|
|
group.add_argument("-t", "--terminals", choices=terminals.all_terminals(), default=terminals.preferred_terminal(), help=f"Automatically start terminals (default: %(default)s). Available terminals are ({available_terminals})")
|
|
group.add_argument("-c", "--console", action="store_true", help="Attach the first uart to stdin/stdout")
|
|
parser.add_argument("--verbose", action="store_true", help="Output verbose logging")
|
|
parser.usage = f"{parser.format_usage().strip()} -- [ arguments passed to FVP ]"
|
|
# TODO option for telnet vs netcat
|
|
|
|
# If the arguments contains -- then everything after it should be passed to the FVP binary directly.
|
|
if "--" in arguments:
|
|
i = arguments.index("--")
|
|
fvp_args = arguments[i+1:]
|
|
arguments = arguments[:i]
|
|
else:
|
|
fvp_args = []
|
|
|
|
args = parser.parse_args(args=arguments)
|
|
logging.basicConfig(level=args.verbose and logging.DEBUG or logging.WARNING,
|
|
format='\033[G%(levelname)s: %(message)s')
|
|
|
|
# If we're hooking up the console, don't start any terminals
|
|
if args.console:
|
|
args.terminals = "none"
|
|
|
|
logger.debug(f"Parsed arguments: {vars(args)}")
|
|
logger.debug(f"FVP arguments: {fvp_args}")
|
|
return args, fvp_args
|
|
|
|
def start_fvp(args, fvpconf, extra_args):
|
|
fvp = runner.FVPRunner(logger)
|
|
try:
|
|
|
|
if args.terminals:
|
|
if not terminal.terminals[args.terminals].is_ready():
|
|
return 1
|
|
|
|
fvp.start(fvpconf, extra_args, args.terminals)
|
|
|
|
if args.console:
|
|
config = fvp.getConfig()
|
|
expected_terminal = config["consoles"].get("default")
|
|
if expected_terminal is None:
|
|
logger.error("--console used but FVP_CONSOLE not set in machine configuration")
|
|
return 1
|
|
port_stdout, log_stdout = itertools.tee(fvp.stdout, 2)
|
|
parser = runner.ConsolePortParser(port_stdout)
|
|
port = parser.parse_port(expected_terminal)
|
|
|
|
def debug_log():
|
|
for line in log_stdout:
|
|
line = line.strip().decode(errors='ignore')
|
|
logger.debug(f'FVP output: {line}')
|
|
log_thread = threading.Thread(None, debug_log)
|
|
log_thread.start()
|
|
|
|
telnet = fvp.create_telnet(port)
|
|
telnet.wait()
|
|
logger.debug(f"Telnet quit, cancelling tasks")
|
|
else:
|
|
for line in fvp.stdout:
|
|
print(line.strip().decode(errors='ignore'))
|
|
except FileNotFoundError as e:
|
|
logger.error(f"FVP executable not found ({e})")
|
|
finally:
|
|
rv=fvp.stop()
|
|
|
|
return rv
|
|
|
|
def runfvp(cli_args):
|
|
args, extra_args = parse_args(cli_args)
|
|
if args.config and pathlib.Path(args.config).exists():
|
|
config_file = args.config
|
|
else:
|
|
config_file = conffile.find(args.config)
|
|
return start_fvp(args, config_file, extra_args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
# Set the process group so that it's possible to kill runfvp and
|
|
# everything it spawns easily.
|
|
# Ignore permission errors happening when spawned from an other process
|
|
# for example run from except
|
|
try:
|
|
os.setpgid(0, 0)
|
|
except PermissionError:
|
|
pass
|
|
if sys.stdin.isatty():
|
|
signal.signal(signal.SIGTTOU, signal.SIG_IGN)
|
|
os.tcsetpgrp(sys.stdin.fileno(), os.getpgrp())
|
|
sys.exit(runfvp(sys.argv[1:]))
|
|
except KeyboardInterrupt:
|
|
pass
|