Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ RUN apt-get update \
file \
less \
libcrypt-dev \
bear \
libzstd-dev \
liblzma-dev \
libbz2-dev \
Expand Down
1 change: 1 addition & 0 deletions news/279.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for Python subinterpreters. When a process uses multiple interpreters (e.g. via Python 3.14's ``concurrent.interpreters`` module), stacks for all interpreters are now reported instead of just the main one.
4 changes: 2 additions & 2 deletions src/pystack/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ._version import __version__
from .traceback_formatter import print_thread
from .traceback_formatter import print_threads

__all__ = [
"__version__",
"print_thread",
"print_threads",
]
14 changes: 7 additions & 7 deletions src/pystack/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from pystack.process import is_gzip

from . import errors
from . import print_thread
from . import print_threads
from .colors import colored
from .engine import CoreFileAnalyzer
from .engine import NativeReportingMode
Expand Down Expand Up @@ -287,14 +287,14 @@ def process_remote(parser: argparse.ArgumentParser, args: argparse.Namespace) ->
if not args.block and args.native_mode != NativeReportingMode.OFF:
parser.error("Native traces are only available in blocking mode")

for thread in get_process_threads(
threads = get_process_threads(
args.pid,
stop_process=args.block,
native_mode=args.native_mode,
locals=args.locals,
method=StackMethod.ALL if args.exhaustive else StackMethod.AUTO,
):
print_thread(thread, args.native_mode)
)
print_threads(threads, args.native_mode)


def format_psinfo_information(psinfo: Dict[str, Any]) -> str:
Expand Down Expand Up @@ -414,15 +414,15 @@ def process_core(parser: argparse.ArgumentParser, args: argparse.Namespace) -> N
elf_id if elf_id else "<MISSING>",
)

for thread in get_process_threads_for_core(
threads = get_process_threads_for_core(
corefile,
executable,
library_search_path=lib_search_path,
native_mode=args.native_mode,
locals=args.locals,
method=StackMethod.ALL if args.exhaustive else StackMethod.AUTO,
):
print_thread(thread, args.native_mode)
)
print_threads(threads, args.native_mode)


if __name__ == "__main__": # pragma: no cover
Expand Down
5 changes: 5 additions & 0 deletions src/pystack/_pystack.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ def get_process_threads_for_core(
def get_bss_info(binary: Union[str, pathlib.Path]) -> Optional[Dict[str, Any]]: ...
def copy_memory_from_address(pid: int, address: int, size: int) -> bytes: ...
def _check_interpreter_shutdown(manager: ProcessManager) -> None: ...
def is_eval_frame(symbol: str, python_version: Tuple[int, int]) -> bool: ...
def _normalize_threads_for_testing(
thread_descs: List[Dict[str, Any]],
native_mode: NativeReportingMode,
) -> List[PyThread]: ...

F = TypeVar("F", bound=Callable[..., Any])

Expand Down
2 changes: 2 additions & 0 deletions src/pystack/_pystack/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(PYSTACK_SOURCES
logging.cpp
maps_parser.cpp
mem.cpp
native_frame.cpp
process.cpp
pycode.cpp
pyframe.cpp
Expand All @@ -21,6 +22,7 @@ set(PYSTACK_SOURCES
version.cpp
version_detector.cpp
bindings.cpp
interpreter.cpp
)

# Create the nanobind module
Expand Down
Loading
Loading