mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Fix #1721 "runInTerminal" is broken on non-Windows platforms. Fix #1722: Output is not captured in "noDebug" with "runInTerminal" Groundwork for #1713: adapter: multiple concurrent sessions Move "launch" request parsing and debuggee process spawning, PID reporting and tracking, stdio "output" capture, and exit code reporting into launcher. Launcher now communicates to the adapter via a full-fledged message channel. Refactor adapter. Add an abstraction for a debug session, and treat IDE, launcher, and debug server as separate components managed by that session. Improve adapter logging to capture information about current debug session, and current message handler if any. Fix reporting exceptions from message handlers. Various test fixes.
143 lines
4.5 KiB
Python
143 lines
4.5 KiB
Python
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
# Licensed under the MIT License. See LICENSE in the project root
|
|
# for license information.
|
|
|
|
from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
|
|
import sys
|
|
from tests import debug
|
|
from tests.patterns import some
|
|
|
|
|
|
def test_with_path_mappings(pyfile, tmpdir, start_method, run_as):
|
|
@pyfile
|
|
def code_to_debug():
|
|
import debug_me # noqa
|
|
|
|
def full_function():
|
|
# Note that this function is not called, it's there just to make the mapping explicit.
|
|
print("cell1 line 2") # @map_to_cell1_line_2
|
|
print("cell1 line 3") # @map_to_cell1_line_3
|
|
|
|
print("cell2 line 2") # @map_to_cell2_line_2
|
|
print("cell2 line 3") # @map_to_cell2_line_3
|
|
|
|
def strip_lines(s):
|
|
return "\n".join([line.strip() for line in s.splitlines()])
|
|
|
|
def create_code():
|
|
cell1_code = compile(
|
|
strip_lines(
|
|
""" # line 1
|
|
a = 1 # line 2
|
|
b = 2 # line 3
|
|
"""
|
|
),
|
|
"<cell1>",
|
|
"exec",
|
|
)
|
|
|
|
cell2_code = compile(
|
|
strip_lines(
|
|
"""# line 1
|
|
c = 3 # line 2
|
|
d = 4 # line 3
|
|
"""
|
|
),
|
|
"<cell2>",
|
|
"exec",
|
|
)
|
|
|
|
return {"cell1": cell1_code, "cell2": cell2_code}
|
|
|
|
code = create_code()
|
|
exec(code["cell1"], {})
|
|
exec(code["cell1"], {})
|
|
|
|
exec(code["cell2"], {})
|
|
exec(code["cell2"], {})
|
|
print("ok")
|
|
|
|
with debug.Session(start_method) as session:
|
|
session.configure(run_as, code_to_debug)
|
|
|
|
map_to_cell_1_line2 = code_to_debug.lines["map_to_cell1_line_2"]
|
|
map_to_cell_2_line2 = code_to_debug.lines["map_to_cell2_line_2"]
|
|
|
|
source_entry = code_to_debug.strpath
|
|
if sys.platform == "win32":
|
|
# Check if it matches even not normalized.
|
|
source_entry = source_entry[0].lower() + source_entry[1:].upper()
|
|
source_entry = source_entry.replace("\\", "/")
|
|
|
|
# Set breakpoints first and the map afterwards to make sure that it's reapplied.
|
|
session.set_breakpoints(code_to_debug, [map_to_cell_1_line2])
|
|
|
|
session.request(
|
|
"setPydevdSourceMap",
|
|
{
|
|
"source": {"path": source_entry},
|
|
"pydevdSourceMaps": [
|
|
{
|
|
"line": map_to_cell_1_line2,
|
|
"endLine": map_to_cell_1_line2 + 1,
|
|
"runtimeSource": {"path": "<cell1>"},
|
|
"runtimeLine": 2,
|
|
},
|
|
{
|
|
"line": map_to_cell_2_line2,
|
|
"endLine": map_to_cell_2_line2 + 1,
|
|
"runtimeSource": {"path": "<cell2>"},
|
|
"runtimeLine": 2,
|
|
},
|
|
],
|
|
},
|
|
)
|
|
|
|
session.start_debugging()
|
|
session.wait_for_stop(
|
|
"breakpoint",
|
|
expected_frames=[some.dap.frame(code_to_debug, line=map_to_cell_1_line2)],
|
|
)
|
|
|
|
session.set_breakpoints(code_to_debug, [map_to_cell_2_line2])
|
|
# Leave only the cell2 mapping.
|
|
session.request(
|
|
"setPydevdSourceMap",
|
|
{
|
|
"source": {"path": source_entry},
|
|
"pydevdSourceMaps": [
|
|
{
|
|
"line": map_to_cell_2_line2,
|
|
"endLine": map_to_cell_2_line2 + 1,
|
|
"runtimeSource": {"path": "<cell2>"},
|
|
"runtimeLine": 2,
|
|
}
|
|
],
|
|
},
|
|
)
|
|
|
|
session.request("continue")
|
|
session.wait_for_stop(
|
|
"breakpoint",
|
|
expected_frames=[some.dap.frame(code_to_debug, line=map_to_cell_2_line2)],
|
|
)
|
|
|
|
# Remove the cell2 mapping so that it doesn't stop again.
|
|
session.request(
|
|
"setPydevdSourceMap",
|
|
{
|
|
"source": {"path": source_entry},
|
|
"pydevdSourceMaps": [
|
|
{
|
|
"line": map_to_cell_1_line2,
|
|
"endLine": map_to_cell_1_line2 + 1,
|
|
"runtimeSource": {"path": "<cell1>"},
|
|
"runtimeLine": 2,
|
|
}
|
|
],
|
|
},
|
|
)
|
|
|
|
session.request_continue()
|