FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-151022: Fix remote debugging linetable reads by goutamadwant · Pull Request #151036 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .py  (1) .rst  (1) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
50 changes: 50 additions & 0 deletions Lib/test/test_external_inspection.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,56 @@ def _extract_coroutine_stacks_lineno_only(self, stack_trace):
# ============================================================================


@requires_remote_subprocess_debugging()
class TestSelfStackTrace(RemoteInspectionTestBase):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@goutamadwant I think there's a missing @requires_remote_subprocess_debugging() decorator :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Fixed @maurycy.. added the missing @requires_remote_subprocess_debugging() decorator to the new test class.

@skip_if_not_supported
@unittest.skipIf(
sys.platform == "linux" and not PROCESS_VM_READV_SUPPORTED,
"Test only runs on Linux with process_vm_readv support",
)
def test_self_trace_with_large_linetable(self):
script = textwrap.dedent("""\
import os
import _remote_debugging

assignments = "\\n".join(
f"value_{i} = {i}" for i in range(1000)
)
expected_lineno = len(assignments.splitlines()) + 1
source = (
f"{assignments}\\n"
"stack_trace = "
"_remote_debugging.RemoteUnwinder(os.getpid()).get_stack_trace()\\n"
)
code = compile(source, "large_linetable.py", "exec")
assert len(code.co_linetable) > 4096, len(code.co_linetable)
namespace = {"os": os, "_remote_debugging": _remote_debugging}
exec(code, namespace)
large_linetable_frames = [
frame
for interpreter in namespace["stack_trace"]
for thread in interpreter.threads
for frame in thread.frame_info
if frame.filename == "large_linetable.py"
]
assert len(large_linetable_frames) == 1, large_linetable_frames
assert large_linetable_frames[0].location.lineno == expected_lineno, (
large_linetable_frames[0]
)
""")

result = subprocess.run(
[sys.executable, "-c", script],
capture_output=True,
text=True,
timeout=SHORT_TIMEOUT,
)
self.assertEqual(
result.returncode, 0,
f"stdout: {result.stdout}\nstderr: {result.stderr}"
Comment on lines +485 to +487

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@goutamadwant It would be interesting to ensure that the returned linetable is also correct, not -1 :-)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

@maurycy Updated this too. The test now checks the returned frame for large_linetable.py and asserts the resolved line number matches the generated RemoteUnwinder call line, so it should catch the -1 fallback case.

)


@requires_remote_subprocess_debugging()
class TestGetStackTrace(RemoteInspectionTestBase):
@skip_if_not_supported
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix ``_remote_debugging`` stack traces for code objects with large line
tables.
11 changes: 5 additions & 6 deletions Modules/_remote_debugging/code_objects.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

#include "_remote_debugging.h"

#define MAX_LINETABLE_SIZE (64 * 1024)

/* ============================================================================
* TLBC CACHING FUNCTIONS (Py_GIL_DISABLED only)
* ============================================================================ */
Expand Down Expand Up @@ -186,11 +188,7 @@ parse_linetable(const uintptr_t addrq, const char* linetable, Py_ssize_t linetab
int computed_line = firstlineno; // Running accumulator, separate from output
int val; // Temporary for varint results
uint8_t byte; // Temporary for byte reads
const size_t MAX_LINETABLE_ENTRIES = 65536;
size_t entry_count = 0;

while (ptr < end && *ptr != '\0' && entry_count < MAX_LINETABLE_ENTRIES) {
entry_count++;
while (ptr < end && *ptr != '\0') {
uint8_t first_byte = *(ptr++);
uint8_t code = (first_byte >> 3) & 15;
size_t length = (first_byte & 7) + 1;
Expand Down Expand Up @@ -387,7 +385,8 @@ parse_code_object(RemoteUnwinderObject *unwinder,
}

linetable = read_py_bytes(unwinder,
GET_MEMBER(uintptr_t, code_object, unwinder->debug_offsets.code_object.linetable), 4096);
GET_MEMBER(uintptr_t, code_object, unwinder->debug_offsets.code_object.linetable),
MAX_LINETABLE_SIZE);
if (!linetable) {
set_exception_cause(unwinder, PyExc_RuntimeError, "Failed to read linetable from code object");
goto error;
Expand Down
Loading

Back | FazBrowse Home | New Git URL