binutils-gdb/gdb/gdbserver/target.c
Pedro Alves 1a3d890bcc [GDBserver]: Silence exits if GDB is connected through stdio.
If we make gdbserver gdb_continue_to_end actually expect a process
exit with GDBserver, we get many testsuite failures with the remote
stdio board:

-PASS: gdb.arch/amd64-disp-step.exp: continue until exit at amd64-disp-step
+FAIL: gdb.arch/amd64-disp-step.exp: continue until exit at amd64-disp-step (the program exited)
-PASS: gdb.base/break.exp: continue until exit at recursive next test
+FAIL: gdb.base/break.exp: continue until exit at recursive next test (the program exited)
-PASS: gdb.base/chng-syms.exp: continue until exit at breakpoint first time through
+FAIL: gdb.base/chng-syms.exp: continue until exit at breakpoint first time through (the program exited)
... etc. ...

This is what the log shows for all of them:

 (gdb) continue
 Continuing.

 Child exited with status 0
 GDBserver exiting
 [Inferior 1 (process 22721) exited normally]
 (gdb) FAIL: gdb.arch/amd64-disp-step.exp: continue until exit (the program exited)

The problem is the whole "Child exited ... GDBserver exiting" output,
that comes out of GDBserver, and that the testsuite is not expecting.

I pondered somehow making the testsuite adjust to this.  But,
testsuite aside, I think GDBserver should not be outputting this at
all when GDB is connected through stdio.  GDBserver will be printing
this in GDB's console, but the user can already tell from the regular
output that the inferior is gone.

Again, manually:

 (gdb) tar remote | ./gdbserver/gdbserver - program
 Remote debugging using | ./gdbserver/gdbserver - program
 Process program created; pid = 22486
 stdin/stdout redirected
 Remote debugging using stdio
 done.
 Loaded symbols for /lib64/ld-linux-x86-64.so.2
 0x000000323d001530 in _start () from /lib64/ld-linux-x86-64.so.2
 (gdb) c
 Continuing.
 Child exited with status 1
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 GDBserver exiting
 ^^^^^^^^^^^^^^^^^
 [Inferior 1 (process 22486) exited with code 01]
 (gdb)

Suppressing those two lines makes the output be exactly like when
debugging against a remote tcp gdbserver:

 (gdb) c
 Continuing.
 [Inferior 1 (process 22914) exited with code 01]
 (gdb)

2013-10-02  Pedro Alves  <palves@redhat.com>

	* server.c (process_serial_event): Don't output "GDBserver
	exiting" if GDB is connected through stdio.
	* target.c (mywait): Likewise, be silent if GDB is connected
	through stdio.
2013-10-02 11:42:35 +00:00

160 lines
4.2 KiB
C

/* Target operations for the remote server for GDB.
Copyright (C) 2002-2013 Free Software Foundation, Inc.
Contributed by MontaVista Software.
This file is part of GDB.
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 "server.h"
#include "tracepoint.h"
struct target_ops *the_target;
void
set_desired_inferior (int use_general)
{
struct thread_info *found;
if (use_general == 1)
found = find_thread_ptid (general_thread);
else
found = find_thread_ptid (cont_thread);
if (found == NULL)
current_inferior = (struct thread_info *) all_threads.head;
else
current_inferior = found;
}
int
read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
int res;
res = (*the_target->read_memory) (memaddr, myaddr, len);
check_mem_read (memaddr, myaddr, len);
return res;
}
int
write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
int len)
{
/* Lacking cleanups, there is some potential for a memory leak if the
write fails and we go through error(). Make sure that no more than
one buffer is ever pending by making BUFFER static. */
static unsigned char *buffer = 0;
int res;
if (buffer != NULL)
free (buffer);
buffer = xmalloc (len);
memcpy (buffer, myaddr, len);
check_mem_write (memaddr, buffer, myaddr, len);
res = (*the_target->write_memory) (memaddr, buffer, len);
free (buffer);
buffer = NULL;
return res;
}
ptid_t
mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
int connected_wait)
{
ptid_t ret;
if (connected_wait)
server_waiting = 1;
ret = (*the_target->wait) (ptid, ourstatus, options);
/* If GDB is connected through TCP/serial, then GDBserver will most
probably be running on its own terminal/console, so it's nice to
print there why is GDBserver exiting. If however, GDB is
connected through stdio, then there's no need to spam the GDB
console with this -- the user will already see the exit through
regular GDB output, in that same terminal. */
if (!remote_connection_is_stdio ())
{
if (ourstatus->kind == TARGET_WAITKIND_EXITED)
fprintf (stderr,
"\nChild exited with status %d\n", ourstatus->value.integer);
else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
gdb_signal_to_host (ourstatus->value.sig),
gdb_signal_to_name (ourstatus->value.sig));
}
if (connected_wait)
server_waiting = 0;
return ret;
}
int
start_non_stop (int nonstop)
{
if (the_target->start_non_stop == NULL)
{
if (nonstop)
return -1;
else
return 0;
}
return (*the_target->start_non_stop) (nonstop);
}
void
set_target_ops (struct target_ops *target)
{
the_target = (struct target_ops *) xmalloc (sizeof (*the_target));
memcpy (the_target, target, sizeof (*the_target));
}
/* Convert pid to printable format. */
const char *
target_pid_to_str (ptid_t ptid)
{
static char buf[80];
if (ptid_equal (ptid, minus_one_ptid))
xsnprintf (buf, sizeof (buf), "<all threads>");
else if (ptid_equal (ptid, null_ptid))
xsnprintf (buf, sizeof (buf), "<null thread>");
else if (ptid_get_tid (ptid) != 0)
xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx",
ptid_get_pid (ptid), ptid_get_tid (ptid));
else if (ptid_get_lwp (ptid) != 0)
xsnprintf (buf, sizeof (buf), "LWP %d.%ld",
ptid_get_pid (ptid), ptid_get_lwp (ptid));
else
xsnprintf (buf, sizeof (buf), "Process %d",
ptid_get_pid (ptid));
return buf;
}
int
kill_inferior (int pid)
{
gdb_agent_about_to_close (pid);
return (*the_target->kill) (pid);
}