{"id":13831498,"url":"https://github.com/peadar/pstack","last_synced_at":"2025-07-09T14:33:05.537Z","repository":{"id":4226911,"uuid":"5349428","full_name":"peadar/pstack","owner":"peadar","description":"Print stack traces from running processes, or core files. Supports aarch64, x86_64, and i386","archived":false,"fork":false,"pushed_at":"2024-11-11T14:57:48.000Z","size":2143,"stargazers_count":137,"open_issues_count":6,"forks_count":35,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-11T15:43:02.840Z","etag":null,"topics":["aarch64","arm","c","c-plus-plus","debug","dwarf","elf","linux","pstack","x86-64"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peadar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-08-09T00:44:58.000Z","updated_at":"2024-11-11T14:57:52.000Z","dependencies_parsed_at":"2024-03-21T13:47:44.325Z","dependency_job_id":"51452c55-9277-43c4-bcea-4798539fdf24","html_url":"https://github.com/peadar/pstack","commit_stats":{"total_commits":886,"total_committers":12,"mean_commits":73.83333333333333,"dds":0.4977426636568849,"last_synced_commit":"9490d48f908d0e0a7cee9066a281a64ebf7fe259"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peadar%2Fpstack","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peadar%2Fpstack/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peadar%2Fpstack/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peadar%2Fpstack/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peadar","download_url":"https://codeload.github.com/peadar/pstack/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225565803,"owners_count":17489270,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aarch64","arm","c","c-plus-plus","debug","dwarf","elf","linux","pstack","x86-64"],"created_at":"2024-08-04T10:01:29.454Z","updated_at":"2025-07-09T14:33:05.527Z","avatar_url":"https://github.com/peadar.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"# pstack\n\n**A from-scratch implementation of pstack using DWARF debugging and unwind\ninformation.  Works for C/C++, Go, Rust, and Python**\n\nA traditional pstack command can generally print a backtrace of each thread\nin a running program, and sometimes from a core file.\n\nThis version of pstack uses its own self contained ELF and DWARF parsing\nlibrary, `libdwelf` to parse the DWARF debug and unwind information,\nto get a stack trace. The functionality is well tested for C++, and is\nminimally tested for Go and Rust binaries.  It also supports getting\npython language backtraces for cpython.\n\n## Disclaimer\nThis works for my purposes, and the DWARF parsing library is at least\nsomewhat useful outside the pstack implementation, but the documentation\nis weak. [ctypegen](https://github.com/aristanetworks/ctypegen) is a\ngood example of a \"third party\" package that uses libdwelf from here.\n\n## Manpage\n\nThere's a manual page, and you can see a text rendering of it\n[here](./pstack.1.txt)\n\n## Cheatsheet and Features\n\n### Basic usage\nYou can generate a stack trace from a running program by using\n\n`pstack \u003cpid\u003e`\n\nFor example, you can see what your shell is doing like this\n```\nbash-5.1$ pstack $$\nattaching to live process\nprocess: /proc/532040/mem\nthread: 0, lwp: 532040, type: 0\n#0  0x00007fde87791aca in __wait4()+26 in /lib64/libc.so.6 at wait4.c:30\n#1  0x000055fe8fd610bd in waitchld.constprop.0!()+188 in /usr/bin/bash\n#2  0x000055fe8fcc58ea in wait_for!()+1241 in /usr/bin/bash\n#3  0x000055fe8fcadd1e in execute_command_internal!()+10029 in /usr/bin/bash\n#4  0x000055fe8fcae578 in execute_command!()+199 in /usr/bin/bash\n#5  0x000055fe8fc9ff49 in reader_loop!()+648 in /usr/bin/bash\n#6  0x000055fe8fc9191e in main!()+5565 in /usr/bin/bash\n#7  0x00007fde876ecb75 in __libc_start_main()+212 in /lib64/libc.so.6 at libc-start.c:332\n#8  0x000055fe8fc91d1e in _start!()+45 in /usr/bin/bash\n\nbash-5.1$\n```\nAlso, pstack can get traces from core files as easily as it can from\nrunning programs - you can see examples later.\n\n\n### Argument printing\nIn the above examples it's obvious that there is debug information\navailable, as we can see source and line number information. We can also\ntry and see the values of arguments passed to functions using \"-a\". This\n*requires* debugging information:\n```\n$ cat t.c\n#include \u003cassert.h\u003e\nint f(int id, const char*msg) {\n   assert(id == 0);\n}\nint main() {\n   f(42, \"hello world\");\n}\n$ cc -g -o t t.c\n$ ./t\nt: t.c:3: f: Assertion `id == 0' failed.\nzsh: IOT instruction (core dumped)  ./t\n$ ls /var/core\ncore.t.533472\n$ pstack -a /var/core/core.t.533472\nprocess: /var/core/core.t.533472\nthread: 0, lwp: 533472, type: 0\n#0  0x00007fc0e94482a2 in raise(sig=0x2{r5})+322 in /lib64/libc.so.6 at raise.c:50\n#1  0x00007fc0e94318a4 in abort()+277 in /lib64/libc.so.6 at abort.c:79\n#2  0x00007fc0e9431789 in __assert_fail_base(fmt=(null), assertion=(null), file=(null), line=(null), function=(null))+14 in /lib64/libc.so.6 at assert.c:92\n#3  0x00007fc0e9440a16 in __assert_fail(assertion=\"id == 0\"{r6}, file=\"t.c\"{r12}, line=0x3{r13}, function=\"f\"{r3})+69 in /lib64/libc.so.6 at assert.c:101\n#4  0x0000000000401154 in f(id=42, msg=\"hello world\")+45 in ./t at t.c:3\n#5  0x000000000040116a in main()+18 in ./t at t.c:6\n#6  0x00007fc0e9432b75 in __libc_start_main(main=0x401157, argc=1, argv=0x7ffde5430e38, init=0x7fc0e94482a2{r2}, fini=0{r8}, rtld_fini=0x7ffde5430a40{r9}, stack_end=0x7ffde5430e28)+212 in /lib64/libc.so.6 at libc-start.c:332\n#7  0x000000000040106e in _start!()+45 in ./t\n\n$\n```\n\nYou can see the string and integer arguments on frame 4 and 5 quite\neasily, and the format strings from the assertion failure above.\n\n\n### Other useful arguments\n\nYou can pass multiple PIDs and corefiles to pstack, and it will dump\neach process in turn. If multiple processes share libraries or images,\nthen the parsing overhead for DWARF and ELF data only happens once.\n\nYou can use `-b` to cause pstack to repeat the trace of a single process\nrepeatedly with a specified time delay between samples.\n\npstack will do its best to work out the executable to go with a core file,\nbut sometimes it can't. For example, if the executable was invoked with\na relative path, that may be all pstack has available to go on. You can\nprecede the process id/core name with the name of an executable. That\nwill then be used in preference to anything automatically discovered\nuntil overridden again with a new executable.\n\n\n### Python\n\nThere's also support for getting python backtraces, for both python2\nand python3 interpreters. You use '-p' to indicate you are interested\nin python backtraces. For example:\n\n```\nbash-5.1$ cat test.py\ndef testme(pid, text, details):\n    print(\"%s: backtrace of %d folows\" % (text, pid) )\n    os.system(\"pstack -pa %d\" % pid)\n\nimport os\ntestme(os.getpid(), \"check\", details={'hello': 'there'})\nbash-5.1$ python test.py\ncheck: backtrace of 537528 folows\nattaching to live process\n---- interpreter @55ba07d8a910 -----\npthread: 0x7fc3234c1740, lwp 537528\n    testme(537528, \"check\", {\n            \"hello\" : \"there\"\n        }) in /home/peadar/scm/pstack/test.py:3\n    \u003cmodule\u003e() in /home/peadar/scm/pstack/test.py:6\n\n```\n\nFor python, you can even get a full dump of the local frame information\nby passing the \"-l\" option. The output will be very verbose.\n\n## Building\n\n   * To compile, you need CMake, and a compiler that's at least C++20 capable.\n\n   * Various ELF compression mechanisms mean that you should have the\n     development package for zlib and xz compression libraries installed. Those\n     are known as `liblzma-dev` and `zlib1g-dev` if you are on a\n     Debian/Ubuntu-like system, or `xz-devel` and `zlib-devel` on redhat/fedora\n     systems\n\n   * If you want python2 support, you need the python2 development headers installed.\n\n   * If you want python3 support, you need the python3 source installed to\n     match the distribution of your binary. Currently, things only work with\n     python3.9\n\n   * If you want debuginfod support, you need the\n     elfutils-debuginfod-client-debuginfo package or equivalent\n\nTo build:\n```\ngit clone github.com:peadar/pstack\ncd pstack\nmkdir build\ncd build\ncmake -DCMAKE_BUILD_TYPE=RelWithDebInfo ..\nmake -j4\n```\n\nPython 3 support is disabled by default - in theory, the debug source for your\ndistro should include the correct source, but at times it may be askew. To\nenable, add `-DPYTHON3=ON -DPYTHON3_SOURCE=\u003cpath-to-python3\u003e` to the cmake\ncommandline.  Pay attention to the output of cmake to ensure all the features\nyou want are enabled.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeadar%2Fpstack","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeadar%2Fpstack","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeadar%2Fpstack/lists"}