forked from bytecodealliance/wasm-micro-runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add scripts to validate lldb source debugger (bytecodealliance#2150)
- Loading branch information
1 parent
a6b2d54
commit b3255ed
Showing
2 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#!/usr/bin/env python3 | ||
# | ||
# Copyright (C) 2023 Intel Corporation. All rights reserved. | ||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
# | ||
|
||
import argparse | ||
import time | ||
from pathlib import Path | ||
import subprocess, shlex | ||
|
||
SCRIPT_DIR = Path(__file__).parent.resolve() | ||
REPO_ROOT_DIR = SCRIPT_DIR.parent | ||
SAMPLE_CODE_FILE = REPO_ROOT_DIR / 'product-mini/app-samples/hello-world/main.c' | ||
WASM_OUT_FILE = SCRIPT_DIR / 'out.wasm' | ||
|
||
parser = argparse.ArgumentParser( | ||
description="Validate the customized lldb with sample code" | ||
) | ||
parser.add_argument( | ||
"-l", "--lldb", dest='lldb', default='lldb', help="path to lldb executable" | ||
) | ||
parser.add_argument( | ||
"-w", "--wamr", dest='wamr', default='iwasm', help="path to iwasm executable" | ||
) | ||
parser.add_argument( | ||
"-p", "--port", dest='port', default='1234', help="debug server listen port" | ||
) | ||
parser.add_argument( | ||
"-v", "--verbose", dest='verbose', action='store_true', default=False, help="display lldb stdout" | ||
) | ||
|
||
options = parser.parse_args() | ||
|
||
lldb_command_prologue = f'{options.lldb} -o "process connect -p wasm connect://127.0.0.1:{options.port}"' | ||
lldb_command_epilogue = '-o q' | ||
|
||
test_cases = { | ||
'run_to_exit': '-o c', | ||
'func_breakpoint': '-o "b main" -o c -o c', | ||
'line_breakpoint': '-o "b main.c:12" -o c -o c', | ||
'break_on_unknown_func': '-o "b not_a_func" -o c', | ||
'watch_point': '-o "b main" -o c -o "watchpoint set variable buf" -o c -o "fr v buf" -o c', | ||
} | ||
|
||
# Step1: Build wasm module with debug information | ||
build_cmd = f'/opt/wasi-sdk/bin/clang -g -O0 -o {WASM_OUT_FILE} {SAMPLE_CODE_FILE}' | ||
try: | ||
print(f'building wasm module ...', end='', flush=True) | ||
subprocess.check_call(shlex.split(build_cmd)) | ||
print(f'\t OK') | ||
except subprocess.CalledProcessError: | ||
print("Failed to build wasm module with debug information") | ||
exit(1) | ||
|
||
def print_process_output(p): | ||
try: | ||
outs, errs = p.communicate(timeout=2) | ||
print("stdout:") | ||
print(outs) | ||
print("stderr:") | ||
print(errs) | ||
except subprocess.TimeoutExpired: | ||
print("Failed to get process output") | ||
|
||
# Step2: Launch WAMR in debug mode and validate lldb commands | ||
wamr_cmd = f'{options.wamr} -g=127.0.0.1:{options.port} {WASM_OUT_FILE}' | ||
for case, cmd in test_cases.items(): | ||
has_error = False | ||
print(f'validating case [{case}] ...', end='', flush=True) | ||
lldb_cmd = f'{lldb_command_prologue} {cmd} {lldb_command_epilogue}' | ||
|
||
wamr_process = subprocess.Popen(shlex.split( | ||
wamr_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | ||
|
||
time.sleep(0.1) | ||
if (wamr_process.poll() != None): | ||
print("\nWAMR doesn't wait for lldb connection") | ||
print_process_output(wamr_process) | ||
exit(1) | ||
|
||
lldb_process = subprocess.Popen(shlex.split( | ||
lldb_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) | ||
|
||
if (options.verbose): | ||
while (lldb_process.poll() is None): | ||
print(lldb_process.stdout.read(), end='', flush=True) | ||
|
||
try: | ||
if (lldb_process.wait(5) != 0): | ||
print(f"\nFailed to validate case [{case}]") | ||
print_process_output(lldb_process) | ||
has_error = True | ||
|
||
if wamr_process.wait(2) != 0: | ||
print("\nWAMR process doesn't exit normally") | ||
print_process_output(wamr_process) | ||
has_error = True | ||
|
||
except subprocess.TimeoutExpired: | ||
print(f"\nFailed to validate case [{case}]") | ||
print("wamr output:") | ||
print_process_output(wamr_process) | ||
print("lldb output:") | ||
print_process_output(lldb_process) | ||
has_error = True | ||
finally: | ||
if (lldb_process.poll() == None): | ||
print(f'\nterminating lldb process [{lldb_process.pid}]') | ||
lldb_process.kill() | ||
if (wamr_process.poll() == None): | ||
print(f'terminating wamr process [{wamr_process.pid}]') | ||
wamr_process.kill() | ||
|
||
if (has_error): | ||
exit(1) | ||
|
||
print(f'\t OK') | ||
|
||
# wait 100ms to ensure the socket is closed | ||
time.sleep(0.1) | ||
|
||
print('Validate lldb success') | ||
exit(0) |