远程Python进程堆栈分析
项目描述
PyStack
打印运行中的Python进程或Python核心转储的堆栈跟踪。
PyStack是一个工具,使用禁止的魔法来允许您检查运行中的Python进程或Python核心转储的堆栈帧,帮助您快速轻松地了解它在做什么(或它在崩溃时做了什么),而无需解释恶心的CPython内部结构。
PyStack能做什么
PyStack具有以下惊人的功能
- 💻 适用于运行中的进程和核心转储文件。
- 🧵 显示每个线程是否当前持有Python GIL,正在等待获取它,或正在当前释放它。
- 🗑️ 显示线程是否正在运行垃圾回收周期。
- 🐍 可选地显示原生函数调用,包括Python调用。在此模式下,PyStack打印原生堆栈跟踪(C/C++/Rust函数调用),但将Python可调用对象的调用替换为显示正在执行的Python代码的帧,而不是显示解释器用于执行调用的内部C代码。
- 🔍 自动解混淆原生堆栈中显示的符号。
- 📈 当有足够的调试信息时,包括内联函数的调用。
- 🔍 可选地显示Python堆栈帧中局部变量和函数参数的值。
- 🔒 在运行进程上使用是安全的。PyStack不会修改任何内存或执行任何正在运行的进程中的代码。它只是附着足够长的时间来读取进程的一些内存。
- ⚡ 可选地,它可以在不暂停进程的情况下执行Python堆栈分析。这最大限度地减少了调试进程的影响,但可能会因为数据竞争而失败。
- 🚀 非常快!它分析核心文件的速度比通用工具如GDB快10倍。
- 🎯 即使是经过积极优化的Python解释器二进制文件也能正常工作。
- 🔍 即使是与没有符号或调试信息的Python解释器二进制文件一起工作(仅Python堆栈)。
- 💥 良好地容忍内存损坏。即使进程因内存损坏而崩溃,PyStack通常也能重建堆栈。
- 💼 自包含:它不依赖于运行PyStack本身所使用的Python解释器之外的任何外部工具或程序。
支持哪些平台?
目前只支持Linux。
从源码构建
如果您想从源码构建PyStack,您需要在系统中安装以下二进制依赖项
- libdw
- libelf
注意,有时这两个库作为分发的一部分(如elfutils
包)一起提供。
检查您的包管理器以了解如何安装这些依赖项(例如,在基于Debian的系统上apt-get install libdw-dev libelf-dev
)。请注意,您可能需要告诉编译器依赖项的头文件和库文件的路径,以便构建成功。如果pkg-config
可用(例如,在基于Debian的系统上apt-get install pkg-config
),它将自动用于定位库并配置正确的构建标志。检查您的分发文档以确定头文件和库文件的路径,或获取更详细的信息。在Alpine Linux(或任何不使用glibc的其它分发)上构建时,您将需要elfutils 0.188或更新的版本。如果您的分发包管理器中没有它,您可能需要从源码构建。
安装这些二进制依赖项后,您可以克隆存储库并遵循Python库的典型构建过程。
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
这将安装PyStack到开发模式下的虚拟环境(最后一个pip install
命令的-e
),然后安装测试、lint和生成其文档所需的Python库。
如果您计划贡献,应安装pre-commit钩子
pre-commit install
这将确保您的贡献通过我们的lint检查。
文档
您可以在这里找到完整的文档。
用法
PyStack使用不同的子命令来分析运行中的进程和核心转储文件。
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
分析运行中的进程
使用remote
命令来分析正在运行(远程)进程的状态。分析始终以安全和侵入性的方式进行,因为不会在分析进程的内存空间中加载代码,也不会修改远程进程中的内存。这使得使用PyStack进行分析成为那些在运行进程必须以任何方式受到影响的(除了临时暂停之外)环境中服务的绝佳选择。有几个选项可用
usage: pystack remote [-h] [-v] [--no-color] [--no-block] [--native] [--native-all] [--locals] [--exhaustive] 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)
要使用PyStack,您只需要提供进程的PID
$ 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)
分析核心转储
《core》子命令用于分析核心转储文件的状态。分析核心文件与分析进程非常相似,但也有一些区别,因为核心文件不包含程序运行时有效的全部内存。在大多数情况下,这并没有什么区别,因为PyStack会自动尝试适应。然而,在某些情况下,您可能需要指定额外的命令行选项,以帮助PyStack定位所需的信息。在分析核心时,有几种选项可供选择。
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.
在大多数情况下,您只需要提供核心的位置,以便使用PyStack处理核心转储文件。
$ 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)
许可
PyStack遵循Apache-2.0许可协议,如《LICENSE》文件所示。
行为准则
本项目已采用行为准则。如果您对准则有任何疑问,或在本项目中经历了任何不当行为,请通过opensource@bloomberg.net与我们联系。
安全策略
如果您认为您已在此项目中发现安全漏洞,请通过opensource@bloomberg.net将电子邮件发送给项目团队,详细说明可疑问题以及您发现复现问题的任何方法。
请勿在GitHub存储库中打开问题,因为我们希望将漏洞报告保持私密,直到我们有机会审查和解决它们。
贡献
我们欢迎您的贡献,以帮助我们改进和扩展此项目!
以下是一些基本的步骤,以便您能够为本项目做出贡献。如果您对此过程或向Bloomberg开源项目做出贡献的任何其他方面有任何疑问,请随时通过opensource@bloomberg.net发送电子邮件,我们将尽快回答您的问题。
贡献许可
由于本项目根据开源许可协议分发,因此您做出的贡献也将遵循相同的条款。为了能够接受您的贡献,我们需要您明确确认您能够并愿意在这些条款下提供它们,我们用来做到这一点的方法称为开发者原创性证书(DCO)。这与Linux内核、Samba和其他许多主要开源项目所使用的流程类似。
要遵守这些条款进行参与,您必须做的只是在每个贡献的提交消息的最后一行包含以下类似的行
Signed-Off-By: Random J. Developer <random@developer.example.org>
完成此操作的最简单方法是向您的git commit
命令添加-s
或--signoff
。
您必须使用您的真实姓名(抱歉,不接受化名,也不接受匿名贡献)。
步骤
- 创建一个问题,选择“功能请求”,并解释所提出的更改。
- 遵循您面前的问题模板中的指南。
- 提交问题。
- 提交拉取请求,并在拉取请求摘要中包含“#”以将其链接到问题。
项目详细信息
pystack-1.4.0.tar.gz的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 9308a66f5f7cd4895a0d06e25839bac1686a10757bc4da3c303cbec957e4d4a8 |
|
MD5 | 07c53ff54caad2c0e8fe25bdcba11110 |
|
BLAKE2b-256 | 2d040d0a12c26656b70b3bc93b4e485a32dcd6a131b50a884b6433c5e21bbfe8 |
pystack-1.4.0-cp313-cp313-musllinux_1_1_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 8ca5ff3530e0011d4331c271b6a57c5079c246acd1f7ef104fcd39d11bf3dad1 |
|
MD5 | d16924f15cd35eb34223cab2744afc08 |
|
BLAKE2b-256 | ca49a675ff0319ed2d868b9b6225d06f9c554cb692ee89ac8615466efef47fdd |
pystack-1.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | f554e3016ea9c250bfc9656d100d42db945f6a0c3e42acdd57753ce0e5018a79 |
|
MD5 | 2a63bb90718efdef366ea465a6e03090 |
|
BLAKE2b-256 | aec747ff9083e923ed3123b5ad45cab8252dbf91770de72e360cd4ca34148ef7 |
pystack-1.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 686c1cf7111e937ef9cf81b95414e785434874f1105b4fb21d4a18af949420d7 |
|
MD5 | 542f76ee3847a59853238cfd003f6780 |
|
BLAKE2b-256 | 29f9890fecc29ec841142c751d5cbee59db42cd424398f6f5819768d2f8886ef |
pystack-1.4.0-cp312-cp312-musllinux_1_1_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | f3c8dd5485ea4a9e7637665ab075b3ac0fad4ea43bed89d29297a7b1008d58ba |
|
MD5 | 74e6b970f33a009c216e9a2dbdf94b40 |
|
BLAKE2b-256 | 6ab8b7847550b5745c8f51afec2336c21a7a8c5f14c38108bd1a272f0834ddfe |
pystack-1.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 35a18ff8f7a5110afa0d6a93da3a6f51effd6de0ac17cace9e49d068d6906e9e |
|
MD5 | 741f19f6760af965ada1bfe609763847 |
|
BLAKE2b-256 | 1d38b6598b28c6dc1c250d4fc397bbfe5d342309a66e981153b47998428e6c37 |
pystack-1.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 99705f2fcb8d79f363e5c6d9e8826afb4ef0b7c2533e4b63c526144b43bee839 |
|
MD5 | 05415dc5770a87d24451a674dcaaf894 |
|
BLAKE2b-256 | c8c28958f1497321015b9f93ff319dafabfa477615e80df70fe0b1683eead163 |
pystack-1.4.0-cp311-cp311-musllinux_1_1_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 9aadad12b061920418fc7e6e9599e971e0e0efb1e4b58f2a5f3a418783a284a6 |
|
MD5 | f2a8d583f52168d69780737bc49e4f08 |
|
BLAKE2b-256 | b3c0f5df3a5fe93774cc6b407dfdf02816b34833b6e8f3fe9366d23922ff7284 |
pystack-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 8c65972dbd441d6986b9eb16559b6bdd3f4494344a74184f5b5b9a26224adc7e |
|
MD5 | 63265a4bb8078b3b6c024543dd385cb1 |
|
BLAKE2b-256 | d6ee698eee058528b9f31006a4bd1d6d38e2d8ffc705f9033909436b4413b003 |
pystack-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | dc9d62f231a4da71055735cd4c3aa10ec02848bc4b2f05eb9ff50cec7faf9916 |
|
MD5 | 13cd2cf8ea710e729d38bb880b8a6124 |
|
BLAKE2b-256 | 430a1c2a741c0213b23299feb6608ad969fd8cf67efb1724cf22a3207a8d5f51 |
pystack-1.4.0-cp310-cp310-musllinux_1_1_x86_64.whl的散列值
算法 | 散列值 | |
---|---|---|
SHA256 | 88fa5ebd857d83fce766d84b5f515aa98a82d7574b28ff813f7f785808484572 |
|
MD5 | a3bf538dd1478d97f7f22bfe1b83c22f |
|
BLAKE2b-256 | 1c41f0bb19be18acef0219db219b7b9788d1e19f24085bf7ddc7b6cd718a70af |
哈希值 用于 pystack-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | c85a9ecb79c8e2a778e5fa15f3815dd72acec93e39d4875f43c4d6ff897dd3d6 |
|
MD5 | 82b86c2c37dec154bb328fbb7fa2ca41 |
|
BLAKE2b-256 | d666de54f7606582608c3d2d1aa3805e3184e1a06c5b1fdbd24e4125969e3442 |
哈希值 用于 pystack-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 1ba8832b325754a80eb370339c9f36e58d1248e773f96ebbea7b032a7fd9a092 |
|
MD5 | d6d5580cf4cc2331f009c09cc590b39a |
|
BLAKE2b-256 | c85450125f4b1526bdd2aa696d997615d182524bacac205a295f181adc5fb993 |
哈希值 用于 pystack-1.4.0-cp39-cp39-musllinux_1_1_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 20c43d11a9c18af5561015ecb6b2628d7b869aeefb02240563ed423bc664661c |
|
MD5 | 8a3524ce60d02a2f55ad3109d75b157d |
|
BLAKE2b-256 | 583ff8c9bf4e0cf6a43f936d167b620aec5c6134b1a45ae4e92114bf88124e68 |
哈希值 用于 pystack-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | da78a23b67caed1fdadb235309cb8a9aae90efa23b3b9c493901bbde95dea86e |
|
MD5 | 4a103c2f0af744126d0d15eddeeaae9c |
|
BLAKE2b-256 | db9c3c5cfe57ea0f492dd7fa05bc01b101146d2d75ea106e561443ef3760b5e9 |
哈希值 用于 pystack-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 7f0ffde5f1a4a4be49da3f30b8a3b15360eaa4cff163f43a423884c2689ad81d |
|
MD5 | 72c5449baaaff98e424690e02bc43a9b |
|
BLAKE2b-256 | 245357d0cc11411f14e6b5f3e56b679eebda6b64bd6f69437fe16af7ccfa2ae3 |
哈希值 用于 pystack-1.4.0-cp38-cp38-musllinux_1_1_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 44dddb8821be6ae460a13b086b45d9b8e8d4e6c139b48108c98f4ec31b8698d0 |
|
MD5 | a8976069406d4663a46c33075ee17b7c |
|
BLAKE2b-256 | 535cdb413948b38740d56e79c5dbca9ae2154d10b638e8a49ee724e089b4703f |
哈希值 用于 pystack-1.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | a69909cdf0216db32b0aaa6a4e19e656ea67ec1f556e32d8a355e59e51747b67 |
|
MD5 | 93cfbc8b49c1464c01aa4a86c8080216 |
|
BLAKE2b-256 | 47a1c901bc7d02b587a44b188c267170e19585c6d3992cf9e8c5ffe8e5a806a8 |
哈希值 用于 pystack-1.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | f9b8856e9e4922e37b316ac3054b91ef11491674ae788523d6e6f3598a2bce39 |
|
MD5 | 630d40b82262480e25700936a085dffd |
|
BLAKE2b-256 | 8d765eb216c7897372f3a087a188dfaa922b039e4d5921e11c6f57ddd322c9d8 |
哈希值 用于 pystack-1.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 3efe95653cfbf3166bb03860d89e0e3309d645463a20acf78f26f3e92745ccbe |
|
MD5 | 89392a8ce1f18f840310f89a138cb979 |
|
BLAKE2b-256 | d9f665e5f2602ff34d4220a2c7837fdad65e83aee47891c237adf8d13eb59004 |
哈希值 用于 pystack-1.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | bf795b265e498fe89a57f85a7e79242aca8fedcc69e22d4fe698931a2195249a |
|
MD5 | b5a127b23e5bc0f8447921c2917a6d41 |
|
BLAKE2b-256 | c0be4825e4a533d10d087b116d55caa9142840e737d90834c4d84f9f3d1ac50e |
哈希值 用于 pystack-1.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 散列值 | |
---|---|---|
SHA256 | 32447c87ee2cbe66ac382a244e16dbcbdc576fcd015f681a86bfb680fe0411ee |
|
MD5 | 3c6fe616b94d17ebbcd5717c08df3176 |
|
BLAKE2b-256 | 356ebcfd630bf492bb9bad42b4ffe63ac034f487618092eed0b1852f23f5fcec |