Bug 19558 - Trying to attach the same process twice borks gdbserver
Summary: Trying to attach the same process twice borks gdbserver
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-02-02 19:13 UTC by Simon Marchi
Modified: 2024-04-26 21:12 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Marchi 2016-02-02 19:13:22 UTC
Trying to attach to the same process twice (a bad manipulation from the user) leads to gdbserver's internal state to be messed up.

I started gdbserver with:

$ gdbserver --multi :1234

Then, in gdb:

$ gdb
(gdb) tar ext :1234
...
(gdb) attach 5549
...
(gdb) add-inferior
(gdb) inferior 2
(gdb) attach 5549
Attaching to process 5549
Attaching to process 5549 failed


gdbserver displays the right error:

gdbserver: Cannot attach to process 5549: Operation not permitted (1), process 5549 is already traced by process 5379

but then it appears that gdb disconnects, because gdbserver prints this again:

Listening on port 1234

Then, pretty everything in the gdb session is broken.

(gdb) inferior 1
(gdb) info threads
Unknown remote qXfer reply: OK
Comment 1 Marc Dumais 2016-02-09 19:08:06 UTC
It seems that this issue can be reproduced with a single attach, if the attach somehow fails. For example, if the user doesn't have permission to attach to the process.
Comment 2 Pedro Alves 2016-02-09 23:12:41 UTC
Is this a regression?
Comment 3 Marc Dumais 2016-02-10 11:11:38 UTC
(In reply to Pedro Alves from comment #2)
> Is this a regression?

Hi Pedro,

It doesn't seem to be. I have reproduced this with a few versions, down-to 7.6.1, but did not try older versions.
Comment 4 Pedro Alves 2016-02-10 11:13:38 UTC
Thanks Marc.  (Trying to access where this one stands re. priority for gdb 7.11.)
Comment 5 Simon Marchi 2017-12-31 14:42:47 UTC
Another consequence of the same bug, if you start gdbserver with --once, gdbserver exits when an attach fails.  I don't think that's right.
Comment 6 Simon Marchi 2021-06-05 04:36:27 UTC
I just stumbled on this again, it's still present.
Comment 7 Sourceware Commits 2021-08-05 16:28:43 UTC
The master branch has been updated by Simon Marchi <simark@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4b0cf3d6d0ff4a737f8aee2ed388fbc72ba941be

commit 4b0cf3d6d0ff4a737f8aee2ed388fbc72ba941be
Author: Simon Marchi <simon.marchi@polymtl.ca>
Date:   Thu Jun 10 10:47:40 2021 -0400

    gdb/testsuite: gdb.base/attach.exp: expose bug when testing with native-extended-gdbserver
    
    In gdb.base/attach.exp, proc do_attach_failure_tests, we attach to a
    process.  When then try to attach to the same process in another
    inferior, expecting it to fail.  We then come back to the first inferior
    and try to kill it, to clean up the test.  When using the
    native-extended-gdbserver board, this "kill" test passes, even though it
    didn't actually work:
    
        add-inferior
        [New inferior 2]
        Added inferior 2 on connection 1 (extended-remote localhost:2347)
        (gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: add empty inferior 2
        inferior 2
        [Switching to inferior 2 [<null>] (<noexec>)]
        (gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 2
        attach 817032
        Attaching to process 817032
        Attaching to process 817032 failed
        (gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: fail to attach again
        inferior 1
        [Switching to inferior 1 [process 817032] (/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/attach/attach)]
        [Switching to thread 1.1 (Thread 817032.817032)]
        #0  main () at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/attach.c:19
        19    while (! should_exit)
        (gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 1
        kill
        Kill the program being debugged? (y or n) y
        Remote connection closed  <==== That's unexpected
        (gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: exit after attach failures
    
    When the second attach fails, gdbserver seems to break the connection
    (it hangs up on the existing remote target) and start listening again
    for incoming connections.  This is documented in PR 19558 [1].
    
    Make the expected output regexp for the kill command tighter (it
    currently accepts anything).  Use "set confirm off" so we don't have to
    deal with the confirmation.  And to be really sure the extended-remote
    target still works, try to run the inferior again after killing.  The
    now tests are kfail'ed when the target is gdbserver.
    
    [1] https://sourceware.org/bugzilla/show_bug.cgi?id=19558
    
    gdb/testsuite/ChangeLog:
    
            * gdb.base/attach.exp (do_attach_failure_tests): Make kill
            regexp tighter, run inferior after killing it.  Kfail when
            target is gdbserver.
    
    Change-Id: I99c5cd3968ce2ec962ace35b016f842a243b7a0d
Comment 8 Sourceware Commits 2024-04-26 20:24:12 UTC
The master branch has been updated by Pedro Alves <palves@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f1fc8dc2dccb4a224cdd1c3973c7a09a752aa95b

commit f1fc8dc2dccb4a224cdd1c3973c7a09a752aa95b
Author: Pedro Alves <pedro@palves.net>
Date:   Wed Apr 17 19:26:32 2024 +0100

    Fix "attach" failure handling with GDBserver
    
    This fixes the same issue as the previous patch, but for "attach"
    instead of "run".
    
    If attaching to a process with "attach" (vAttach packet) fails,
    GDBserver throws an error that escapes all the way to the top level.
    When an error escapes all the way like that, GDBserver interprets it
    as a disconnection, and either goes back to waiting for a new GDB
    connection, or exits, if --once was specified.
    
    Here's an example:
    
    On the GDB side:
    
     ...
     (gdb) tar extended-remote :9999
     ...
     Remote debugging using :9999
     (gdb) attach 1
     Attaching to process 1
     Attaching to process 1 failed
     (gdb)
    
    On the GDBserver side:
    
     $ gdbserver --once --multi :9999
     Listening on port 9999
     Remote debugging from host 127.0.0.1, port 37464
     gdbserver: Cannot attach to process 1: Operation not permitted (1)
     $   # gdbserver exited
    
    This is wrong, as we've connected with extended-remote/--multi.
    GDBserver should just report an error to vAttach, and continue
    connected to GDB, waiting for other commands.
    
    This commit fixes GDBserver by catching the error locally in
    handle_v_attach.
    
    Note we now let pid == 0 pass down to attach_inferior.  That is so we
    get a useful textual error message to report to GDB.
    
    This fixes a couple KFAILs in gdb.base/attach.exp.  Still, I thought
    it would be useful to add a new testcase specifically for this
    scenario, in case gdb.base/attach.exp is ever split and stops trying
    to attach again after a failed attach, with the same GDB session.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=19558
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31554
    
    Change-Id: I25314c7e5f1435eff69cb84d57ecac13d8de3393
    Approved-By: Tom Tromey <tom@tromey.com>
Comment 9 Pedro Alves 2024-04-26 21:12:01 UTC
Should be fixed now.