Skip to main content

Analysis of the stack of remote python processes

Project description


OS Linux PyPI - Python Version PyPI - Implementation PyPI PyPI - Downloads Tests Code Style

PyStack

Print the stack trace of a running Python process, or of a Python core dump.

PyStack is a tool that uses forbidden magic to let you inspect the stack frames of a running Python process or a Python core dump, helping you quickly and easily learn what it's doing (or what it was doing when it crashed) without having to interpret nasty CPython internals.

What PyStack can do

PyStack has the following amazing features:

  • 💻 Works with both running processes and core dump files.
  • 🧵 Shows if each thread currently holds the Python GIL, is waiting to acquire it, or is currently dropping it.
  • 🗑️ Shows if a thread is running a garbage collection cycle.
  • 🐍 Optionally shows native function calls, as well as Python ones. In this mode, PyStack prints the native stack trace (C/C++/Rust function calls), except that the calls to Python callables are replaced with frames showing the Python code being executed, instead of showing the internal C code the interpreter used to make the call.
  • 🔍 Automatically demangles symbols shown in the native stack.
  • 📈 Includes calls to inlined functions in the native stack whenever enough debug information is available.
  • 🔍 Optionally shows the values of local variables and function arguments in Python stack frames.
  • 🔒 Safe to use on running processes. PyStack does not modify any memory or execute any code in a process that is running. It simply attaches just long enough to read some of the process's memory.
  • ⚡ Optionally, it can perform a Python stack analysis without pausing the process at all. This minimizes impact to the debugged process, at the cost of potentially failing due to data races.
  • 🚀 Super fast! It can analyze core files 10x faster than general-purpose tools like GDB.
  • 🎯 Even works with aggressively optimized Python interpreter binaries.
  • 🔍 Even works with Python interpreters' binaries that do not have symbols or debug information (Python stack only).
  • 💥 Tolerates memory corruption well. Even if the process crashed due to memory corruption, PyStack can usually reconstruct the stack.
  • 💼 Self-contained: it does not depend on external tools or programs other than the Python interpreter used to run PyStack itself.

What platforms are supported?

At this time only Linux is supported.

Building from source

If you wish to build PyStack from source, you need the following binary dependencies in your system:

  • libdw
  • libelf

Note that sometimes both libraries are provided together as part of a distribution's elfutils package.

Check your package manager on how to install these dependencies (e.g., apt-get install libdw-dev libelf-dev in Debian-based systems). Note that you may need to tell the compiler where to find the header and library files of the dependencies for the build to succeed. Check your distribution's documentation to determine the location of the header and library files or for more detailed information. When building on Alpine Linux (or any other distribution that doesn't use glibc) you'll need elfutils 0.188 or newer. You may need to build this from source if your distribution's package manager doesn't have it.

Once you have these binary dependencies installed, you can clone the repository and follow the typical build process for Python libraries:

git clone git@github.com:bloomberg/pystack.git pystack
cd pystack
python3 -m venv ../pystack-env/  # just an example, put this wherever you want
source ../pystack-env/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e .
python3 -m pip install -r requirements-test.txt -r requirements-extra.txt

This will install PyStack in the virtual environment in development mode (the -e of the last pip install command), and then install the Python libraries needed to test it, lint it, and generate its documentation.

If you plan to contribute back, you should install the pre-commit hooks:

pre-commit install

This will ensure that your contribution passes our linting checks.

Documentation

You can find the full documentation here.

Usage

PyStack uses distinct subcommands for analyzing running processes and core dump files.

usage: pystack [-h] [-v] [--no-color] {remote,core} ...

Get Python stack trace of a remote process

options:
  -h, --help     show this help message and exit
  -v, --verbose
  --no-color     Deactivate colored output

commands:
  {remote,core}  What should be analyzed by PyStack (use <command> --help for a command-specific help section).
    remote       Analyze a remote process given its PID
    core         Analyze a core dump file given its location and the executable

Analyzing running processes

The remote command is used to analyze the status of a running (remote) process. The analysis is always done in a safe and non-intrusive way, as no code is loaded in the memory space of the process under analysis and no memory is modified in the remote process. This makes analysis using PyStack a great option even for those services and applications that are running in environments where the running process must not be impacted in any way (other than being temporarily paused, though --no-block can avoid even that). There are several options available:

usage: pystack remote [-h] [-v] [--no-color] [--no-block] [--native] [--native-all] [--locals] [--exhaustive] [--self] pid

positional arguments:
  pid            The PID of the remote process

options:
  -h, --help     show this help message and exit
  -v, --verbose
  --no-color     Deactivate colored output
  --no-block     do not block the process when inspecting its memory
  --native       Include the native (C) frames in the resulting stack trace
  --native-all   Include native (C) frames from threads not registered with the interpreter (implies --native)
  --locals       Show local variables for each frame in the stack trace
  --exhaustive   Use all possible methods to obtain the Python stack info (may be slow)

To use PyStack, you just need to provide the PID of the process:

$ pystack remote 112
Traceback for thread 112 [] (most recent call last):
    (Python) File "/test.py", line 17, in <module>
        first_func()
    (Python) File "/test.py", line 6, in first_func
        second_func()
    (Python) File "/test.py", line 10, in second_func
        third_func()
    (Python) File "/test.py", line 14, in third_func
        time.sleep(1000)

Analyzing core dumps

The core subcommand is used to analyze the status of a core dump file. Analyzing core files is very similar to analyzing processes but there are some differences, as the core file does not contain the totality of the memory that was valid when the program was live. In most cases, this makes no difference, as PyStack will try to adapt automatically. However, in some cases, you will need to specify extra command line options to help PyStack locate the information it needs. When analyzing cores, there are several options available:

usage: pystack core [-h] [-v] [--no-color] [--native] [--native-all] [--locals] [--exhaustive] [--lib-search-path LIB_SEARCH_PATH | --lib-search-root LIB_SEARCH_ROOT] core [executable]

positional arguments:
  core                  The path to the core file
  executable            (Optional) The path to the executable of the core file

options:
  -h, --help            show this help message and exit
  -v, --verbose
  --no-color            Deactivate colored output
  --native              Include the native (C) frames in the resulting stack trace
  --native-all          Include native (C) frames from threads not registered with the interpreter (implies --native)
  --locals              Show local variables for each frame in the stack trace
  --exhaustive          Use all possible methods to obtain the Python stack info (may be slow)
  --lib-search-path LIB_SEARCH_PATH
                        List of paths to search for shared libraries loaded in the core. Paths must be separated by the ':' character
  --lib-search-root LIB_SEARCH_ROOT
                        Root directory to search recursively for shared libraries loaded into the core.

In most cases, you just need to provide the location of the core to use PyStack with core dump files:

$ pystack core ./the_core_file
Using executable found in the core file: /usr/bin/python3.8

Core file information:
state: t zombie: True niceness: 0
pid: 570 ppid: 1 sid: 1
uid: 0 gid: 0 pgrp: 570
executable: python3.8 arguments: python3.8

The process died due receiving signal SIGSTOP
Traceback for thread 570 [] (most recent call last):
    (Python) File "/test.py", line 19, in <module>
        first_func({1: None}, [1,2,3])
    (Python) File "/test.py", line 7, in first_func
        second_func(x, y)
    (Python) File "/test.py", line 12, in second_func
        third_func(x, y)
    (Python) File "/test.py", line 16, in third_func
        time.sleep(1000)

License

PyStack is Apache-2.0 licensed, as found in the LICENSE file.

Code of Conduct

This project has adopted a Code of Conduct. If you have any concerns about the Code, or behavior that you have experienced in the project, please contact us at opensource@bloomberg.net.

Security Policy

If you believe you have identified a security vulnerability in this project, please send an email to the project team at opensource@bloomberg.net, detailing the suspected issue and any methods you've found to reproduce it.

Please do NOT open an issue in the GitHub repository, as we'd prefer to keep vulnerability reports private until we've had an opportunity to review and address them.

Contributing

We welcome your contributions to help us improve and extend this project!

Below you will find some basic steps required to be able to contribute to the project. If you have any questions about this process or any other aspect of contributing to a Bloomberg open source project, feel free to send an email to opensource@bloomberg.net and we'll get your questions answered as quickly as we can.

Contribution Licensing

Since this project is distributed under the terms of an open source license, contributions that you make are licensed under the same terms. For us to be able to accept your contributions, we will need explicit confirmation from you that you are able and willing to provide them under these terms, and the mechanism we use to do this is called a Developer's Certificate of Origin (DCO). This is similar to the process used by the Linux kernel, Samba, and many other major open source projects.

To participate under these terms, all that you must do is include a line like the following as the last line of the commit message for each commit in your contribution:

Signed-Off-By: Random J. Developer <random@developer.example.org>

The simplest way to accomplish this is to add -s or --signoff to your git commit command.

You must use your real name (sorry, no pseudonyms, and no anonymous contributions).

Steps

  • Create an Issue, select 'Feature Request', and explain the proposed change.
  • Follow the guidelines in the issue template presented to you.
  • Submit the Issue.
  • Submit a Pull Request and link it to the Issue by including "#" in the Pull Request summary.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pystack-1.2.0.tar.gz (87.6 kB view details)

Uploaded Source

Built Distributions

pystack-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.12 musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.12 manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.11 musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.6 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

pystack-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.10 musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

pystack-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl (5.7 MB view details)

Uploaded CPython 3.9 musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

pystack-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl (5.8 MB view details)

Uploaded CPython 3.8 musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.6 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

pystack-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.7m musllinux: musl 1.1+ x86-64

pystack-1.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.5 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ x86-64

pystack-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.5 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

File details

Details for the file pystack-1.2.0.tar.gz.

File metadata

  • Download URL: pystack-1.2.0.tar.gz
  • Upload date:
  • Size: 87.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for pystack-1.2.0.tar.gz
Algorithm Hash digest
SHA256 96859bb39da99c42cee97974bedf3386dd8fd8f28c04fbdc843fd3260c030874
MD5 874e8c83f0ea5461e6732ba08c002b59
BLAKE2b-256 4bd49d0b8b6b5074f44937b2937a7841949f2e79a3c02e9b208d1716efbc818c

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp312-cp312-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 8c246ebcb22039e28bdb9834d162ea5d74a4c5e7d9154c4a9f8726ae04d3e228
MD5 877cd5a62f3516ef15a6b3030c758b73
BLAKE2b-256 feb008656d010f2a5a85143b572bbb32b31c735348a9c62a77e3da0d442ee116

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4b2d60b30e6f95eef3c509044ad91557f1921b84ac19099d823e462754fd8e8b
MD5 67e25385a2873e09f9b3ef9494781f5a
BLAKE2b-256 806241619d9147d119ac969226d0e127ec310e294cd249d9c92b7c775c288c93

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 d202f84cb9a1771e00aee3f8a583611973aa3407aa6eee65a9a4a7c0b73761f5
MD5 788ee66ccd5f13adf93c0dc38d25063a
BLAKE2b-256 6cc54509aa0d2c56121011cfe68f6b63c4a2ba8e256cc0bcff9e314b66b9bbf7

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 b7ae647237ab9e3884dfca3baf472160910cb59081984e2a587f7cfbf3470dd6
MD5 8fcda8c709a969eb510fc05b983bd75b
BLAKE2b-256 00f581555f4671de7896c558442a46f056da6dd1dec7dc2d4df7969c1625806a

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 26d67386f31fac6508c01363096beaa45938df5f5d4f601edf3f9746afaff83a
MD5 9ff613e1fd6a6b8c3479e40ce77a1a33
BLAKE2b-256 9d192f3d8130857092899aa5b6f30437b82eb7f1af9a4d033d99a5752a422fc8

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 44ce243a4116d33afd7afb29cd437c53f26ffa7dfd62694f690befd03493e6b5
MD5 9d4fdcc7843d198330b6c1fd40de9278
BLAKE2b-256 fc4594f5a938bde6fc832a003de0361b964682d3ca25eb2c55f61b43e690ccb6

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 803b44e01bf0ccee98d315eb61b2e02f7ec9a6034757416788799c2d1f25806f
MD5 2bf835f3e099563fff4cbdc0f10f11e8
BLAKE2b-256 b4724ce30e4c7c1499afc136e043dea77473f0adc58e0da4beef45ccbb00848a

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 2190afc1d11b196ff1f3c952d366ea5438774ff500784d22b3c08198e23e325a
MD5 fed67f679b1330290dd726c9bf210ed8
BLAKE2b-256 dc4b8765cbda9db86d8317478f44d9c97dcb90a490b5dff021f0851930dfa7f1

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 192179f1d357f8ceadaa04357ea10b68e88bb7772815eea25fc9ee0eff2033b2
MD5 315ab47192e42b6eea766320c788329a
BLAKE2b-256 9afaf9daebc2e8ee7bde6c80c4f40cc7c031dc80d73f6ab01f3fa1be3159ec9f

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 0fd02bc8cd11575bf563df8e76db53d3a87bda86458e22568796cd6b5960b2b2
MD5 69c7f8d6b0d25f375d2283cc5051f07d
BLAKE2b-256 4c357c435f69958e780d91f2977075a87aa6d57bdf06bd9405728649138bd922

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 1209e131272088fd9a0c1d3dfea5e65c6692e8d2606cbdb07a8d68a6223ba7db
MD5 b0dd79f2d54665a03c5a1501cb55c759
BLAKE2b-256 510e33f5b897f45a52b4315542954f3ee176bdcf702930379a4e674db54b7683

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 2baf0f485471b4779f48efcfc29dfda668fc0307c90ed8fcce9605bf647ce302
MD5 b67ed6e591ba1d3888c2563103611054
BLAKE2b-256 b7b31d5e090adea1b1384b965827aefc23f63790e9f81fb32ae6ec6f4390318c

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8f9699bd61fdc81d9eccb6ae91bb03a6fc3ac7804fbd42bf334940b39fbe7b5a
MD5 7ea7757c3f51c3c1e6cefc655187b3b7
BLAKE2b-256 1d0f9c8cb866a53cc2aea211ee2d4fd19efa7d3b77804298ec6d48dd82a20649

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 d7512b2ef45ba010e29161e276e6922d8dd7e42edc29907114da06e33e7ca658
MD5 4b0e5c0198bc303138714a13c2f641b9
BLAKE2b-256 6ec79e2ee0966b5e7fbcba36962ef249296fb8a7e7846f5c6457254922d873b9

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 fa29d36e75d202a7b9223e6236e017755dbca89137b5b88e3a357fce6f75dedd
MD5 3308b8aff825cd179e18c415a7b5c9e5
BLAKE2b-256 916765a50b58bddcde7f2be867f6ab60f44b69f96a22002e2c6afe1c75d07955

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 051726d0fabc43ed2d86143ad8c2db3499541ec2b32e2ebf40538584ab355ef3
MD5 4738b8d82ebfc9d9754e9c0b6fd1a2b0
BLAKE2b-256 8c071527d0342528f26812669a7db244f74412ca92296664e0ca081d20615a74

See more details on using hashes here.

File details

Details for the file pystack-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pystack-1.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 68c524a0e52317cdff9e3b16c309313717cffb8d9d600dafffc8ed03546017da
MD5 c8bc9b7f7d892184c802feab3f946210
BLAKE2b-256 6fef6dfa68dba0688db0a603b6122cbd02d56da81fd87fa19e35882c13f0cc04

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page