1010
1111import argparse
1212import json
13+ import platform
1314import re
1415from pathlib import Path
1516
17+ import host_tools .cargo_build as build_tools
1618from framework .artifacts import disks , kernels
17- from framework .defs import DEFAULT_BINARY_DIR
19+ from framework .defs import DEFAULT_BINARY_DIR , LOCAL_BUILD_PATH
1820from framework .microvm import MicroVMFactory
1921
2022kernels = list (kernels ("vmlinux-*" ))
@@ -58,12 +60,31 @@ def parse_byte_size(param):
5860parser .add_argument ("--rootfs-size" , type = parse_byte_size , default = 1 * 2 ** 30 ) # 1GB
5961parser .add_argument ("--binary-dir" , help = "Path to the firecracker binaries" )
6062parser .add_argument ("--cpu-template-path" , help = "CPU template to use" , type = Path )
63+ parser .add_argument (
64+ "--debug" , action = "store_true" , default = False , help = "Use debug kernel"
65+ )
66+ parser .add_argument (
67+ "--gdb" , action = "store_true" , default = False , help = "Connect to Firecracker guest GDB"
68+ )
6169args = parser .parse_args ()
6270print (args )
6371
6472binary_dir = None
6573if args .binary_dir :
6674 binary_dir = Path (args .binary_dir ).resolve ()
75+ elif args .gdb :
76+ # Build Firecracker with GDB feature if needed
77+ print ("Building Firecracker with GDB feature..." )
78+ machine = platform .machine ()
79+ target = f"{ machine } -unknown-linux-musl"
80+ build_dir = LOCAL_BUILD_PATH / "gdb"
81+ build_tools .cargo (
82+ "build" ,
83+ f"--features gdb --target { target } --all" ,
84+ env = {"CARGO_TARGET_DIR" : build_dir },
85+ )
86+ print ("Build complete!" )
87+ binary_dir = build_dir / target / "debug"
6788else :
6889 binary_dir = DEFAULT_BINARY_DIR
6990
@@ -72,28 +93,26 @@ def parse_byte_size(param):
7293 cpu_template = json .loads (args .cpu_template_path .read_text ())
7394vmfcty = MicroVMFactory (binary_dir )
7495
75- print (f"uvm with kernel { args .kernel } ..." )
76- uvm = vmfcty .build (args .kernel , args .rootfs )
96+ if args .debug or args .gdb :
97+ kernel = args .kernel .parent / "debug" / args .kernel .name
98+ else :
99+ kernel = args .kernel
100+
101+ print (f"uvm with kernel { kernel } ..." )
102+ uvm = vmfcty .build (kernel , args .rootfs )
77103uvm .help .enable_console ()
78104uvm .help .resize_disk (uvm .rootfs_file , args .rootfs_size )
79- uvm .spawn (log_show_level = True )
105+ uvm .spawn (log_show_level = True , validate_api = False )
80106uvm .help .print_log ()
81107uvm .add_net_iface ()
82108uvm .basic_config (vcpu_count = args .vcpus , mem_size_mib = args .guest_mem_size // 2 ** 20 )
83109if cpu_template is not None :
84110 uvm .api .cpu_config .put (** cpu_template )
85111 print (cpu_template )
112+
113+ if args .gdb :
114+ uvm .enable_gdb ()
115+ uvm .help .tmux_gdb ()
116+
86117uvm .start ()
87118uvm .get_all_metrics ()
88-
89- kernel_dbg_dir = args .kernel .parent / "debug"
90- kernel_dbg = kernel_dbg_dir / args .kernel .name
91- print (f"uvm2 with kernel { kernel_dbg } ..." )
92- uvm2 = vmfcty .build (kernel_dbg , args .rootfs )
93- uvm2 .spawn ()
94- uvm2 .add_net_iface ()
95- uvm2 .basic_config (vcpu_count = args .vcpus , mem_size_mib = args .guest_mem_size // 2 ** 20 )
96- uvm2 .start ()
97- # trace-cmd needs this (DNS resolution?)
98- uvm2 .help .enable_ip_forwarding ()
99- files = uvm2 .help .trace_cmd_guest (["-l" , "read_msr" ], cmd = "sleep 5" )
0 commit comments