pwndbg / pwndbg

Exploit Development and Reverse Engineering with GDB Made Easy
https://pwndbg.re/
MIT License
7.22k stars 867 forks source link

gdb.error: Selected thread is running. #1599

Open yooo1999 opened 1 year ago

yooo1999 commented 1 year ago

Working with last commit 9d22acc1d769d02aae88f9b343d2043437fca6f2 run gdb-multiarch and then source gdbinit.py then I stop with breakpoint and press c and I got


╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮                                                                                                                                [20/1863]
│ /PATH/pwndbg/pwndbg/gdblib/events.py:156 in caller                      │
│                                                                                                  │
│   153 │   │   │   objfile_cache[path] = dispatched                                               │
│   154 │   │                                                                                      │
│   155 │   │   try:                                                                               │
│ ❱ 156 │   │   │   func()                                                                         │
│   157 │   │   except Exception as e:                                                             │
│   158 │   │   │   import pwndbg.exception                                                        │
│   159                                                                                            │
│                                                                                                  │
│ /PATH/pwndbg/pwndbg/gdblib/hooks.py:32 in update_arch                   │
│                                                                                                  │
│    29 @pwndbg.gdblib.events.stop                                                                 │
│    30 @pwndbg.gdblib.events.new_objfile                                                          │
│    31 def update_arch() -> None:                                                                 │
│ ❱  32 │   arch_mod.update()                                                                      │
│    33                                                                                            │
│    34                                                                                            │
│    35 @pwndbg.gdblib.events.new_objfile                                                          │
│                                                                                                  │
│ /PATH/pwndbg/pwndbg/gdblib/arch.py:57 in update                         │
│                                                                                                  │
│   54                                                                                             │
│   55                                                                                             │
│   56 def update() -> None:                                                                       │
│ ❱ 57 │   arch_name, ptrsize, endian = _get_arch(typeinfo.ptrsize)                                │
│   58 │   arch.update(arch_name, ptrsize, endian)                                                 │
│   59 │   pwnlib.context.context.arch = pwnlib_archs_mapping[arch_name]                           │
│   60 │   pwnlib.context.context.bits = ptrsize * 8                                               │
│                                                                                                  │
│ /PATH/pwndbg/pwndbg/gdblib/arch.py:37 in _get_arch                      │
│                                                                                                  │
│   34 │   │   endian = "big"                                                                      │
│   35 │                                                                                           │
│   36 │   if pwndbg.gdblib.proc.alive:                                                            │
│ ❱ 37 │   │   arch = gdb.newest_frame().architecture().name()                                     │
│   38 │   else:                                                                                   │
│   39 │   │   arch = gdb.execute("show architecture", to_string=True).strip()                     │
│   40 │   │   not_exactly_arch = True                                                             │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
error: Selected thread is running.
If that is an issue, you can report it on https://github.com/pwndbg/pwndbg/issues
(Please don't forget to search if it hasn't been reported before)
To generate the report and open a browser, you may run `bugreport --run-browser`
PS: Pull requests are welcome
> /PATH/pwndbg/pwndbg/gdblib/arch.py(37)_get_arch()
-> arch = gdb.newest_frame().architecture().name()
(Pdb) q
Traceback (most recent call last):
  File "/PATH/pwndbg/pwndbg/gdblib/events.py", line 161, in caller
    raise e
  File "/PATH/pwndbg/pwndbg/gdblib/events.py", line 156, in caller
    func()
  File "/PATH/pwndbg/pwndbg/gdblib/hooks.py", line 32, in update_arch
    arch_mod.update()
  File "/PATH/pwndbg/pwndbg/gdblib/arch.py", line 57, in update
    arch_name, ptrsize, endian = _get_arch(typeinfo.ptrsize)
  File "/PATH/pwndbg/pwndbg/gdblib/arch.py", line 37, in _get_arch
    arch = gdb.newest_frame().architecture().name()
gdb.error: Selected thread is running.
disconnect3d commented 1 year ago

Can it be that this is in a script that does more than just source gdbinit.py?

How can we reproduce this?

disconnect3d commented 1 year ago

@yooo1999 ping. Please provide more data or we will have to close this issue :(

disconnect3d commented 1 year ago

Closing this for now since we can't reproduce it

yooo1999 commented 1 year ago

@disconnect3d gdbinit looks like


set pagination off
file <some_file>
set arch arm
set sysroot /<some path>
target remote <some_ip>:<some_port>
source ~pwndbg/gdbinit.py
set show-tips off

b *0x<some_addr>
commands
silent
echo "hi!"
c
end

and when the pwndbg stop in breakpoint it print hi and after that Exception occurred: Error: Selected thread is running. (<class 'gdb.error'>)

disconnect3d commented 1 year ago

GDB has a bug where it deadlocks when you setup a stop hook using it Python API (which is what Pwndbg does) and then you set up a command to be executed for a breakpoint using its GDB scripting capabilities.

This bug was already reported here: https://github.com/pwndbg/pwndbg/issues/425 and I reported it to GDB some time ago and someone posted a patch with a fix recently, but it hasn't been polished or merged yet: https://sourceware.org/bugzilla/show_bug.cgi?id=29831. In theory, you can take this patch and recompile GDB with it.

On the other hand, there is a workaround (as described in #425): you can set up your command for a breakpoint using the Python API which does not cause the deadlock to happen. That would be something like:

class Bp(gdb.Breakpoint):
    def stop(self):
        print("hi!")
        # use gdb.execute("<commands>") here
        # you can also use pwndbg.gdblib.memory.write(addr, val)
        # pwndbg.gdblib.memory.read(addr, count) etc.
        # though keep in mind that Pwndbg will not clear cache during such BPs execution
        # so it may be good to disable caching here via gdb.execute("set memoize off") and re-enabling it afterwards
        return False

Bp("*0x<some_addr>")
yooo1999 commented 1 year ago

@disconnect3d Maybe is there any way to add the breakpoint native instead of via Python?

disconnect3d commented 1 year ago

You can create your own command using the Python API that would use the code above; I'm not sure if there is other way.

yooo1999 commented 1 year ago

@disconnect3d Just for doc. I have tried this fix https://sourceware.org/bugzilla/show_bug.cgi?id=29831#c2 It doesn't help

disconnect3d commented 1 year ago

Do you mean that you applied the latch to the latest gdb version? but what is your full setup? dont you use gdbserver? (maybe the fix has to be applied to it as well somehow)

On Sun, 7 May 2023 at 13:48, yooo1999 @.***> wrote:

@disconnect3d https://github.com/disconnect3d Just for doc. I have tried this fix https://sourceware.org/bugzilla/show_bug.cgi?id=29831#c2 It doesn't help

— Reply to this email directly, view it on GitHub https://github.com/pwndbg/pwndbg/issues/1599#issuecomment-1537420178, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMLWCTFLUJ4NCXMSPLZD3TXE6DX5ANCNFSM6AAAAAAVJFFAYA . You are receiving this because you were mentioned.Message ID: @.***>

yooo1999 commented 1 year ago

@disconnect3d yes, I used gdb-server version 12.1 (with that patch) and gdb-multiarch 12.0.90

disconnect3d commented 1 year ago

Just to be sure: is the patch also applied to gdb-multiarch?

yooo1999 commented 1 year ago

@disconnect3d No , I re-compile the gdb-server with that patch , I didn't touch gdb-multiarch.

disconnect3d commented 1 year ago

I would try recompiling gdb with the patch as well

On Sun, 7 May 2023 at 18:37, yooo1999 @.***> wrote:

@disconnect3d https://github.com/disconnect3d No , I re-compile the gdb-server with that patch , I didn't touch gdb-multiarch.

— Reply to this email directly, view it on GitHub https://github.com/pwndbg/pwndbg/issues/1599#issuecomment-1537487555, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACMLWCWG5LKG2B5LKXSRVLLXE7FTVANCNFSM6AAAAAAVJFFAYA . You are receiving this because you were mentioned.Message ID: @.***>

yooo1999 commented 1 year ago

@disconnect3d I understand that is GDB bug and not pwndbg bug, But maybe just catch that exception into pwndbg and print offer how to set proper breakpoint using Python

disconnect3d commented 1 year ago

Reopening to discuss if we should catch the exception and inform the user about GDB bug + remediation with using breakpoints in Python scripts?

cc: @gsingh93 wdyt?