|
1 | 1 | import unittest |
2 | 2 | import os |
3 | | -import json |
4 | 3 | import textwrap |
5 | 4 | import contextlib |
6 | 5 | import importlib |
@@ -419,91 +418,6 @@ def _frame_to_lineno_tuple(frame): |
419 | 418 | filename, location, funcname, opcode = frame |
420 | 419 | return (filename, location.lineno, funcname, opcode) |
421 | 420 |
|
422 | | - @contextmanager |
423 | | - def _poisoned_debug_offsets_process(self, poison_code): |
424 | | - script = ( |
425 | | - textwrap.dedent( |
426 | | - """\ |
427 | | - import json |
428 | | - import os |
429 | | - import struct |
430 | | - import sys |
431 | | - import threading |
432 | | - import time |
433 | | -
|
434 | | - cookie = b"xdebugpy" |
435 | | - pid = os.getpid() |
436 | | -
|
437 | | - def find_debug_offsets(): |
438 | | - with open(f"/proc/{pid}/maps") as f: |
439 | | - for line in f: |
440 | | - parts = line.split() |
441 | | - if len(parts) < 2 or "rw" not in parts[1]: |
442 | | - continue |
443 | | - start, end = (int(x, 16) for x in parts[0].split("-")) |
444 | | - if end - start > 10_000_000: |
445 | | - continue |
446 | | - try: |
447 | | - fd = os.open(f"/proc/{pid}/mem", os.O_RDONLY) |
448 | | - os.lseek(fd, start, 0) |
449 | | - data = os.read(fd, end - start) |
450 | | - os.close(fd) |
451 | | - except OSError: |
452 | | - continue |
453 | | - off = data.find(cookie) |
454 | | - if off == -1: |
455 | | - continue |
456 | | - version = struct.unpack_from("<Q", data, off + 8)[0] |
457 | | - if ((version >> 24) & 0xFF) != sys.version_info.major: |
458 | | - continue |
459 | | - return start + off |
460 | | - raise RuntimeError("debug offsets not found") |
461 | | -
|
462 | | - addr = find_debug_offsets() |
463 | | - """ |
464 | | - ) |
465 | | - + textwrap.dedent(poison_code) |
466 | | - + "\n" |
467 | | - + textwrap.dedent( |
468 | | - """\ |
469 | | - print( |
470 | | - json.dumps({"pid": pid, "native_tid": threading.get_native_id()}), |
471 | | - flush=True, |
472 | | - ) |
473 | | - time.sleep(60) |
474 | | - """ |
475 | | - ) |
476 | | - ) |
477 | | - |
478 | | - proc = subprocess.Popen( |
479 | | - [sys.executable, "-c", script], |
480 | | - stdout=subprocess.PIPE, |
481 | | - stderr=subprocess.PIPE, |
482 | | - text=True, |
483 | | - ) |
484 | | - try: |
485 | | - line = proc.stdout.readline() |
486 | | - if not line: |
487 | | - stderr = proc.stderr.read() |
488 | | - self.fail( |
489 | | - "poisoned child failed to initialize: " |
490 | | - f"{stderr.strip() or 'no stderr output'}" |
491 | | - ) |
492 | | - yield proc, json.loads(line) |
493 | | - finally: |
494 | | - try: |
495 | | - proc.terminate() |
496 | | - proc.wait(timeout=SHORT_TIMEOUT) |
497 | | - except subprocess.TimeoutExpired: |
498 | | - proc.kill() |
499 | | - proc.wait(timeout=SHORT_TIMEOUT) |
500 | | - except OSError: |
501 | | - pass |
502 | | - if proc.stdout is not None: |
503 | | - proc.stdout.close() |
504 | | - if proc.stderr is not None: |
505 | | - proc.stderr.close() |
506 | | - |
507 | 421 | def _extract_coroutine_stacks_lineno_only(self, stack_trace): |
508 | 422 | """Extract coroutine stacks with line numbers only (no column offsets). |
509 | 423 |
|
|
0 commit comments