Skip to content

Commit e32aed2

Browse files
committed
more wip
1 parent cf582be commit e32aed2

File tree

2 files changed

+36
-14
lines changed

2 files changed

+36
-14
lines changed

coverage/sysmon.py

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,10 @@ def log(msg: str) -> None:
115115
# f"{root}-{pid}-{tslug}.out",
116116
]:
117117
with open(filename, "a") as f:
118-
print(f"{pid}:{tslug}: {msg}", file=f, flush=True)
118+
try:
119+
print(f"{pid}:{tslug}: {msg}", file=f, flush=True)
120+
except UnicodeError:
121+
print(f"{pid}:{tslug}: {ascii(msg)}", file=f, flush=True)
119122

120123
def arg_repr(arg: Any) -> str:
121124
"""Make a customized repr for logged values."""
@@ -214,6 +217,7 @@ def populate_branch_trails(code: CodeType, code_info: CodeInfo) -> None:
214217
"""
215218
Populate the `branch_trails` attribute on `code_info`.
216219
"""
220+
log(f"populate_branch_trails: {code}")
217221
iwalker = InstructionWalker(code)
218222
for inst in iwalker.walk(follow_jumps=False):
219223
log(f"considering {inst=}")
@@ -225,7 +229,8 @@ def populate_branch_trails(code: CodeType, code_info: CodeInfo) -> None:
225229
continue
226230

227231
from_line = inst.line_number
228-
assert from_line is not None
232+
if from_line is None:
233+
continue
229234

230235
def walk_one_branch(
231236
start_at: TOffset, branch_kind: str
@@ -255,14 +260,19 @@ def walk_one_branch(
255260
)
256261
return inst_offsets, (from_line, to_line)
257262
else:
258-
log(f" no possible branch from @{start_at}: {inst_offsets}")
263+
log(f"no possible branch from @{start_at}: {inst_offsets}")
259264
return [], None
260265

261-
code_info.branch_trails[inst.offset] = (
266+
trails = [
262267
walk_one_branch(start_at=inst.offset + 2, branch_kind="not-taken"),
263268
walk_one_branch(start_at=inst.jump_target, branch_kind="taken"),
264-
)
265-
269+
]
270+
code_info.branch_trails[inst.offset] = trails
271+
for trail in trails:
272+
for offset in trail[0]:
273+
if offset not in code_info.branch_trails:
274+
code_info.branch_trails[offset] = []
275+
code_info.branch_trails[offset].append(trail)
266276

267277
@dataclass
268278
class CodeInfo:
@@ -272,18 +282,15 @@ class CodeInfo:
272282
file_data: TTraceFileData | None
273283
byte_to_line: dict[TOffset, TLineNo] | None
274284
# Keys are start instruction offsets for branches.
275-
# Values are two tuples:
276-
# (
285+
# Values are lists:
286+
# [
277287
# ([offset, offset, ...], (from_line, to_line)),
278288
# ([offset, offset, ...], (from_line, to_line)),
279-
# )
289+
# ]
280290
# Two possible trails from the branch point, left and right.
281291
branch_trails: dict[
282292
TOffset,
283-
tuple[
284-
tuple[list[TOffset], TArc | None],
285-
tuple[list[TOffset], TArc | None],
286-
],
293+
list[tuple[list[TOffset], TArc | None]],
287294
]
288295

289296

@@ -448,6 +455,7 @@ def sysmon_py_start( # pylint: disable=useless-return
448455
)
449456
self.code_infos[id(code)] = code_info
450457
populate_branch_trails(code, code_info) # TODO: should be a method?
458+
log(f"branch_trails for {code}:\n {code_info.branch_trails}")
451459
self.code_objects.append(code)
452460

453461
if tracing_code:
@@ -509,6 +517,7 @@ def sysmon_branch_either(
509517
) -> MonitorReturn:
510518
"""Handle BRANCH_RIGHT and BRANCH_LEFT events."""
511519
code_info = self.code_infos[id(code)]
520+
added_arc = False
512521
if code_info.file_data is not None:
513522
dest_info = code_info.branch_trails.get(instruction_offset)
514523
log(f"{dest_info = }")
@@ -519,4 +528,17 @@ def sysmon_branch_either(
519528
if destination_offset in offsets:
520529
cast(set[TArc], code_info.file_data).add(arc)
521530
log(f"adding {arc=}")
531+
added_arc = True
532+
break
533+
534+
if not added_arc:
535+
# This could be an exception jumping from line to line.
536+
assert code_info.byte_to_line is not None
537+
l1 = code_info.byte_to_line[instruction_offset]
538+
l2 = code_info.byte_to_line[destination_offset]
539+
if l1 != l2:
540+
arc = (l1, l2)
541+
cast(set[TArc], code_info.file_data).add(arc)
542+
log(f"adding unforeseen {arc=}")
543+
522544
return DISABLE

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[tox]
55
# When changing this list, be sure to check the [gh] list below.
66
# PYVERSIONS
7-
envlist = py3{9,10,11,12,13,14}, pypy3, doc, lint, mypy
7+
envlist = py3{9,10,11,12,13,14}, pypy3, anypy, doc, lint, mypy
88
skip_missing_interpreters = {env:COVERAGE_SKIP_MISSING_INTERPRETERS:True}
99
toxworkdir = {env:TOXWORKDIR:.tox}
1010

0 commit comments

Comments
 (0)