78708b7c8c
The target->request_interrupt callback implements the handling for ctrl-c. User types ctrl-c in GDB, GDB sends a \003 to the remote target, and the remote targets stops the program with a SIGINT, just like if the user typed ctrl-c in GDBserver's terminal. The trouble is that using kill_lwp(signal_pid, SIGINT) sends the SIGINT directly to the program's main thread. If that thread has exited already, then that kill won't do anything. Instead, send the SIGINT to the process group, just like GDB does (see inf-ptrace.c:inf_ptrace_stop). gdb.threads/leader-exit.exp is extended to cover the scenario. It fails against GDBserver before the patch. Tested on x86_64 Fedora 20, native and GDBserver. gdb/gdbserver/ 2014-11-12 Pedro Alves <palves@redhat.com> * linux-low.c (linux_request_interrupt): Always send a SIGINT to the process group instead of to a specific LWP. gdb/testsuite/ 2014-11-12 Pedro Alves <palves@redhat.com> * gdb.threads/leader-exit.exp: Test sending ctrl-c works after the leader has exited.
50 lines
1.2 KiB
C
50 lines
1.2 KiB
C
/* Clean exit of the thread group leader should not break GDB.
|
|
|
|
Copyright 2007-2014 Free Software Foundation, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
#include <pthread.h>
|
|
#include <assert.h>
|
|
#include <unistd.h>
|
|
|
|
static volatile pthread_t main_thread;
|
|
|
|
static void *
|
|
start (void *arg)
|
|
{
|
|
int i;
|
|
|
|
i = pthread_join (main_thread, NULL);
|
|
assert (i == 0);
|
|
|
|
sleep (10); /* break-here */
|
|
return arg;
|
|
}
|
|
|
|
int
|
|
main (void)
|
|
{
|
|
pthread_t thread;
|
|
int i;
|
|
|
|
main_thread = pthread_self ();
|
|
|
|
i = pthread_create (&thread, NULL, start, NULL);
|
|
assert (i == 0);
|
|
|
|
pthread_exit (NULL);
|
|
/* NOTREACHED */
|
|
return 0;
|
|
}
|