Files
Sprinter-SDCC/tests/sdbg/run_macro_log_probe.py
T
2026-09-17 22:57:27 +03:00

90 lines
4.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""Живой DAP-проход: C-макрос → breakpoint → обе console без DSS-вывода."""
from __future__ import annotations
import json
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import time
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(Path(__file__).resolve().parent))
sys.path.insert(0, str(ROOT/'toolchain'))
from run_vscode_dap_probe import receive, send, wait_response
from sdbg.server import rpc_call
def main():
provider = 'osx' if '--osx' in sys.argv else 'sdbg'
source = ROOT/'tests/sdbg/fixtures/logmacro.c'
with tempfile.TemporaryDirectory(prefix='sprinter-macro-live-') as temp:
exe = Path(temp)/'logmacro.exe'
build = subprocess.run([str(ROOT/'bin/sprinter-cc'), '-o', str(exe),
'--src-debug', str(source)], cwd=ROOT,
env=dict(os.environ, SPRINTER_PYTHON=sys.executable),
capture_output=True, text=True)
if build.returncode:
raise RuntimeError('Не собрано приложение с SDBG_LOG: '+build.stdout+build.stderr)
process = subprocess.Popen([sys.executable, str(ROOT/'toolchain/sdbg_dap.py')], cwd=ROOT,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
buffer = b''
try:
send(process, 1, 'initialize')
_, buffer, _ = wait_response(process, buffer, 'initialize', 10)
send(process, 2, 'launch', {'build': str(exe.with_name('.sprinter-cc-logmacro')),
'debugger': provider, 'dssTimeout': 30})
launched, buffer, events = wait_response(process, buffer, 'launch', 80)
if not any(event.get('event') == 'initialized' for event in events):
event, buffer = receive(process, buffer, 5)
if event.get('event') != 'initialized':
raise RuntimeError('Нет DAP initialized: '+str(event))
send(process, 3, 'configurationDone')
_, buffer, _ = wait_response(process, buffer, 'configurationDone', 10)
send(process, 4, 'stackTrace')
frames, buffer, _ = wait_response(process, buffer, 'stackTrace', 10)
if not frames['body']['stackFrames'][0]['name'].startswith('main'):
raise RuntimeError('Перед стартом нет main: '+str(frames['body']['stackFrames']))
send(process, 5, 'continue')
_, buffer, events = wait_response(process, buffer, 'continue', 10)
outputs = [event for event in events if event.get('event') == 'output']
deadline = time.monotonic()+25
while not any('total=1\n' == event.get('body', {}).get('output') for event in outputs):
if time.monotonic() >= deadline:
raise RuntimeError('SDBG_LOG не пришёл в DAP Debug Console: '+str(outputs[-4:]))
event, buffer = receive(process, buffer, deadline-time.monotonic())
if event.get('event') == 'terminated':
raise RuntimeError('DAP завершился до авторского лога')
if event.get('event') == 'output': outputs.append(event)
socket = launched['body']['socket']
identity = rpc_call(socket, 'status')
tail = rpc_call(socket, 'mame_console_tail', {'count': 50}, timeout=6,
session_id=identity['session_id'],
build_id=identity['build_id'])
if not any('total=1' in line for line in tail['lines']):
raise RuntimeError('В debugger console MAME нет total=1: '+str(tail))
print(json.dumps({'event': 'macro_dual_console_verified',
'provider': provider, 'dap_output': 'total=1',
'mame_console': [line for line in tail['lines'] if 'total=1' in line],
'entry': launched['body']['entry']}, ensure_ascii=False), flush=True)
send(process, 6, 'disconnect')
wait_response(process, buffer, 'disconnect', 10)
finally:
if process.poll() is None: process.terminate()
try: _, stderr = process.communicate(timeout=8)
except subprocess.TimeoutExpired:
process.kill()
_, stderr = process.communicate()
if stderr:
print(stderr.decode(errors='replace')[-3000:], file=sys.stderr)
if __name__ == '__main__':
try: main()
except (RuntimeError, TimeoutError, OSError, KeyError, ValueError) as error:
print('macro-log-probe: '+str(error), file=sys.stderr)
sys.exit(1)