pwndbg: Pwndbg Hangs with gdbserver on High Thread Count Programs
Description
Pwndbg gets stuck when used with gdbserver when debugging a program with 40+ threads, an example of which is Chromium running on Android.
Steps to reproduce
debug chromium apk on android
My setup
pwndbg commit hash: 13f467b0246367548a7fd9fd952391978ec1d47c
Gdb: 13.2 Python: 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] Pwndbg: 2023.07.17 build: 13f467b Capstone: 5.0.1280 Unicorn: 2.0.1
We have verified that this is not the issue with GDB.
The issue seems to be located in the update()
function in the pwndbg/gdblib/stack.py
file. This function takes a significantly long time to process when there is a high number of threads as it tries to find the stack boundary for each one.
When enabling the debug feature, we can see that Pwndbg gets hung up on the โstopโ event for thread processing as shown here:
...
'obj' pwndbg.gdblib.hooks.reset_config (<gdb.NewObjFileEvent object at 0x7fde7a41bb10>,)
'obj' pwndbg.lib.cache.clear (<gdb.NewObjFileEvent object at 0x7fde7a41bb10>,)
0x0000007984eeab68 in __epoll_pwait () from /home/dev/android-solibs/system/lib64/libc.so
'stop' pwndbg.gdblib.events._start_stop (<gdb.StopEvent object at 0x7fde7a3fa2f0>,)
'stop' pwndbg.gdblib.regs.update_last (<gdb.StopEvent object at 0x7fde7a3fa2f0>,)
'stop' pwndbg.gdblib.stack.update (<gdb.StopEvent object at 0x7fde7a3fa2f0>,)
It appears that the current method of enumerating all thread information for context is inefficient for the case of debugging applications with a high number of threads. This should be more on-demand or limited to only showing information about the current thread.
Relevant Code:
@pwndbg.gdblib.events.stop
@pwndbg.lib.cache.cache_until("stop")
def update() -> None:
"""
For each running thread, updates the known address range
for its stack.
"""
curr_thread = gdb.selected_thread()
try:
...
Proposed Solution:
A potential solution to reduce processing time could be to only display thread information on-demand or solely display information about the current thread.
About this issue
- Original URL
- State: closed
- Created 7 months ago
- Comments: 16 (14 by maintainers)
Commits related to this issue
- Fetch stacks only on demand (stacks.update -> stacks.get) Hopefully fixes #1947 by fetching stacks only when they are used instead of doing it on each stop event. — committed to pwndbg/pwndbg by disconnect3d 6 months ago
- Fetch stacks only on demand (stacks.update -> stacks.get) Hopefully fixes #1947 by fetching stacks only when they are used instead of doing it on each stop event. — committed to pwndbg/pwndbg by disconnect3d 6 months ago
- Fetch stacks from vmmap if they exist (also stacks.update -> stacks.get) Hopefully fixes #1947 by fetching stacks only when they are used instead of doing it on each stop event. It will also first tr... — committed to pwndbg/pwndbg by disconnect3d 6 months ago
- Fetch stacks from vmmap if they exist (also stacks.update -> stacks.get) Hopefully fixes #1947 by fetching stacks only when they are used instead of doing it on each stop event. It will also first tr... — committed to pwndbg/pwndbg by disconnect3d 6 months ago
- Fetch stacks from vmmap if they exist (also stacks.update -> stacks.get) (#1959) Hopefully fixes #1947 by fetching stacks only when they are used instead of doing it on each stop event. It will also... — committed to pwndbg/pwndbg by disconnect3d 6 months ago
Hi, I have tried latest commit and tested again. it works great now for high thread count program. Thanks for the work! ๐. much appreciated.