Hi Support, it looks like a bug has been introduced, somewhere between 7.5 & 7.9. I do not have all the intermediate builds available to narrow this down. I have a very simple testcase, running on Fedora Linux, but appears to be a general issue I even reproduced on an ARM target. 1: #include <stdio.h> 2: int main() { 3: int cond = 0; 4: while(cond == 0) { /* do nothing */ } // BREAK at this line 5: return 0; 6: } compile for debug $ gcc -g -o app.exe app.c run the application in gdbserver $ gdbserver localhost:9999 app.exe in gdb do the following $ gdb app.exe (gdb) target remote localhost:9999 (gdb) b app.c:4 (gdb) continue (gdb) next so now gdb is trying to run to the 'next' line, which it cannot reach because the condition in the while loop is always true, so interrupt by sending CTRL-C (gdb) ^C nothing happens The session is now locked up, if you issue another CTRL-C, the gdb client will Quit (gdb)^CQuit The gdbserver is still running, but I have failed to interrupt Try the same with gdb version 7.5 and it works Thx Lee
This is 7.12.1 server and client. Having no breakpoints it is not possible to pause execution by CTRL+c at all, as it is done using the native gdb: server $ gdbserver --multi --attach localhost:8888 $(pgrep -f my_app) client $ gdb target extended-remote localhost:8888 Remote debugging using localhost:8888 Reading /lib64/libdl.so.2 from remote target... Reading /lib64/libSegFault.so from remote target... ... Reading /lib64/ld-linux-x86-64.so.2 from remote target... 0x00007f6b26857923 in __select_nocancel () from target:/lib64/libc.so.6 (gdb) where #0 0x00007f6b26857923 in __select_nocancel () from target:/lib64/libc.so.6 ... #9 0x00000000004497ee in main (argc=14, argv=0x7ffe8e4b0af8) at main.cpp:245 (gdb) c Continuing. ^C^CThe target is not responding to interrupt requests. Stop debugging it? (y or n) y Disconnected from target.
This appears to still be a problem in gdb 8. It also seems to be a problem for sim targets. (Sometimes CTRL-C can break a windows sim target, but never on Linux). Note that CTRL-C only seems to be ignored for the 'next' or 'step' commands. If you 'continue' instead of 'next', then CTRL-C seems to work for me: (gdb) run Starting program: test.exe ^C Program received signal SIGINT, Interrupt. 0x000000bc in main () at test.c:6 6 while(!x) (gdb) c Continuing. ^C Program received signal SIGINT, Interrupt. 0x000000bc in main () at test.c:6 6 while(!x) (gdb) n ^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C
Looks like this is triggered by https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commit;h=78708b7c8ccc2138880217de9bd60eceff683f10 following change worked for me: diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 94af240..2e5776f 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -5936,7 +5936,9 @@ linux_request_interrupt (void) { /* Send a SIGINT to the process group. This acts just like the user typed a ^C on the controlling terminal. */ - kill (-signal_pid, SIGINT); + int r = kill (-signal_pid, SIGINT); + if (r != 0) + kill (signal_pid, SIGINT); } /* Copy LEN bytes from inferior's auxiliary vector starting at OFFSET
Any progress here? Is the proposed patch a reasonable solution and will be integrated?
I don't think the proposed patch is good, for it is wrong to send SIGINT to the pocess group. See this ticket. Josh suggested the right approach. https://sourceware.org/bugzilla/show_bug.cgi?id=18945 I'm not sure why this bug is not fixed yet. In Yocto project case, they decided to apply the patch. https://git.yoctoproject.org/cgit.cgi/poky/plain/meta/recipes-devtools/gdb/gdb/0011-gdbserver-ctrl-c-handling.patch There're no active gdbserver maintainers?
Agree with rarul, sending interrupt to group process is not a good choice. My post about it: https://sourceware.org/bugzilla/show_bug.cgi?id=26575
I tried to reproduce this issue with GDB 8.2 and 11.2 on x86-64 GNU/Linux using Fedora 31, using the test program from the original comment. I can't see any problems interrupting GDB using Ctrl-C. I tested this using 'continue', 'next', and 'step' commands, and in all cases GDB interrupts as expected (i.e. comes to a stop). If any of the original bug reporters are still seeing this issue with a recent version of GDB, then please do follow up and we can reopen this bug, but for no I propose that we close this issue.
wow I logged this 7 years ago! I tried this with gdbserver/gdb 8.1, the problem no longer occurs no idea at what point it got fixed
(In reply to Lee Moore from comment #8) > wow I logged this 7 years ago! > I tried this with gdbserver/gdb 8.1, the problem no longer occurs > > no idea at what point it got fixed This issue still happened to me on an ARMv7 target from a x86_64 host. Adding the patch that sends kill to just the process when sending to the process group fails worked instantly fixed the problem. This is with gdbserver 10.2 and gdb 9.2
(In reply to Andrew Burgess from comment #7) > I tried to reproduce this issue with GDB 8.2 and 11.2 on x86-64 GNU/Linux > using Fedora 31, using the test program from the original comment. > > I can't see any problems interrupting GDB using Ctrl-C. I tested this using > 'continue', 'next', and 'step' commands, and in all cases GDB interrupts as > expected (i.e. comes to a stop). > > If any of the original bug reporters are still seeing this issue with a > recent version of GDB, then please do follow up and we can reopen this bug, > but for no I propose that we close this issue. Did you confirm that the pgid was != to the pid in your testing? In my case, the pgid did not match the pgid or pid of any processes, resulting in the signal not getting sent anywhere.
(In reply to Rich Surgenor from comment #10) > Did you confirm that the pgid was != to the pid in your testing? In my case, > the pgid did not match the pgid or pid of any processes, resulting in the > signal not getting sent anywhere. OK, that's pretty interesting. So I guess you started debugging some process that forks, you follow the fork, then you place the child into a different process group? Or am I overthinking this? I'll try to craft a test that matches your description above later this week, but any further hints you have about the nature of the failing situation would be great. I'm reopening this issue for now.
Created attachment 14082 [details] A reproducer for this issue The attached file sig-c-bug.c is a reproducer for this issue. The bug impacts not just remote targets, but also native Linux targets too as of commit 2b718529b99. Compile up the attached file as: gcc -g3 -O0 -Wall -Wextra -Werror -o sig-c-bug.x sig-c-bug.c Then run the test as: ./gdb/gdb --data-directory ./gdb/data-directory/ \ ~/tmp/sig-c-bug.x \ -q \ -ex 'set detach-on-fork off' \ -ex 'set follow-fork-mode parent' \ -ex 'run' \ -ex 'info inferiors' \ -ex 'inferior 2' \ -ex 'continue' You should end up with inferior 2 running, every second you'll see a new line of this output: Tick: 0 Tick: 1 Tick: 2 Tick: 3 Tick: 4 ... and so on ... try to interrupt gdb using ctrl-c ... it doesn't work for me. Inferior 2 will automatically exit after 'Tick: 9', at which point you need to restart the test. The same behaviour can be seen when using a remote target, just start gdbserver something like: gdbserver --multi :54321 sig-c-bug.x and then: ./gdb/gdb --data-directory ./gdb/data-directory/ \ ~/tmp/sig-c-bug.x \ -q \ -ex 'set sysroot /' \ -ex 'set detach-on-fork off' \ -ex 'set follow-fork-mode parent' \ -ex 'target extended-remote :54321' \ -ex 'continue' \ -ex 'info inferiors' \ -ex 'inferior 2' \ -ex 'continue' and the remote target will be ticking in inferior 2, and can't be interrupted.
Once I'm done with my current priorities, my next project will be going back to this: [PATCH v2 00/16] Interrupting programs that block/ignore SIGINT https://pi.simark.ca/gdb-patches/20210614212410.1612666-1-pedro@palves.net/ That redesigns how SIGINT is handled when native debugging, such that GDB _always_ gets the SIGINT first instead of relying on the inferior getting it, so I suspect it will fix Andrew's testcase when native debugging (though I haven't tried it). As for remote debugging with gdbserver, I will take a look at it too, once I resume work on that series.
(In reply to Pedro Alves from comment #13) > Once I'm done with my current priorities, my next project will be going back > to this: > > [PATCH v2 00/16] Interrupting programs that block/ignore SIGINT > https://pi.simark.ca/gdb-patches/20210614212410.1612666-1-pedro@palves.net/ > > That redesigns how SIGINT is handled when native debugging, such that GDB > _always_ gets the SIGINT first instead of relying on the inferior getting > it, so I suspect it will fix Andrew's testcase when native debugging (though > I haven't tried it). As for remote debugging with gdbserver, I will take a > look at it too, once I resume work on that series. Hey, Any progress on it? I just stumbled on it when debugging an AARCH64 target [0] run via QEMU user emulation [1]. I wonder if that it is a bug in the QEMU user emulation layer here or if comes from GDB? [0] https://github.com/perfectblue/ctf-writeups/tree/master/2019/insomnihack-teaser-2019/nyanc/challenge [1] Via command `qemu-aarch64 -g 1234 ./nyanc`, but I first used patchelf to set interpreter and libc: ``` patchelf --set-interpreter ./ld-linux-aarch64.so.1 ./nyanc patchelf --replace-needed libc.so.6 ./libc.so.6 ./nyanc ```
(In reply to Pedro Alves from comment #13) > Once I'm done with my current priorities, my next project will be going back > to this: > > [PATCH v2 00/16] Interrupting programs that block/ignore SIGINT > https://pi.simark.ca/gdb-patches/20210614212410.1612666-1-pedro@palves.net/ > > That redesigns how SIGINT is handled when native debugging, such that GDB > _always_ gets the SIGINT first instead of relying on the inferior getting > it, so I suspect it will fix Andrew's testcase when native debugging (though > I haven't tried it). As for remote debugging with gdbserver, I will take a > look at it too, once I resume work on that series. Hello community, it seems this patch also broke Eclipse Suspend functionality during debugging. I think the Eclipse also sends CTRL-C when the user presses Suspend button. I noticed it from the GDB release 11.1 (10.2 works). Used remote debugging of the Qemu target Aarch64 with Eclipse in Windows. Feel free to contact me for any support or additional information Best regards, Filip Bascarevic
The master branch has been updated by Tom de Vries <vries@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4c35c4c6a779c79e456b7a5311f74aafc9026bd5 commit 4c35c4c6a779c79e456b7a5311f74aafc9026bd5 Author: Tom de Vries <tdevries@suse.de> Date: Sun Nov 27 10:31:50 2022 +0100 [gdb/server] Emit warning for SIGINT failure Consider the executable from test-case gdb.base/interrupt-daemon.exp. When starting it using gdbserver: ... $ ./build/gdbserver/gdbserver localhost:2345 \ ./outputs/gdb.base/interrupt-daemon/interrupt-daemon ... and connecting to it using gdb: ... $ gdb -q -ex "target remote localhost:2345" \ -ex "set follow-fork-mode child" \ -ex "break daemon_main" -ex cont ... we are setup to do the same as in the test-case: interrupt a running inferior using ^C. So let's try: ... (gdb) continue Continuing. ^C ... After pressing ^C, nothing happens. This a known problem, filed as PR remote/18772. The problem is that in linux_process_target::request_interrupt, a kill is used to send a SIGINT, but it fails. And it fails silently. Make the failure verbose by adding a warning, such that the gdbserver output becomes more helpful: ... Process interrupt-daemon created; pid = 15068 Listening on port 2345 Remote debugging from host ::1, port 35148 Detaching from process 15068 Detaching from process 15085 gdbserver: Sending SIGINT to process group of pid 15068 failed: \ No such process ... Note that the failure can easily be reproduced using the test-case and target board native-gdbserver: ... (gdb) continue^M Continuing.^M PASS: gdb.base/interrupt-daemon.exp: fg: continue ^CFAIL: gdb.base/interrupt-daemon.exp: fg: ctrl-c stops process (timeout) ... as reported in PR server/23382. Tested on x86_64-linux. Approved-By: Simon Marchi <simon.marchi@efficios.com>
There's one more thing why the naive `kill (-signal_pid, SIGINT);` is wrong. In case the target PID is 1, it calls `kill` passing -1 to it, which has a special meaning (quoting https://man7.org/linux/man-pages/man2/kill.2.html#DESCRIPTION): If pid equals -1, then sig is sent to every process for which the calling process has permission to send signals, except for process 1 (init), but see below. That is, it attempts to interrupt any process other than the one it is supposed to! Debugging PID 1 may sound an edge case, but it is actually perfectly fine to do so in case of a sole process running inside a Docker container. In other words, it's not necessarily even the init process, like systemd or upstart, it's often a legit regular program that you develop yourself.
On Linux at least we could use PTRACE_INTERRUPT, see bug #15250.