Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

RemoteUnwinder.get_stack_trace is missing exceptions on some error code paths #144316

Copy link
Copy link
@colesbury

Description

@colesbury
Issue body actions

Bug report

On a PR recently, I saw the following crash in test_external_inspection. I don't think the crash is related to the PR:

Test that frame cache is per-thread and cache invalidation works independently. ... Assertion failed: (res_o != NULL) ^ (_PyErr_Occurred(tstate) != NULL), file C:\a\cpython\cpython\Python\generated_cases.c.h, line 3938
Fatal Python error: Aborted

<Cannot show all threads while the GIL is disabled>
Stack (most recent call first):
  File "C:\a\cpython\cpython\Lib\test\test_external_inspection.py", line 2702 in _get_frames_with_retry
  File "C:\a\cpython\cpython\Lib\test\test_external_inspection.py", line 3268 in test_cache_per_thread_isolation
  File "C:\a\cpython\cpython\Lib\unittest\case.py", line 613 in _callTestMethod
  File "C:\a\cpython\cpython\Lib\unittest\case.py", line 667 in run
  File "C:\a\cpython\cpython\Lib\unittest\case.py", line 723 in __call__
  File "C:\a\cpython\cpython\Lib\unittest\suite.py", line 122 in run
  File "C:\a\cpython\cpython\Lib\unittest\suite.py", line 84 in __call__
  File "C:\a\cpython\cpython\Lib\unittest\suite.py", line 122 in run
  File "C:\a\cpython\cpython\Lib\unittest\suite.py", line 84 in __call__
  File "C:\a\cpython\cpython\Lib\unittest\runner.py", line 257 in run
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 84 in _run_suite
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 42 in run_unittest
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 162 in test_func
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 118 in regrtest_runner
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 165 in _load_run_test
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 210 in _runtest_env_changed_exc
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 319 in _runtest
  File "C:\a\cpython\cpython\Lib\test\libregrtest\single.py", line 348 in run_single_test
  File "C:\a\cpython\cpython\Lib\test\libregrtest\worker.py", line 99 in worker_process
  File "C:\a\cpython\cpython\Lib\test\libregrtest\worker.py", line 134 in main
  File "C:\a\cpython\cpython\Lib\test\libregrtest\worker.py", line 138 in <module>
  File "C:\a\cpython\cpython\Lib\runpy.py", line 87 in _run_code
  File "C:\a\cpython\cpython\Lib\runpy.py", line 196 in _run_module_as_main

I think that's in the call to _remote_debugging.RemoteUnwinder.get_stack_trace. Either it's returning NULL without an exception set or it's returning non-NULL with an exception.

I asked Claude to find the missing exceptions and it came up with the following:

  Missing Exception Error Paths

  1. asyncio.c:119-122 - Set object validation
  if (mask < 0 || mask >= MAX_SET_TABLE_SIZE || num_els < 0 || num_els > mask + 1) {
      set_exception_cause(unwinder, PyExc_RuntimeError,
          "Invalid set object (corrupted remote memory)");
      return -1;
  }
  2. object_reading.c:198-201 - PyLong size validation
  if (size < 0 || size > MAX_LONG_DIGITS) {
      set_exception_cause(unwinder, PyExc_RuntimeError,
          "Invalid PyLong size (corrupted remote memory)");
      return -1;
  }
  3. frames.c:50-54 - Stack chunk size validation
  if (actual_size <= offsetof(_PyStackChunk, data) || actual_size > MAX_STACK_CHUNK_SIZE) {
      PyMem_RawFree(this_chunk);
      set_exception_cause(unwinder, PyExc_RuntimeError,
          "Invalid stack chunk size (corrupted remote memory)");
      return -1;
  }
  4. code_objects.c:448-451 - TLBC index validation
  if (ctx->tlbc_index < 0 || ctx->tlbc_index >= tlbc_entry->tlbc_array_size) {
      set_exception_cause(unwinder, PyExc_RuntimeError,
          "Invalid tlbc_index (corrupted remote memory)");
      goto error;
  }
  5. module.c:596-601 - Thread list cycle detection
  if (current_tstate == prev_tstate) {
      Py_DECREF(interpreter_threads);
      set_exception_cause(self, PyExc_RuntimeError,
          "Thread list cycle detected (corrupted remote memory)");
      Py_CLEAR(result);
      goto exit;
  }

The set_exception_cause macro only sets an exception if unwinder->debug is set.

cc @pablogsal

Linked PRs

Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Labels

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.