Skip to content

Commit 68f8b9a

Browse files
committed
scripts: sof-qemu-run: add native_sim and valgrind support
Add native_sim board target to the sof-qemu-run scripts, and add an option to additionally run it under valgrind. The default build directory is set to ../build-native_sim Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
1 parent cae940d commit 68f8b9a

File tree

2 files changed

+75
-10
lines changed

2 files changed

+75
-10
lines changed

scripts/sof-qemu-run.py

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,12 @@ def main():
7676
parser = argparse.ArgumentParser(description="Run QEMU via west and automatically decode crashes.")
7777
parser.add_argument("--build-dir", default="build", help="Path to the build directory containing zephyr.elf, linker.cmd, etc. Defaults to 'build'.")
7878
parser.add_argument("--log-file", default="qemu-run.log", help="Path to save the QEMU output log. Defaults to 'qemu-run.log'.")
79+
parser.add_argument("--valgrind", action="store_true", help="Run the executable under Valgrind (only valid for native_sim).")
7980
args = parser.parse_args()
8081

8182
# Make absolute path just in case
83+
# The shell script cd's into `args.build_dir` before executing us, so `args.build_dir` might be relative to the shell script's pwd.
84+
# We resolve it relative to the python script's original invocation cwd.
8285
build_dir = os.path.abspath(args.build_dir)
8386

8487
print(f"Starting QEMU test runner. Monitoring for crashes (Build Dir: {args.build_dir})...")
@@ -91,7 +94,53 @@ def main():
9194
print("Please ensure you have sourced the Zephyr environment (e.g., source zephyr-env.sh).")
9295
sys.exit(1)
9396

94-
child = pexpect.spawn(west_path, ["-v", "build", "-t", "run"], encoding='utf-8')
97+
# Detect the board configuration from CMakeCache.txt
98+
is_native_sim = False
99+
100+
cmake_cache = os.path.join(build_dir, "CMakeCache.txt")
101+
102+
if os.path.isfile(cmake_cache):
103+
with open(cmake_cache, "r") as f:
104+
for line in f:
105+
if line.startswith("CACHED_BOARD:STRING=") or line.startswith("BOARD:STRING="):
106+
if "native_sim" in line.split("=", 1)[1].strip():
107+
is_native_sim = True
108+
break
109+
110+
# Determine execution command
111+
# If the user is running the python script directly from outside the workspace, we need to provide the source directory.
112+
# But if west finds it automatically (or we are in the build dir), providing `-s` might clear the CACHED_BOARD config.
113+
run_cmd = [west_path, "-v", "build", "-d", build_dir]
114+
115+
# Check if we are physically sitting inside the build directory
116+
if os.path.abspath(".") != os.path.abspath(build_dir):
117+
# We need to explicitly supply the app source to prevent west from crashing
118+
app_source_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "app"))
119+
run_cmd.extend(["-s", app_source_dir])
120+
121+
run_cmd.extend(["-t", "run"])
122+
123+
if args.valgrind:
124+
if not is_native_sim:
125+
print("[sof-qemu-run] Error: --valgrind is only supported for the native_sim board.")
126+
sys.exit(1)
127+
128+
print("[sof-qemu-run] Rebuilding before valgrind...")
129+
subprocess.run([west_path, "build", "-d", build_dir], check=True)
130+
131+
valgrind_path = shutil.which("valgrind")
132+
if not valgrind_path:
133+
print("[sof-qemu-run] Error: 'valgrind' command not found in PATH.")
134+
sys.exit(1)
135+
136+
exe_path = os.path.join(build_dir, "zephyr", "zephyr.exe")
137+
if not os.path.isfile(exe_path):
138+
print(f"[sof-qemu-run] Error: Executable not found at {exe_path}")
139+
sys.exit(1)
140+
141+
run_cmd = [valgrind_path, exe_path]
142+
143+
child = pexpect.spawn(run_cmd[0], run_cmd[1:], encoding='utf-8')
95144

96145
# We will accumulate output to check for crashes
97146
full_output = ""
@@ -157,11 +206,14 @@ def main():
157206

158207
run_sof_crash_decode(build_dir, full_output)
159208
else:
160-
print("\n[sof-qemu-run] No crash detected. Interacting with QEMU Monitor to grab registers...")
209+
if is_native_sim:
210+
print("\n[sof-qemu-run] No crash detected. (Skipping QEMU monitor interaction for native_sim)")
211+
else:
212+
print("\n[sof-qemu-run] No crash detected. Interacting with QEMU Monitor to grab registers...")
161213

162-
# We need to send Ctrl-A c to enter the monitor
163-
if child.isalive():
164-
child.send("\x01c") # Ctrl-A c
214+
# We need to send Ctrl-A c to enter the monitor
215+
if child.isalive():
216+
child.send("\x01c") # Ctrl-A c
165217
try:
166218
# Wait for (qemu) prompt
167219
child.expect(r"\(qemu\)", timeout=5)
@@ -185,8 +237,8 @@ def main():
185237
child.close(force=True)
186238
except pexpect.EOF:
187239
print("\n[sof-qemu-run] QEMU terminated before we could run monitor commands.")
188-
else:
189-
print("\n[sof-qemu-run] Process is no longer alive, cannot extract registers.")
240+
else:
241+
print("\n[sof-qemu-run] Process is no longer alive, cannot extract registers.")
190242

191243
if __name__ == "__main__":
192244
main()

scripts/sof-qemu-run.sh

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,21 @@
22
# SPDX-License-Identifier: BSD-3-Clause
33
# Copyright(c) 2026 Intel Corporation. All rights reserved.
44

5-
# Define the build directory from the first argument (or default)
6-
BUILD_DIR="${1:-build}"
5+
BUILD_DIR="../build-native_sim"
6+
VALGRIND_ARG=""
7+
8+
while [[ $# -gt 0 ]]; do
9+
case $1 in
10+
--valgrind)
11+
VALGRIND_ARG="--valgrind"
12+
shift
13+
;;
14+
*)
15+
BUILD_DIR="$1"
16+
shift
17+
;;
18+
esac
19+
done
720

821
# Find and source the zephyr environment script, typically via the sof-venv wrapper
922
# or directly if running in a known zephyrproject layout.
@@ -24,5 +37,5 @@ source ${VENV_DIR}/bin/activate
2437
cd "${BUILD_DIR}" || exit 1
2538

2639
# Finally run the python script which will now correctly inherit 'west' from the sourced environment.
27-
python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir "${BUILD_DIR}"
40+
python3 "${SCRIPT_DIR}/sof-qemu-run.py" --build-dir "${BUILD_DIR}" $VALGRIND_ARG
2841

0 commit comments

Comments
 (0)