validate_lldb.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/env python3
  2. #
  3. # Copyright (C) 2023 Intel Corporation. All rights reserved.
  4. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  5. #
  6. import argparse
  7. import time
  8. from pathlib import Path
  9. import subprocess, shlex
  10. SCRIPT_DIR = Path(__file__).parent.resolve()
  11. REPO_ROOT_DIR = SCRIPT_DIR.parent
  12. SAMPLE_CODE_FILE = REPO_ROOT_DIR / 'product-mini/app-samples/hello-world/main.c'
  13. WASM_OUT_FILE = SCRIPT_DIR / 'out.wasm'
  14. parser = argparse.ArgumentParser(
  15. description="Validate the customized lldb with sample code"
  16. )
  17. parser.add_argument(
  18. "-l", "--lldb", dest='lldb', default='lldb', help="path to lldb executable"
  19. )
  20. parser.add_argument(
  21. "-w", "--wamr", dest='wamr', default='iwasm', help="path to iwasm executable"
  22. )
  23. parser.add_argument(
  24. "-p", "--port", dest='port', default='1234', help="debug server listen port"
  25. )
  26. parser.add_argument(
  27. "-v", "--verbose", dest='verbose', action='store_true', default=False, help="display lldb stdout"
  28. )
  29. options = parser.parse_args()
  30. lldb_command_prologue = f'{options.lldb} -o "process connect -p wasm connect://127.0.0.1:{options.port}"'
  31. lldb_command_epilogue = '-o q'
  32. test_cases = {
  33. 'run_to_exit': '-o c',
  34. 'func_breakpoint': '-o "b main" -o c -o c',
  35. 'line_breakpoint': '-o "b main.c:12" -o c -o c',
  36. 'break_on_unknown_func': '-o "b not_a_func" -o c',
  37. 'watch_point': '-o "b main" -o c -o "watchpoint set variable buf" -o c -o "fr v buf" -o c',
  38. }
  39. # Step1: Build wasm module with debug information
  40. build_cmd = f'/opt/wasi-sdk/bin/clang -g -O0 -o {WASM_OUT_FILE} {SAMPLE_CODE_FILE}'
  41. try:
  42. print(f'building wasm module ...', end='', flush=True)
  43. subprocess.check_call(shlex.split(build_cmd))
  44. print(f'\t OK')
  45. except subprocess.CalledProcessError:
  46. print("Failed to build wasm module with debug information")
  47. exit(1)
  48. def print_process_output(p):
  49. try:
  50. outs, errs = p.communicate(timeout=2)
  51. print("stdout:")
  52. print(outs)
  53. print("stderr:")
  54. print(errs)
  55. except subprocess.TimeoutExpired:
  56. print("Failed to get process output")
  57. # Step2: Launch WAMR in debug mode and validate lldb commands
  58. wamr_cmd = f'{options.wamr} -g=127.0.0.1:{options.port} {WASM_OUT_FILE}'
  59. for case, cmd in test_cases.items():
  60. has_error = False
  61. print(f'validating case [{case}] ...', end='', flush=True)
  62. lldb_cmd = f'{lldb_command_prologue} {cmd} {lldb_command_epilogue}'
  63. wamr_process = subprocess.Popen(shlex.split(
  64. wamr_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
  65. time.sleep(0.1)
  66. if (wamr_process.poll() != None):
  67. print("\nWAMR doesn't wait for lldb connection")
  68. print_process_output(wamr_process)
  69. exit(1)
  70. lldb_process = subprocess.Popen(shlex.split(
  71. lldb_cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
  72. if (options.verbose):
  73. while (lldb_process.poll() is None):
  74. print(lldb_process.stdout.read(), end='', flush=True)
  75. try:
  76. if (lldb_process.wait(5) != 0):
  77. print(f"\nFailed to validate case [{case}]")
  78. print_process_output(lldb_process)
  79. has_error = True
  80. if wamr_process.wait(2) != 0:
  81. print("\nWAMR process doesn't exit normally")
  82. print_process_output(wamr_process)
  83. has_error = True
  84. except subprocess.TimeoutExpired:
  85. print(f"\nFailed to validate case [{case}]")
  86. print("wamr output:")
  87. print_process_output(wamr_process)
  88. print("lldb output:")
  89. print_process_output(lldb_process)
  90. has_error = True
  91. finally:
  92. if (lldb_process.poll() == None):
  93. print(f'\nterminating lldb process [{lldb_process.pid}]')
  94. lldb_process.kill()
  95. if (wamr_process.poll() == None):
  96. print(f'terminating wamr process [{wamr_process.pid}]')
  97. wamr_process.kill()
  98. if (has_error):
  99. exit(1)
  100. print(f'\t OK')
  101. # wait 100ms to ensure the socket is closed
  102. time.sleep(0.1)
  103. print('Validate lldb success')
  104. exit(0)