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.

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.1.0.tar.gz (84.8 kB view details)

Uploaded Source

Built Distributions

pystack-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.11 musllinux: musl 1.1+ x86-64

pystack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ x86-64

pystack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.3 MB view details)

Uploaded CPython 3.11 manylinux: glibc 2.17+ ARM64

pystack-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.10 musllinux: musl 1.1+ x86-64

pystack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ x86-64

pystack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.3 MB view details)

Uploaded CPython 3.10 manylinux: glibc 2.17+ ARM64

pystack-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl (5.5 MB view details)

Uploaded CPython 3.9 musllinux: musl 1.1+ x86-64

pystack-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ x86-64

pystack-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.3 MB view details)

Uploaded CPython 3.9 manylinux: glibc 2.17+ ARM64

pystack-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl (5.6 MB view details)

Uploaded CPython 3.8 musllinux: musl 1.1+ x86-64

pystack-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.4 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ x86-64

pystack-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.4 MB view details)

Uploaded CPython 3.8 manylinux: glibc 2.17+ ARM64

pystack-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl (5.5 MB view details)

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

pystack-1.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.3 MB view details)

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

pystack-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (4.3 MB view details)

Uploaded CPython 3.7m manylinux: glibc 2.17+ ARM64

File details

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

File metadata

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

File hashes

Hashes for pystack-1.1.0.tar.gz
Algorithm Hash digest
SHA256 7657e41101dfbe881c19ea336bcd0981a980338448d937460dba01b15aace4ae
MD5 2f283c7eed53bb409c2dc7a97872050c
BLAKE2b-256 861b31dd401fae476cf39941f4ffb0d14bf5e9b7a52ff6c9a73206c24c328fd1

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 8dc71a73883e13c7019a1669c255fc0707359e5872b831ce808492744f697ff1
MD5 bee1b9e2ad4921f0e49e092ccd5080d4
BLAKE2b-256 80b0bba48b4e8cfbf67f9e0526e00398308593c2ebc141ecc3186a726fd7a7d9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fa0e805a920b152a7c0858ad1f83ea9abf513fd99657cdc125ec1c7ae5cd876d
MD5 7179e87351f8e82eb6598f7bdcb324fb
BLAKE2b-256 41070756253bf0cf38d89e8166f172391d96a37d01f49e1daab6a35fc98ed7a5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 f4596f38c7b54278ef96d2fd5e30901d7da94283cba058ee7b47cb1b53df2d21
MD5 2634a35cade8bf0eb1e904e231f018f5
BLAKE2b-256 73301108126d52615cf6b3d54592488493147f01d5bb974395d5f7dc99044ff9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 197b47ee8e1b4dcd35964dae2f1ab7546295621d4e27a4a26bb69edbc76a7624
MD5 b227e269614abd402d151407f1a4b053
BLAKE2b-256 f0f64ddf7b3c7a07ab99aae198864eb0b44acc1e72e141e9ff697aa22eb4369a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 861990a6e9b93951b070baebb1c3ae38b5599ea1a4e774887c3282a7d1725a29
MD5 21e763ddc070b6c62b26abbf5f54e41c
BLAKE2b-256 b4ce085f468d36a088b1942113b163a987513a6df5743467be0a03ced0e3e33b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 9425589ab69c7b636fe6380e5e81c8d384a1e84e5110518a2ad447cfb75405d0
MD5 861438c4c25ea6ef4141ff450aca5e6e
BLAKE2b-256 3b44efb374dbb23fee06f509de246e3be4694e3727e3dcbe8bc5e19b33d76dd0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ad0bb7620acf8010197c60eb04218cb0dca9a68d020b841fb16a570406f8cf7c
MD5 8b305518c36d8aa4b4e9a80426f16515
BLAKE2b-256 17c2e83dd36107f86ea9f92f84c98fbf3e95b2ea5594d7c83987d2dec7efec8a

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 223cf3f2b57d8f1f6e028006a7dee5322e4ac1c4ef3b890dd02b1be0eab2bf8c
MD5 fb38de49762a0fe86ad96553f79036c7
BLAKE2b-256 e37c747f7dd860c874922d9f065910cd72a96eb3a8ea91770a6a6addc9c5ac81

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 3b8db8f8d35208b5301d5af46a09dc5f15a822d4c001a9128942bb6d0c837a8b
MD5 7d666ad8b0d0664c3fe28f275013bdc2
BLAKE2b-256 46bcf4160f2d78c21bfcd561727e70ee37af5e99058a4ace0e64bf72742a411e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 c5ec0ebbc988e084a1e319110c80fbfaeffdd722b2e41675894d284da7b3eeca
MD5 a8fb2e94774e81815971ce92594ae592
BLAKE2b-256 36541fe9600fd617d326542948ae9496300ecc42ffbd7c784f02354c4e3066e6

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f031a6c8cc4ce4cf25d60c519ec439977cfb1883e02f0f9c03702244053eac78
MD5 e645f35501fb6f622e488da7ebb70166
BLAKE2b-256 b7d74d35dd3a69e895464245052cc8b1f1ff22164a086ae2f1604c8cf283e282

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 e9bb331c59e47c3aa47a3034ab7d37918bd623a8a8ee5a71c0f1b418cab46687
MD5 5e99d18a090ab565f6d9307cc374f844
BLAKE2b-256 7cf7a0aa97462af07687a3805535e78b42de5496a3740554eaeb9208f10606e5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 ed88ffb04e8be0daaf9496d087650a12d4639617278de2d061d36d59e66fef5f
MD5 cf52535fdee50c21b27cb0fffaddb4f7
BLAKE2b-256 20f44d9b58fe6461d7115ee2f6868244f22303bf70eba68deb604805e570beb9

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 761b8751fce511eac19161f889b9cbdb4fcb79ad41bcfbd569c5d187472c7458
MD5 05ef0ad160f8f12a2338aaedf66033a5
BLAKE2b-256 76981cd5b432ddc2799ca2cfaf30c2fe941c31b12a57bae06e853013b4acf8d0

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for pystack-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5d5d7fe99d605082b424bcea4a628e87933cf5e43148ace196b3f9bc0dec5b52
MD5 5f118ff17e499778edc6120e6b96669b
BLAKE2b-256 315c9512491e35b935b05149eacc1fa1ba96454080f729436d26f6bee0dd1b28

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