13b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--------------------------------------------------------------------*/
23b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--- Relay between gdb and gdbserver embedded in valgrind  vgdb.c ---*/
33b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*--------------------------------------------------------------------*/
43b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
53b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/*
63b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This file is part of Valgrind, a dynamic binary instrumentation
73b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   framework.
83b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
90f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj   Copyright (C) 2011-2013 Philippe Waroquiers
103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This program is free software; you can redistribute it and/or
123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   modify it under the terms of the GNU General Public License as
133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   published by the Free Software Foundation; either version 2 of the
143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   License, or (at your option) any later version.
153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This program is distributed in the hope that it will be useful, but
173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   General Public License for more details.
203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   You should have received a copy of the GNU General Public License
223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   along with this program; if not, write to the Free Software
233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   02111-1307, USA.
253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   The GNU General Public License is contained in the file COPYING.
273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
280ba37c90c4674515da387b30a6e5f23fa75a173csewardj
293c761f0f0344757ac243c65511392fb41d1c841aphilippe#include "vgdb.h"
303c761f0f0344757ac243c65511392fb41d1c841aphilippe
31b985e2de52983cafd2d17cc6c9e60064847777fdflorian#include "config.h"
32cbe385015145f16e3e88f919d8979df628a535easewardj
333c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <assert.h>
343c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <dirent.h>
353c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <errno.h>
363c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <fcntl.h>
3730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#include <limits.h>
383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <poll.h>
393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <pthread.h>
403c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <signal.h>
413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdlib.h>
423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdio.h>
433c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <string.h>
443c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <unistd.h>
45992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <netinet/in.h>
463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/mman.h>
473c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/socket.h>
483c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/stat.h>
493c761f0f0344757ac243c65511392fb41d1c841aphilippe#include <sys/time.h>
503c761f0f0344757ac243c65511392fb41d1c841aphilippe
513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* vgdb has two usages:
523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   1. relay application between gdb and the gdbserver embedded in valgrind.
533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   2. standalone to send monitor commands to a running valgrind-ified process
543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   It is made of a main program which reads arguments.  If no
563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   arguments are given or only --pid and --vgdb-prefix, then usage 1 is
573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   assumed.
583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As relay application, vgdb reads bytes from gdb on stdin and
603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   writes these bytes to valgrind.  Bytes read from valgrind are
613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   written to gdb on stdout.  Read/Write from/to valgrind is done
623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   using FIFOs.  There is one thread reading from stdin, writing to
633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind on a FIFO.  There is one thread reading from valgrind on a
643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FIFO, writing to gdb on stdout
653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   As a standalone utility, vgdb builds command packets to write to valgrind,
673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends it and reads the reply. The same two threads are used to write/read.
683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Once all the commands are sent and their replies received, vgdb will exit.
693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/
703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
713c761f0f0344757ac243c65511392fb41d1c841aphilippeint debuglevel;
723c761f0f0344757ac243c65511392fb41d1c841aphilippestruct timeval dbgtv;
73b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic char *vgdb_prefix = NULL;
743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Will be set to True when any condition indicating we have to shutdown
763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   is encountered. */
773c761f0f0344757ac243c65511392fb41d1c841aphilippeBool shutting_down = False;
783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
793c761f0f0344757ac243c65511392fb41d1c841aphilippeVgdbShared32 *shared32;
803c761f0f0344757ac243c65511392fb41d1c841aphilippeVgdbShared64 *shared64;
813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_written_by_vgdb (shared32 != NULL ?        \
823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            shared32->written_by_vgdb \
833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            : shared64->written_by_vgdb)
843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_seen_by_valgrind (shared32 != NULL ?         \
853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             shared32->seen_by_valgrind \
863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                             : shared64->seen_by_valgrind)
873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_vgdb_pid (shared32 != NULL ? shared32->vgdb_pid : shared64->vgdb_pid)
893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
903b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vmalloc(size_t size)
913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = malloc(size);
933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't allocate memory\n");
953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
983b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vrealloc(void *ptr,size_t size)
993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void * mem = realloc(ptr, size);
1013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (mem == NULL)
1023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "can't reallocate memory\n");
1033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return mem;
1043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
106b985e2de52983cafd2d17cc6c9e60064847777fdflorian/* Return the name of a directory for temporary files. */
107b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic
108b985e2de52983cafd2d17cc6c9e60064847777fdflorianconst char *vgdb_tmpdir(void)
109b985e2de52983cafd2d17cc6c9e60064847777fdflorian{
110b985e2de52983cafd2d17cc6c9e60064847777fdflorian   const char *tmpdir;
111b985e2de52983cafd2d17cc6c9e60064847777fdflorian
112b985e2de52983cafd2d17cc6c9e60064847777fdflorian   tmpdir = getenv("TMPDIR");
113ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (tmpdir == NULL || *tmpdir == '\0')
114ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe     tmpdir = VG_TMPDIR;
115ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (tmpdir == NULL || *tmpdir == '\0')
116ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe     tmpdir = "/tmp";    /* fallback */
117b985e2de52983cafd2d17cc6c9e60064847777fdflorian
118b985e2de52983cafd2d17cc6c9e60064847777fdflorian   return tmpdir;
119b985e2de52983cafd2d17cc6c9e60064847777fdflorian}
120b985e2de52983cafd2d17cc6c9e60064847777fdflorian
121ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe/* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb
122b985e2de52983cafd2d17cc6c9e60064847777fdflorian   to communicate with valgrind */
123b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic
124b985e2de52983cafd2d17cc6c9e60064847777fdflorianchar *vgdb_prefix_default(void)
125b985e2de52983cafd2d17cc6c9e60064847777fdflorian{
126ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   static HChar *prefix;
127ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe
128ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   if (prefix == NULL) {
129ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      const char *tmpdir = vgdb_tmpdir();
130ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      prefix = vmalloc(strlen(tmpdir) + strlen("/vgdb-pipe") + 1);
131ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      strcpy(prefix, tmpdir);
132ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe      strcat(prefix, "/vgdb-pipe");
133ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe   }
134b985e2de52983cafd2d17cc6c9e60064847777fdflorian   return prefix;
135b985e2de52983cafd2d17cc6c9e60064847777fdflorian}
136b985e2de52983cafd2d17cc6c9e60064847777fdflorian
1373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* add nrw to the written_by_vgdb field of shared32 or shared64 */
1383b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1393b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid add_written(int nrw)
1403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
1423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->written_by_vgdb += nrw;
1433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
1443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->written_by_vgdb += nrw;
1453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
1463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
1473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int shared_mem_fd = -1;
1503b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid map_vgdbshared (char* shared_mem)
1523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct stat fdstat;
1543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   void **s;
1553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shared_mem_fd = open(shared_mem, O_RDWR);
1563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* shared_mem_fd will not be closed till vgdb exits. */
1573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared_mem_fd == -1)
1593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s shared memory file\n", shared_mem);
1603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fstat(shared_mem_fd, &fdstat) != 0)
1623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "fstat");
1633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fdstat.st_size == sizeof(VgdbShared64))
1653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared64;
1663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (fdstat.st_size == sizeof(VgdbShared32))
1673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      s = (void*) &shared32;
1683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
1693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8
1703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
1713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
1723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (64bits) or %d (32bits) got %ld.\n",
1733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
1743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared64), (int) sizeof(VgdbShared32),
1753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (long int)fdstat.st_size);
1763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4
1773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0,
1783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "error size shared memory file %s.\n"
1793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "expecting size %d (32bits) got %ld.\n",
1803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              shared_mem,
1813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (int) sizeof(VgdbShared32),
1823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              fdstat.st_size);
1833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else
1843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize"
1853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
1863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 4
1883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared64 != NULL)
1893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (0, "cannot use 32 bits vgdb with a 64bits valgrind process\n");
1903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* But we can use a 64 bits vgdb with a 32 bits valgrind */
1913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif
1923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *s = (void*) mmap (NULL, fdstat.st_size,
1943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      PROT_READ|PROT_WRITE, MAP_SHARED,
1953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      shared_mem_fd, 0);
1963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*s == (void *) -1)
1983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error mmap shared memory file %s\n", shared_mem);
1993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
2013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* This function loops till shutting_down becomes true.  In this loop,
2033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   it verifies if valgrind process is reading the characters written
2043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   by vgdb.  The verification is done every max_invoke_ms ms.  If
2053c761f0f0344757ac243c65511392fb41d1c841aphilippe   valgrind is not reading characters, it will use invoker_invoke_gdbserver
2063c761f0f0344757ac243c65511392fb41d1c841aphilippe   to ensure that the gdbserver code is called soon by valgrind. */
2073b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int max_invoke_ms = 100;
20830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#define NEVER 99999999
20930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic int cmd_time_out = NEVER;
2103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
2113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *invoke_gdbserver_in_valgrind(void *v_pid)
2123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
21330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval cmd_max_end_time;
21430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   Bool cmd_started = False;
21530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   struct timeval invoke_time;
21630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
2173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = *(int *)v_pid;
2183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int written_by_vgdb_before_sleep;
2193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int seen_by_valgrind_before_sleep;
2203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int invoked_written = -1;
22230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   unsigned int usecs;
2233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2243c761f0f0344757ac243c65511392fb41d1c841aphilippe   pthread_cleanup_push(invoker_cleanup_restore_and_detach, v_pid);
2253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
2263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (!shutting_down) {
2273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      written_by_vgdb_before_sleep = VS_written_by_vgdb;
2283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      seen_by_valgrind_before_sleep = VS_seen_by_valgrind;
2293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(3,
2303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "written_by_vgdb_before_sleep %d "
2313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            "seen_by_valgrind_before_sleep %d\n",
2323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            written_by_vgdb_before_sleep,
2333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            seen_by_valgrind_before_sleep);
23430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_time_out != NEVER
23530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && !cmd_started
23630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj          && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) {
23730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         /* A command was started. Record the time at which it was started. */
23830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         DEBUG(1, "IO for command started\n");
23930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&cmd_max_end_time, NULL);
24030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_max_end_time.tv_sec += cmd_time_out;
24130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         cmd_started = True;
24230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
24330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (max_invoke_ms > 0) {
24430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 1000 * max_invoke_ms;
24530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&invoke_time, NULL);
24630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += max_invoke_ms / 1000;
24730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000);
24830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000);
24930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000);
25030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
25130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         usecs = 0;
25230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
25330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      if (cmd_started) {
25430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // 0 usecs here means the thread just has to check gdbserver eats
25530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // the characters in <= cmd_time_out seconds.
25630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // We will just wait by 1 second max at a time.
25730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (usecs == 0 || usecs > 1000 * 1000)
25830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            usecs = 1000 * 1000;
25930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      }
260992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      usleep(usecs);
261992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
26230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      /* If nothing happened during our sleep, let's try to wake up valgrind
26330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         or check for cmd time out. */
2643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (written_by_vgdb_before_sleep == VS_written_by_vgdb
2653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && seen_by_valgrind_before_sleep == VS_seen_by_valgrind
2663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          && VS_written_by_vgdb > VS_seen_by_valgrind) {
26730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         struct timeval now;
26830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         gettimeofday(&now, NULL);
2693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(2,
2703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "after sleep "
2713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "written_by_vgdb %d "
2723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "seen_by_valgrind %d "
2733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               "invoked_written %d\n",
2743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_written_by_vgdb,
2753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               VS_seen_by_valgrind,
2763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               invoked_written);
2773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* if the pid does not exist anymore, we better stop */
2783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (kill(pid, 0) != 0)
2793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           XERROR (errno,
2803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "invoke_gdbserver_in_valgrind: "
2813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "check for pid %d existence failed\n", pid);
28230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_started) {
28330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (timercmp (&now, &cmd_max_end_time, >))
28430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               XERROR (0,
28530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       "pid %d did not handle a command in %d seconds\n",
28630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                       pid, cmd_time_out);
28730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
28830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) {
28930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            /* only need to wake up if the nr written has changed since
29030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               last invoke. */
29130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            if (invoked_written != written_by_vgdb_before_sleep) {
2923c761f0f0344757ac243c65511392fb41d1c841aphilippe               if (invoker_invoke_gdbserver(pid)) {
29330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  /* If invoke succesful, no need to invoke again
29430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                     for the same value of written_by_vgdb_before_sleep. */
29530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                  invoked_written = written_by_vgdb_before_sleep;
29630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               }
2973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
29830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
29930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else {
30030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         // Something happened => restart timer check.
30130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (cmd_time_out != NEVER) {
30230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            DEBUG(2, "some IO was done => restart command\n");
30330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            cmd_started = False;
3043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
3053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
3063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   pthread_cleanup_pop(0);
3083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return NULL;
3093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3126bd9dc18c043927c1196caba20a327238a179c42florianint open_fifo (const char* name, int flags, const char* desc)
3133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int fd;
3153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opening %s %s\n", name, desc);
3163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open(name, flags);
3173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1)
3183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "error opening %s %s\n", name, desc);
3193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "opened %s %s fd %d\n", name, desc, fd);
3213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return fd;
3223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* acquire a lock on the first byte of the given fd. If not successful,
3253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   exits with error.
3263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   This allows to avoid having two vgdb speaking with the same Valgrind
3273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   gdbserver as this causes serious headaches to the protocol. */
3283b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3293b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid acquire_lock (int fd, int valgrind_pid)
3303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
331992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   struct flock fl;
332992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_type = F_WRLCK;
333992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_whence = SEEK_SET;
334992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_start = 0;
335992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   fl.l_len = 1;
336992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (fcntl(fd, F_SETLK, &fl) < 0) {
3373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (errno == EAGAIN || errno == EACCES) {
3383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno,
3393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Cannot acquire lock.\n"
3403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "Probably vgdb pid %d already speaks with Valgrind pid %d\n",
3413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                VS_vgdb_pid,
3423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                valgrind_pid);
3433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
3443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR(errno, "cannot acquire lock.\n");
3453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
3463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Here, we have the lock. It will be released when fd will be closed. */
3493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We indicate our pid to Valgrind gdbserver */
3503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (shared32 != NULL)
3513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared32->vgdb_pid = getpid();
3523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (shared64 != NULL)
3533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shared64->vgdb_pid = getpid();
3543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
3553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      assert(0);
3563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PBUFSIZ 16384 /* keep in sync with server.h */
3593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* read some characters from fd.
3613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the nr of characters read, -1 if error.
3623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a string used in tracing */
3633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3646bd9dc18c043927c1196caba20a327238a179c42florianint read_buf (int fd, char* buf, const char* desc)
3653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
3673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "reading %s\n", desc);
3683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read(fd, buf, PBUFSIZ);
3693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread == -1) {
3703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR (errno, "error reading %s\n", desc);
3713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return -1;
3723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
3733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[nrread] = '\0';
3743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(2, "read %s %s\n", desc, buf);
3753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return nrread;
3763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
3773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
3783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* write size bytes from buf to fd.
3793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   desc is a description of the action for which the write is done.
3803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   If notify, then add size to the shared cntr indicating to the
3813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   valgrind process that there is new data.
3823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns True if write is ok, False if there was a problem. */
3833b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
3846bd9dc18c043927c1196caba20a327238a179c42florianBool write_buf(int fd, char* buf, int size, const char* desc, Bool notify)
3853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
3863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrwritten;
3873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrw;
38866bc6e53d12d6d107eab3bebcfc814ff5179d1dcphilippe   DEBUG(2, "writing %s len %d %.*s notify: %d\n", desc, size,
38966bc6e53d12d6d107eab3bebcfc814ff5179d1dcphilippe         size, buf, notify);
3903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrwritten = 0;
3913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (nrwritten < size) {
3923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrw = write (fd, buf+nrwritten, size - nrwritten);
3933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrw == -1) {
3943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR(errno, "error write %s\n", desc);
3953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         return False;
3963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
3973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      nrwritten = nrwritten + nrw;
3983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (notify)
3993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         add_written(nrw);
4003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
4023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4043b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef enum {
4053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_GDB,
4063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_GDB,
4073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   FROM_PID,
4083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   TO_PID } ConnectionKind;
4093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int NumConnectionKind = TO_PID+1;
4103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4116bd9dc18c043927c1196caba20a327238a179c42florianconst char *ppConnectionKind (ConnectionKind con)
4123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   switch (con) {
4143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_GDB: return "FROM_GDB";
4153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_GDB:   return "TO_GDB";
4163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case FROM_PID: return "FROM_PID";
4173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case TO_PID:   return "TO_PID";
4183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   default:       return "invalid connection kind";
4193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *shared_mem;
4233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
424992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int from_gdb = 0; /* stdin by default, changed if --port is given. */
4253b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *from_gdb_to_pid; /* fifo name to write gdb command to pid */
4263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
4273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
4283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid is the file descriptor to write to the process pid. */
4293b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4303b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_gdb_write_to_pid(int to_pid)
4313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4321d76a80d63502951cb9cbf6f696d663f093083faphilippe   char buf[PBUFSIZ+1]; // +1 for trailing \0
4333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
4343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_gdb, buf, "from gdb on stdin");
4363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
4373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
4383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from gdb => assume exit\n");
4393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
4403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from gdb\n");
4413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_gdb);
4423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
4433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
4443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_pid, buf, nrread, "to_pid", /* notify */ True);
4463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
448992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int to_gdb = 1; /* stdout by default, changed if --port is given. */
4493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *to_gdb_from_pid; /* fifo name to read pid replies */
4503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly.
4513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns False in case of error.
4523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid is the file descriptor to read data from the process pid. */
4533b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
4543b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_pid_write_to_gdb(int from_pid)
4553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
4561d76a80d63502951cb9cbf6f696d663f093083faphilippe   char buf[PBUFSIZ+1]; // +1 for trailing \0
4573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nrread;
4583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
4593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   nrread = read_buf(from_pid, buf, "from pid");
4603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (nrread <= 0) {
4613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (nrread == 0)
4623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "read 0 bytes from pid => assume exit\n");
4633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
4643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "error reading bytes from pid\n");
4653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      close (from_pid);
4663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
4673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
4683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
4693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return write_buf(to_gdb, buf, nrread, "to_gdb", /* notify */ False);
4703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
4713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
472992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic
473992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjvoid wait_for_gdb_connect (int in_port)
474992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj{
475992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   struct sockaddr_in addr;
476992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
477992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int listen_gdb = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
478992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int gdb_connect;
479992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
480992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (-1 == listen_gdb) {
481992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "cannot create socket");
482992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   }
483992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
484992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    memset(&addr, 0, sizeof(addr));
485992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
486992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_family = AF_INET;
487992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_port = htons((unsigned short int)in_port);
488992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    addr.sin_addr.s_addr = INADDR_ANY;
489992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
490992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (-1 == bind(listen_gdb,(struct sockaddr *)&addr, sizeof(addr))) {
491992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "bind failed");
492992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
493992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fprintf(stderr, "listening on port %d ...", in_port);
494992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fflush(stderr);
495992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (-1 == listen(listen_gdb, 1)) {
496992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      XERROR(errno, "error listen failed");
497992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
498992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
499992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    gdb_connect = accept(listen_gdb, NULL, NULL);
500992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    if (gdb_connect < 0) {
501992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj        XERROR(errno, "accept failed");
502992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    }
503992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fprintf(stderr, "connected.\n");
504992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    fflush(stderr);
505992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    close(listen_gdb);
506992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    from_gdb = gdb_connect;
507992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj    to_gdb = gdb_connect;
508992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj}
509992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
5103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* prepares the FIFOs filenames, map the shared memory. */
5113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
5123b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid prepare_fifos_and_shared_mem(int pid)
5133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
514ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   const HChar *user, *host;
515ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   unsigned len;
516ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
517ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   user = getenv("LOGNAME");
518ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (user == NULL) user = getenv("USER");
519ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (user == NULL) user = "???";
520511df4ecbd147628cb33f556e34d4c0dbfbff51aflorian   if (strchr(user, '/')) user = "???";
521ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
522ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   host = getenv("HOST");
523ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (host == NULL) host = getenv("HOSTNAME");
524ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   if (host == NULL) host = "???";
525511df4ecbd147628cb33f556e34d4c0dbfbff51aflorian   if (strchr(host, '/')) host = "???";
526ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian
527ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   len = strlen(vgdb_prefix) + strlen(user) + strlen(host) + 40;
528ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   from_gdb_to_pid = vmalloc (len);
529ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   to_gdb_from_pid = vmalloc (len);
530ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   shared_mem      = vmalloc (len);
5313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* below 3 lines must match the equivalent in remote-utils.c */
532ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(from_gdb_to_pid, "%s-from-vgdb-to-%d-by-%s-on-%s",    vgdb_prefix,
533ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
534ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(to_gdb_from_pid, "%s-to-vgdb-from-%d-by-%s-on-%s",    vgdb_prefix,
535ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
536ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian   sprintf(shared_mem,      "%s-shared-mem-vgdb-%d-by-%s-on-%s", vgdb_prefix,
537ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian           pid, user, host);
5383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG (1, "vgdb: using %s %s %s\n",
5393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj          from_gdb_to_pid, to_gdb_from_pid, shared_mem);
5403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   map_vgdbshared(shared_mem);
5423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Convert hex digit A to a number.  */
5453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
5473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjfromhex (int a)
5483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (a >= '0' && a <= '9')
5503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - '0';
5513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (a >= 'a' && a <= 'f')
5523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return a - 'a' + 10;
5533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
5543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR(0, "Reply contains invalid hex digit %c\n", a);
5553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return 0;
5563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns next char from fd.  -1 if error, -2 if EOF.
5593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   NB: must always call it with the same fd */
5603b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
5613b290486cd4cd601b20e04340e593c9ed9717e5fsewardjreadchar (int fd)
5623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
563adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe  static char buf[PBUFSIZ+1]; // +1 for trailing \0
5643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  static int bufcnt = 0;
565adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe  static unsigned char *bufp;
566adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe  // unsigned bufp to e.g. avoid having 255 converted to int -1
5673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt-- > 0)
5693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     return *bufp++;
5703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5711d76a80d63502951cb9cbf6f696d663f093083faphilippe  bufcnt = read_buf (fd, buf, "static buf readchar");
5723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (bufcnt <= 0) {
5743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (bufcnt == 0) {
5753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        fprintf (stderr, "readchar: Got EOF\n");
5763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -2;
5773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     } else {
5783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR (errno, "readchar\n");
5793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        return -1;
5803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
5813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
5823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
583adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe  bufp = (unsigned char *)buf;
5843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  bufcnt--;
5853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return *bufp++;
5863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
5873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Read a packet from fromfd, with error checking,
5893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and store it in BUF.
5903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns length of packet, or -1 if error or -2 if EOF.
5913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Writes ack on ackfd */
5923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
5933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int
5943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjgetpkt (char *buf, int fromfd, int ackfd)
5953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
5963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  char *bp;
5973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  unsigned char csum, c1, c2;
5983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  int c;
5993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  while (1) {
6013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     csum = 0;
6023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
6043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
6053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '$')
6063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
6073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        DEBUG(2, "[getpkt: discarding char '%c']\n", c);
6083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
6093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
6103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
6113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     bp = buf;
6133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     while (1) {
6143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        c = readchar (fromfd);
6153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c < 0)
6163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           return c;
6173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '#')
6183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           break;
6193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        if (c == '*') {
6203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int repeat;
6213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int r;
6223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           int prev;
6233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           prev = *(bp-1);
6243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
6253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           repeat = readchar (fromfd);
6263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += repeat;
6273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           for (r = 0; r < repeat - 29; r ++)
6283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              *bp++ = prev;
6293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        } else {
6303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           *bp++ = c;
6313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           csum += c;
6323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        }
6333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     }
6343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     *bp = 0;
6353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c1 = fromhex (readchar (fromfd));
6373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     c2 = fromhex (readchar (fromfd));
6383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (csum == (c1 << 4) + c2)
6403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj	break;
6413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
6433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              (c1 << 4) + c2, csum, buf);
6443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     if (write (ackfd, "-", 1) != 1)
6453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        ERROR(0, "error when writing - (nack)\n");
6463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     else
6473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj        add_written(1);
6483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  }
6493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  DEBUG(2, "getpkt (\"%s\");  [sending ack] \n", buf);
6513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  if (write (ackfd, "+", 1) != 1)
6523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     ERROR(0, "error when writing + (ack)\n");
6533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  else
6543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj     add_written(1);
6553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj  return bp - buf;
6563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
6573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigint = 0;
6593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigterm = 0;
6603b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigpipe = 0;
6613b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sighup = 0;
6623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1 = 0;
6633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigalrm = 0;
6643b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1_fd = -1;
6653b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic pthread_t invoke_gdbserver_in_valgrind_thread;
6663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
6673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
6683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid received_signal (int signum)
6693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
6703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (signum == SIGINT)
6713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigint++;
6723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGUSR1) {
6733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigusr1++;
6743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (sigusr1_fd >= 0) {
6753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         char control_c = '\003';
6763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         write_buf(sigusr1_fd, &control_c, 1,
6773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   "write \\003 on SIGUSR1", /* notify */ True);
6783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
6793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
6803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (signum == SIGTERM) {
6813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
6823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigterm++;
6833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGHUP) {
6843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      shutting_down = True;
6853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sighup++;
6863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGPIPE) {
6873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigpipe++;
6883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else if (signum == SIGALRM) {
6893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sigalrm++;
690c42f255524f0bf498e4c46644c60a4cbda3b7997Dmitriy Ivanov#if defined(__ANDROID__)
691992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      /* Android has no pthread_cancel. As it also does not have
6923c761f0f0344757ac243c65511392fb41d1c841aphilippe         an invoker implementation, there is no need for cleanup action.
693992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         So, we just do nothing. */
694992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      DEBUG(1, "sigalrm received, no action on android\n");
695992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#else
6963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* Note: we cannot directly invoke restore_and_detach : this must
6973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         be done by the thread that has attached.
6983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         We have in this thread pushed a cleanup handler that will
6993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cleanup what is needed. */
700992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      DEBUG(1, "pthread_cancel invoke_gdbserver_in_valgrind_thread\n");
7013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_cancel(invoke_gdbserver_in_valgrind_thread);
702992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif
7033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
7043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(0, "unexpected signal %d\n", signum);
7053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
7063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
7073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* install the signal handlers allowing e.g. vgdb to cleanup in
7093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   case of termination. */
7103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
7113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid install_handlers(void)
7123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
7133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   struct sigaction action, oldaction;
7143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_handler = received_signal;
7163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigemptyset (&action.sa_mask);
7173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   action.sa_flags = 0;
7183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGINT: when user types C-c in gdb, this sends
7203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a SIGINT to vgdb + causes a character to be sent to remote gdbserver.
7213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      The later is enough to wakeup the valgrind process. */
7223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGINT, &action, &oldaction) != 0)
7233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGINT\n");
7243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We might do something more intelligent than just
7253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      reporting this SIGINT E.g. behave similarly to the gdb: two
7263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      control-C without feedback from the debugged process would
7273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      mean to stop debugging it. */
7283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGUSR1: this is used to facilitate automatic testing.  When
7303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      vgdb receives this signal, it will simulate the user typing C-c. */
7313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGUSR1, &action, &oldaction) != 0)
7323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGUSR1\n");
7333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGTERM: can receive this signal (e.g. from gdb) to terminate vgdb
7363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when detaching or similar. A clean shutdown will be done as both
7373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the read and write side will detect an end of file. */
7383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGTERM, &action, &oldaction) != 0)
7393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGTERM\n");
7403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGPIPE: can receive this signal when gdb detaches or kill the
7423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process debugged: gdb will close its pipes to vgdb. vgdb
7433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      must resist to this signal to allow a clean shutdown. */
7443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGPIPE, &action, &oldaction) != 0)
7453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGPIPE\n");
7463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* SIGALRM: in case invoke thread is blocked, alarm is used
7483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      to cleanup.  */
7493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (sigaction (SIGALRM, &action, &oldaction) != 0)
7503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      XERROR (errno, "vgdb error sigaction SIGALRM\n");
751e6460fa595b0bfe3551b378b105140564aaca8d7philippe
752e6460fa595b0bfe3551b378b105140564aaca8d7philippe   /* unmask all signals, in case the process that launched vgdb
753e6460fa595b0bfe3551b378b105140564aaca8d7philippe      masked some. */
754e6460fa595b0bfe3551b378b105140564aaca8d7philippe   if (sigprocmask (SIG_SETMASK, &action.sa_mask, NULL) != 0)
755e6460fa595b0bfe3551b378b105140564aaca8d7philippe      XERROR (errno, "vgdb error sigprocmask");
7563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
7573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* close the FIFOs provided connections, terminate the invoker thread.  */
7593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
7603b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid close_connection(int to_pid, int from_pid)
7613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
7623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   DEBUG(1, "nr received signals: sigint %d sigterm %d sighup %d sigpipe %d\n",
7633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         sigint, sigterm, sighup, sigpipe);
7643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* Note that we do not forward sigterm to the valgrind process:
7653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      a sigterm signal is (probably) received from gdb if the user wants to
7663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      kill the debugged process. The kill instruction has been given to
7673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      the valgrind process, which should execute a clean exit. */
7683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* We first close the connection to pid. The pid will then
7703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      terminates its gdbserver work. We keep the from pid
7713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fifo opened till the invoker thread is finished.
7723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      This allows the gdbserver to finish sending its last reply. */
7733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(to_pid) != 0)
7743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close to_pid\n");
7753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* if there is a task that was busy trying to wake up valgrind
7773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      process, we wait for it to be terminated otherwise threads
7783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      in the valgrind process can stay stopped if vgdb main
7793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exits before the invoke thread had time to detach from
7803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      all valgrind threads. */
78130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER) {
7823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int join;
7833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
7843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* It is surprisingly complex to properly shutdown or exit the
7853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process in which gdbserver has been invoked through
7863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ptrace.  In the normal case (gdb detaches from the process,
7873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         or process is continued), the valgrind process will reach the
7883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         breakpoint place.  Using ptrace, vgdb will ensure the
7893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         previous activity of the process is resumed (e.g. restart a
7903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         blocking system call).  The special case is when gdb asks the
7913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process to exit (using either the "kill" command or
7923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         "monitor exit").  In such a case, the valgrind process will
7933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         call exit.  But a ptraced process will be blocked in exit,
7943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         waiting for the ptracing process to detach or die. vgdb
7953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cannot detach unconditionally as otherwise, in the normal
796b2572b52b37d56d302408395f7fed9f509423af1sewardj         case, the valgrind process would stop abnormally with SIGSTOP
7973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         (as vgdb would not be there to catch it). vgdb can also not
7983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         die unconditionally otherwise again, similar problem.  So, we
7993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         assume that most of the time, we arrive here in the normal
8003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         case, and so, the breakpoint has been encountered by the
8013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         valgrind process, so the invoker thread will exit and the
8023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         join will succeed.  For the "kill" case, we cause an alarm
8033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         signal to be sent after a few seconds. This means that in the
8043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         normal case, the gdbserver code in valgrind process must have
8053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         returned the control in less than the alarm nr of seconds,
806b2572b52b37d56d302408395f7fed9f509423af1sewardj         otherwise, valgrind will stop abnormally with SIGSTOP. */
8073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      (void) alarm (3);
8083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "joining with invoke_gdbserver_in_valgrind_thread\n");
8103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      join = pthread_join(invoke_gdbserver_in_valgrind_thread, NULL);
8113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (join != 0)
8123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         XERROR
8133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            (join,
8143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj             "vgdb error pthread_join invoke_gdbserver_in_valgrind_thread\n");
8153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
8163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (close(from_pid) != 0)
8173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ERROR(errno, "close from_pid\n");
8183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
8193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Relay data between gdb and Valgrind gdbserver, till EOF or an
8213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   error is encountered. */
8223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
8233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid gdb_relay (int pid)
8243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
8253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
8263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
8273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int shutdown_loop = 0;
8293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf (stderr, "relaying data between gdb and process %d\n", pid);
8303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fflush (stderr);
8313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0)
8333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
8343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
8353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
8363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
8373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo (to_gdb_from_pid, O_RDONLY|O_NONBLOCK,
8393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         "read mode from pid");
8403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sigusr1_fd = to_pid; /* allow simulating user typing control-c */
8423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   while (1) {
8443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ConnectionKind ck;
8453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int ret;
8463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct pollfd pollfds[NumConnectionKind];
8473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by gdb, watch POLLERR on both gdb fd */
8493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].fd = from_gdb;
8503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].events = POLLIN;
8513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_GDB].revents = 0;
8523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].fd = to_gdb;
8533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].events = 0;
8543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_GDB].revents = 0;
8553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* watch data written by pid, watch POLLERR on both pid fd */
8573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].fd = from_pid;
8583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].events = POLLIN;
8593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[FROM_PID].revents = 0;
8603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].fd = to_pid;
8613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].events = 0;
8623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pollfds[TO_PID].revents = 0;
8633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      ret = poll(pollfds,
8653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 NumConnectionKind,
8663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 (shutting_down ?
8673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  1 /* one second */
8683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  : -1 /* infinite */));
8693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(2, "poll ret %d errno %d\n", ret, errno);
8703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for unexpected error */
8723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (ret <= 0 && errno != EINTR) {
8733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         ERROR (errno, "unexpected poll ret %d\n", ret);
8743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down = True;
8753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         break;
8763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for data to read */
8793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
8803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLIN) {
8813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            switch (ck) {
8823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            case FROM_GDB:
8833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (!read_from_gdb_write_to_pid(to_pid))
8843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  shutting_down = True;
8853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               break;
8861d76a80d63502951cb9cbf6f696d663f093083faphilippe            case FROM_PID:
8871d76a80d63502951cb9cbf6f696d663f093083faphilippe               if (!read_from_pid_write_to_gdb(from_pid))
8881d76a80d63502951cb9cbf6f696d663f093083faphilippe                  shutting_down = True;
8891d76a80d63502951cb9cbf6f696d663f093083faphilippe               break;
8903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            default: XERROR(0, "unexpected POLLIN on %s\n",
8913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               ppConnectionKind(ck));
8923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
8933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
8943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
8953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
8963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* check for an fd being in error condition */
8973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (ck = 0; ck < NumConnectionKind; ck ++) {
8983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLERR) {
8993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLERR error condition\n",
9003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     ppConnectionKind(ck), pollfds[ck].fd);
9013c761f0f0344757ac243c65511392fb41d1c841aphilippe            invoker_valgrind_dying();
9023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
9033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
9043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLHUP) {
9053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLHUP error condition\n",
9063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
9073c761f0f0344757ac243c65511392fb41d1c841aphilippe            invoker_valgrind_dying();
9083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
9093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
9103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pollfds[ck].revents & POLLNVAL) {
9113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "connection %s fd %d POLLNVAL error condition\n",
9123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ppConnectionKind(ck), pollfds[ck].fd);
9133c761f0f0344757ac243c65511392fb41d1c841aphilippe            invoker_valgrind_dying();
9143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            shutting_down = True;
9153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
9163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (shutting_down) {
9193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* we let some time to the final packets to be transferred */
9203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutdown_loop++;
9213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (shutdown_loop > 3)
9223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
9233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
9253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
9263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
9273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9283b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int packet_len_for_command(char *cmd)
9293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
9303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* cmd will be send as a packet $qRcmd,xxxx....................xx#cc      */
9313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return                          7+     2*strlen(cmd)             +3  + 1;
9323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
9333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* hyper-minimal protocol implementation that
9353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sends the provided commands (using qRcmd packets)
9363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   and read and display their replies. */
9373b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
9383b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid standalone_send_commands(int pid,
9393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              int last_command,
9403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              char *commands[] )
9413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
9423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int from_pid = -1; /* fd to read from pid */
9433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int to_pid = -1; /* fd to write to pid */
9443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
9463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int hi;
947adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe   char hex[3];
9483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   unsigned char cksum;
949adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe   char *hexcommand;
950adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe   char buf[PBUFSIZ+1]; // +1 for trailing \0
9513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int buflen;
9523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int nc;
9533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
95530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0 || cmd_time_out != NEVER)
9563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
9573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     invoke_gdbserver_in_valgrind, (void *) &pid);
9583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
9603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   acquire_lock (shared_mem_fd, pid);
9613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* first send a C-c \003 to pid, so that it wakes up the process
9633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      After that, we can open the fifo from the pid in read mode
9643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      We then start to wait for packets (normally first a resume reply)
9653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      At that point, we send our command and expect replies */
9663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   buf[0] = '\003';
967def5aae79084c7b1128674105f9e657e2af0d5dcphilippe   i = 0;
968def5aae79084c7b1128674105f9e657e2af0d5dcphilippe   while (!write_buf(to_pid, buf, 1,
969def5aae79084c7b1128674105f9e657e2af0d5dcphilippe                     "write \\003 to wake up", /* notify */ True)) {
970def5aae79084c7b1128674105f9e657e2af0d5dcphilippe      /* If write fails, retries up to 10 times every 0.5 seconds
971def5aae79084c7b1128674105f9e657e2af0d5dcphilippe         This aims at solving the race condition described in
972def5aae79084c7b1128674105f9e657e2af0d5dcphilippe         remote-utils.c remote_finish function. */
973def5aae79084c7b1128674105f9e657e2af0d5dcphilippe      usleep(500*1000);
974def5aae79084c7b1128674105f9e657e2af0d5dcphilippe      i++;
975def5aae79084c7b1128674105f9e657e2af0d5dcphilippe      if (i >= 10)
976def5aae79084c7b1128674105f9e657e2af0d5dcphilippe         XERROR (errno, "failed to send wake up char after 10 trials\n");
977def5aae79084c7b1128674105f9e657e2af0d5dcphilippe   }
9783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from_pid = open_fifo(to_gdb_from_pid, O_RDONLY,
9793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        "read cmd result from pid");
9803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (nc = 0; nc <= last_command; nc++) {
9823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "sending command %s to pid %d\n", commands[nc], pid);
9833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fflush (stderr);
9843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
9853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* prepare hexcommand $qRcmd,xxxx....................xx#cc      */
9863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand = vmalloc (packet_len_for_command(commands[nc]));
9873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      hexcommand[0] = 0;
9883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (hexcommand, "$qRcmd,");
9893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < strlen(commands[nc]); i++) {
990adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe         sprintf(hex, "%02x", (unsigned char) commands[nc][i]);
991adfb8a704c763eb6f8c3e8e79b17322d6c46b040philippe         // Need to use unsigned char, to avoid sign extension.
9923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (hexcommand, hex);
9933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
9943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* checksum (but without the $) */
9953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      cksum = 0;
9963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (hi = 1; hi < strlen(hexcommand); hi++)
9973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         cksum+=hexcommand[hi];
9983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, "#");
9993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      sprintf(hex, "%02x", cksum);
10003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat(hexcommand, hex);
10013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      write_buf(to_pid, hexcommand, strlen(hexcommand),
10023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                "writing hex command to pid", /* notify */ True);
10033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* we exit of the below loop explicitely when the command has
10053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         been handled or because a signal handler will set
10063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         shutting_down. */
10073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      while (!shutting_down) {
10083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         buflen = getpkt(buf, from_pid, to_pid);
10093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buflen < 0) {
10103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            ERROR (0, "error reading packet\n");
10113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (buflen == -2)
10123c761f0f0344757ac243c65511392fb41d1c841aphilippe               invoker_valgrind_dying();
10133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
10143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strlen(buf) == 0) {
10163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "empty packet rcvd (packet qRcmd not recognised?)\n");
10173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
10183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (strcmp(buf, "OK") == 0) {
10203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "OK packet rcvd\n");
10213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
10223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'E') {
10243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0,
10253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  "E NN error packet rcvd: %s (unknown monitor command?)\n",
10263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  buf);
10273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
10283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'W') {
10303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "W stopped packet rcvd: %s\n", buf);
10313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
10323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] == 'T') {
10343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(1, "T resume reply packet received: %s\n", buf);
10353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
10363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         /* must be here an O packet with hex encoded string reply
10393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            => decode and print it */
10403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (buf[0] != 'O') {
10413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            DEBUG(0, "expecting O packet, received: %s\n", buf);
10423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            continue;
10433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         {
10453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char buf_print[buflen/2 + 1];
10463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            for (i = 1; i < buflen; i = i + 2)
10473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               buf_print[i/2] = (fromhex(*(buf+i)) << 4)
10483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     + fromhex(*(buf+i+1));
10493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            buf_print[buflen/2] = 0;
10503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            printf("%s", buf_print);
10513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fflush(stdout);
10523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
10533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
10543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (hexcommand);
10553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
10563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   shutting_down = True;
10573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   close_connection(to_pid, from_pid);
10593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
10603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
10613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* report to user the existence of a vgdb-able valgrind process
1062345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe   with given pid.
10635cbcd62afb84cffe8d1130b0b896bd36fab20a05philippe   Note: this function does not use XERROR if an error is encountered
1064345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe   while producing the command line for pid, as this is not critical
1065345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe   and at least on MacOS, reading cmdline is not available. */
10663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
106730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid report_pid (int pid, Bool on_stdout)
10683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
1069b7742ab1b3859ebf0d102001745e697725555017florian   char cmdline_file[50];   // large enough
1070b7742ab1b3859ebf0d102001745e697725555017florian   int fd, i;
1071b7742ab1b3859ebf0d102001745e697725555017florian   FILE *out = on_stdout ? stdout : stderr;
10723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1073345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe   fprintf(out, "use --pid=%d for ", pid);
1074345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe
10753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   sprintf(cmdline_file, "/proc/%d/cmdline", pid);
10763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fd = open (cmdline_file, O_RDONLY);
10773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (fd == -1) {
10783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "error opening cmdline file %s %s\n",
10793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            cmdline_file, strerror(errno));
1080345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe      fprintf(out, "(could not open process command line)\n");
10813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
1082b7742ab1b3859ebf0d102001745e697725555017florian      char cmdline[100];
1083b7742ab1b3859ebf0d102001745e697725555017florian      ssize_t sz;
1084b7742ab1b3859ebf0d102001745e697725555017florian      while ((sz = read(fd, cmdline, sizeof cmdline - 1)) != 0) {
1085345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe         for (i = 0; i < sz; i++)
1086345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe            if (cmdline[i] == 0)
1087345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe               cmdline[i] = ' ';
1088345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe         cmdline[sz] = 0;
1089345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe         fprintf(out, "%s", cmdline);
1090345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe      }
1091345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe      if (sz == -1) {
1092345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe         DEBUG(1, "error reading cmdline file %s %s\n",
1093345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe               cmdline_file, strerror(errno));
1094345affe06343cf6ed038f9d82fceb9b1ea3354b6philippe         fprintf(out, "(error reading process command line)");
109536c01ef411ad2c71d396a024fdeb506aebd1cd7cphilippe      }
1096b7742ab1b3859ebf0d102001745e697725555017florian      fprintf(out, "\n");
1097d8c12f178d9d03b934ce10d6fcb45c27503889dcsewardj      close (fd);
10983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
1099b7742ab1b3859ebf0d102001745e697725555017florian   fflush(out);
11003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
11013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
11033b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid usage(void)
11043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
11053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   fprintf(stderr,
11063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"Usage: vgdb [OPTION]... [[-c] COMMAND]...\n"
11073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"vgdb (valgrind gdb) has two usages\n"
11083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  1. standalone to send monitor commands to a Valgrind gdbserver.\n"
11093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     The OPTION(s) must be followed by the command to send\n"
11103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     To send more than one command, separate the commands with -c\n"
11113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  2. relay application between gdb and a Valgrind gdbserver.\n"
11123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"     Only OPTION(s) can be given.\n"
11133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n"
11143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n"
111530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--wait=<number>] [--max-invoke-ms=<number>]\n"
1116992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj"             [--port=<portnr>\n"
111730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             [--cmd-time-out=<number>] [-l] [-D] [-d]\n"
111830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"             \n"
11193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --pid arg must be given if multiple Valgrind gdbservers are found.\n"
11203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"  --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n"
11215507d226fd83f2dcf9c5552787e8114594c9972fphilippe"      if you want to change the prefix (default %s) for the FIFOs communication\n"
11223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      between the Valgrind gdbserver and vgdb.\n"
112330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --wait (default 0) tells vgdb to check during the specified number\n"
11243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"      of seconds if a Valgrind gdbserver can be found.\n"
112530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n"
112630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"      will force the invocation of the Valgrind gdbserver (if the Valgrind\n"
112730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"         process is blocked in a system call).\n"
1128992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj"  --port instructs vgdb to listen for gdb on the specified port nr.\n"
112930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n"
113030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"     gdbserver has not processed a command after number seconds\n"
1131d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -l  arg tells to show the list of running Valgrind gdbserver and then exit.\n"
113230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -D  arg tells to show shared mem status and then exit.\n"
113330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj"  -d  arg tells to show debug info. Multiple -d args for more debug info\n"
1134d142f99836471d4245250247cc9ac7bc5a1391fasewardj"\n"
1135d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  -h --help shows this message\n"
1136d142f99836471d4245250247cc9ac7bc5a1391fasewardj"  To get help from the Valgrind gdbserver, use vgdb help\n"
11375507d226fd83f2dcf9c5552787e8114594c9972fphilippe"\n", vgdb_prefix_default()
11383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           );
11393c761f0f0344757ac243c65511392fb41d1c841aphilippe   invoker_restrictions_msg();
11403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
11413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
114230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated.
1143d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 and then exits.
1144d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1145d142f99836471d4245250247cc9ac7bc5a1391fasewardj   else if arg_pid == -1, waits maximum check_trials seconds to discover
11463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   a valgrind pid appearing.
1147d142f99836471d4245250247cc9ac7bc5a1391fasewardj
11483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise verify arg_pid is valid and corresponds to a Valgrind process
11493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   with gdbserver activated.
11503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Returns the pid to work with
11523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   or exits in case of error (e.g. no pid found corresponding to arg_pid */
11533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11543b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
1155d142f99836471d4245250247cc9ac7bc5a1391fasewardjint search_arg_pid(int arg_pid, int check_trials, Bool show_list)
11563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
11573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
11583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid = -1;
11593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_pid == 0 || arg_pid < -1) {
11613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "vgdb error: invalid pid %d given\n", arg_pid);
11623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
11633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
11643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* search for a matching named fifo.
11653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we have been given a pid, we will check that the matching FIFO is
11663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         there (or wait the nr of check_trials for this to appear).
11673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If no pid has been given, then if we find only one FIFO,
11683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         we will use this to build the pid to use.
11693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         If we find multiple processes with valid FIFO, we report them and will
11703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit with an error. */
11713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DIR *vgdb_dir;
11723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_dir_name = vmalloc (strlen (vgdb_prefix) + 3);
11733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      struct dirent *f;
11743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int is;
11753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      int nr_valid_pid = 0;
11763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      const char *suffix = "-from-vgdb-to-"; /* followed by pid */
11773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      char *vgdb_format = vmalloc (strlen(vgdb_prefix) + strlen(suffix) + 1);
11783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcpy (vgdb_format, vgdb_prefix);
11803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      strcat (vgdb_format, suffix);
11813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11825507d226fd83f2dcf9c5552787e8114594c9972fphilippe      if (strchr(vgdb_prefix, '/') != NULL) {
11835507d226fd83f2dcf9c5552787e8114594c9972fphilippe         strcpy (vgdb_dir_name, vgdb_prefix);
11845507d226fd83f2dcf9c5552787e8114594c9972fphilippe         for (is = strlen(vgdb_prefix) - 1; is >= 0; is--)
11855507d226fd83f2dcf9c5552787e8114594c9972fphilippe            if (vgdb_dir_name[is] == '/') {
11865507d226fd83f2dcf9c5552787e8114594c9972fphilippe               vgdb_dir_name[is+1] = '\0';
11875507d226fd83f2dcf9c5552787e8114594c9972fphilippe               break;
11885507d226fd83f2dcf9c5552787e8114594c9972fphilippe            }
11895507d226fd83f2dcf9c5552787e8114594c9972fphilippe      } else {
11905507d226fd83f2dcf9c5552787e8114594c9972fphilippe         strcpy (vgdb_dir_name, "");
11915507d226fd83f2dcf9c5552787e8114594c9972fphilippe      }
11923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      DEBUG(1, "searching pid in directory %s format %s\n",
11943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            vgdb_dir_name, vgdb_format);
11953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
11963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* try to find FIFOs with valid pid.
11973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         On exit of the loop, pid is set to:
1198d142f99836471d4245250247cc9ac7bc5a1391fasewardj         the last pid found if show_list (or -1 if no process was listed)
11993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -1 if no FIFOs matching a running process is found
12003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         -2 if multiple FIFOs of running processes are found
12013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         otherwise it is set to the (only) pid found that can be debugged
12023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      */
12033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      for (i = 0; i < check_trials; i++) {
12043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         DEBUG(1, "check_trial %d \n", i);
12053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (i > 0)
12063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           /* wait one second before checking again */
12073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj           sleep(1);
12083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12095507d226fd83f2dcf9c5552787e8114594c9972fphilippe         vgdb_dir = opendir (strlen (vgdb_dir_name) ? vgdb_dir_name : "./");
12103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (vgdb_dir == NULL)
12113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno,
12123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    "vgdb error: opening directory %s searching vgdb fifo\n",
12133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
12143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         errno = 0; /* avoid complain if vgdb_dir is empty */
12163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         while ((f = readdir (vgdb_dir))) {
12173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            struct stat st;
1218bb4827b2ba7d03fc3d33fa657162d53b68cbdfe9philippe            char pathname[strlen(vgdb_dir_name) + strlen(f->d_name) + 1];
12193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            char *wrongpid;
12203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            int newpid;
12213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcpy (pathname, vgdb_dir_name);
12233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (pathname, f->d_name);
1224bb4827b2ba7d03fc3d33fa657162d53b68cbdfe9philippe            DEBUG(3, "checking pathname is FIFO %s\n", pathname);
12253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            if (stat (pathname, &st) != 0) {
12263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (debuglevel >= 3)
12273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  ERROR (errno, "vgdb error: stat %s searching vgdb fifo\n",
12283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                         pathname);
12293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            } else if (S_ISFIFO (st.st_mode)) {
1230bb4827b2ba7d03fc3d33fa657162d53b68cbdfe9philippe               DEBUG(3, "trying FIFO %s\n", pathname);
12313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               if (strncmp (pathname, vgdb_format,
12323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                            strlen (vgdb_format)) == 0) {
12333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  newpid = strtol(pathname + strlen (vgdb_format),
12343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                  &wrongpid, 10);
1235ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian                  if (*wrongpid == '-' && newpid > 0
12363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                      && kill (newpid, 0) == 0) {
12373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     nr_valid_pid++;
1238d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     if (show_list) {
123930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ True);
1240d142f99836471d4245250247cc9ac7bc5a1391fasewardj                        pid = newpid;
1241d142f99836471d4245250247cc9ac7bc5a1391fasewardj                     } else if (arg_pid != -1) {
12423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (arg_pid == newpid) {
12433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           pid = newpid;
12443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
12453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else if (nr_valid_pid > 1) {
12463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        if (nr_valid_pid == 2) {
12473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                           fprintf
12483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                              (stderr,
12493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               "no --pid= arg given"
12503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                               " and multiple valgrind pids found:\n");
125130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                           report_pid (pid, /*on_stdout*/ False);
12523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        }
12533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = -2;
125430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj                        report_pid (newpid, /*on_stdout*/ False);
12553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     } else {
12563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                        pid = newpid;
12573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                     }
12583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  }
12593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj               }
12603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            }
12613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            errno = 0; /* avoid complain if at the end of vgdb_dir */
12623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
12633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (f == NULL && errno != 0)
12643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            XERROR (errno, "vgdb error: reading directory %s for vgdb fifo\n",
12653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                    vgdb_dir_name);
12663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         closedir (vgdb_dir);
12683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (pid != -1)
12693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            break;
12703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
12713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_dir_name);
12733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (vgdb_format);
12743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
1275d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1276d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list) {
1277d142f99836471d4245250247cc9ac7bc5a1391fasewardj      exit (1);
1278d142f99836471d4245250247cc9ac7bc5a1391fasewardj   } else if (pid == -1) {
12793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (arg_pid == -1)
12803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found and no pid given\n");
12813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      else
12823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "vgdb error: no FIFO found matching pid %d\n",
12833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                  arg_pid);
12843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
12853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else if (pid == -2) {
12873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      /* no arg_pid given, multiple FIFOs found */
12883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (1);
12893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else {
12913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return pid;
12923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
12933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
12943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
12953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* return true if the numeric value of an option of the
12963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   form --xxxxxxxxx=<number> could properly be extracted
12973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   from arg. If True is returned, *value contains the
12983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   extracted value.*/
12993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13003b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool numeric_val(char* arg, int *value)
13013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   const char *eq_pos = strchr(arg, '=');
13033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *wrong;
130430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long long int long_value;
13053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (eq_pos == NULL)
13073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
13083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
130930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   long_value = strtoll(eq_pos+1, &wrong, 10);
131030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (long_value < 0 || long_value > INT_MAX)
131130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      return False;
13123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (*wrong)
13133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return False;
13143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
131530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   *value = (int) long_value;
13163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return True;
13173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* true if arg matches the provided option */
13203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13216bd9dc18c043927c1196caba20a327238a179c42florianBool is_opt(char* arg, const char *option)
13223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int option_len = strlen(option);
13243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (option[option_len-1] == '=')
13253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strncmp(option, arg, option_len));
13263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   else
13273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      return (0 == strcmp(option, arg));
13283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
13293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Parse command lines options. If error(s), exits.
13313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Otherwise returns the options in *p_... args.
13323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   commands must be big enough for the commands extracted from argv.
13333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   On return, *p_last_command gives the position in commands where
13343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   the last command has been allocated (using vmalloc). */
13353b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic
13363b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid parse_options(int argc, char** argv,
13373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   Bool *p_show_shared_mem,
1338d142f99836471d4245250247cc9ac7bc5a1391fasewardj                   Bool *p_show_list,
13393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_arg_pid,
13403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_check_trials,
1341992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj                   int *p_port,
13423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   int *p_last_command,
13433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                   char *commands[])
13443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
13453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem = False;
1346d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list = False;
13473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid = -1;
13483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials = 1;
13493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command = -1;
1350992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int int_port = 0;
13513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
13533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_errors = 0;
13543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
13553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 1; i < argc; i++) {
13563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      if (is_opt(argv[i], "--help") || is_opt(argv[i], "-h")) {
13573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         usage();
13583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         exit(0);
13593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-d")) {
13603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         debuglevel++;
13613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-D")) {
13623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         show_shared_mem = True;
1363d142f99836471d4245250247cc9ac7bc5a1391fasewardj      } else if (is_opt(argv[i], "-l")) {
1364d142f99836471d4245250247cc9ac7bc5a1391fasewardj         show_list = True;
13653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--pid=")) {
13663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int newpid;
13673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &newpid)) {
136830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --pid argument %s\n", argv[i]);
13693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
13703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else if (arg_pid != -1) {
137130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "multiple --pid arguments given\n");
13723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
13733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         } else {
13743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_pid = newpid;
13753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
13763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--wait=")) {
13773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &check_trials)) {
137830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --wait argument %s\n", argv[i]);
13793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
13803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
13813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--max-invoke-ms=")) {
13823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (!numeric_val(argv[i], &max_invoke_ms)) {
138330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]);
138430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            arg_errors++;
138530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         }
138630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      } else if (is_opt(argv[i], "--cmd-time-out=")) {
138730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj         if (!numeric_val(argv[i], &cmd_time_out)) {
138830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj            fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]);
13893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
13903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
1391992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      } else if (is_opt(argv[i], "--port=")) {
1392992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         if (!numeric_val(argv[i], &int_port)) {
1393992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj            fprintf (stderr, "invalid --port argument %s\n", argv[i]);
1394992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj            arg_errors++;
1395992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj         }
13963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "--vgdb-prefix=")) {
13973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         vgdb_prefix = argv[i] + 14;
13983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (is_opt(argv[i], "-c")) {
13993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         last_command++;
14003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vmalloc (1);
14013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command][0] = '\0';
14023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else if (0 == strncmp(argv[i], "-", 1)) {
14033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         fprintf (stderr, "unknown or invalid argument %s\n", argv[i]);
14043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         arg_errors++;
14053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      } else {
14063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         int len;
14073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (last_command == -1) {
14083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            /* only one command, no -c command indicator */
14093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            last_command++;
14103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command] = vmalloc (1);
14113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            commands[last_command][0] = '\0';
14123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
14133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         len = strlen(commands[last_command]);
14143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         commands[last_command] = vrealloc (commands[last_command],
14153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                                            len + 1 + strlen(argv[i]) + 1);
14163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (len > 0)
14173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            strcat (commands[last_command], " ");
14183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         strcat (commands[last_command], argv[i]);
14193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         if (packet_len_for_command(commands[last_command]) > PBUFSIZ) {
14203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            fprintf (stderr, "command %s too long\n", commands[last_command]);
14213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj            arg_errors++;
14223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj         }
14233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      }
14253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
1426d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1427b985e2de52983cafd2d17cc6c9e60064847777fdflorian   if (vgdb_prefix == NULL)
1428b985e2de52983cafd2d17cc6c9e60064847777fdflorian      vgdb_prefix = vgdb_prefix_default();
1429b985e2de52983cafd2d17cc6c9e60064847777fdflorian
1430d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (isatty(0)
1431d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_shared_mem
1432d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && !show_list
1433992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj       && int_port == 0
1434d142f99836471d4245250247cc9ac7bc5a1391fasewardj       && last_command == -1) {
1435d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
1436d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
1437d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Using vgdb standalone implies to give -D or -l or a COMMAND\n");
1438d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
1439d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1440d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_shared_mem && show_list) {
1441d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
1442d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
1443d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both -D and -l options\n");
1444d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
1445d142f99836471d4245250247cc9ac7bc5a1391fasewardj
144630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   if (max_invoke_ms > 0
144730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && cmd_time_out != NEVER
144830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj       && (cmd_time_out * 1000) <= max_invoke_ms) {
144930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      arg_errors++;
145030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj      fprintf (stderr,
145130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj               "--max-invoke-ms must be < --cmd-time-out * 1000\n");
145230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj   }
145330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj
1454d142f99836471d4245250247cc9ac7bc5a1391fasewardj   if (show_list && arg_pid != -1) {
1455d142f99836471d4245250247cc9ac7bc5a1391fasewardj      arg_errors++;
1456d142f99836471d4245250247cc9ac7bc5a1391fasewardj      fprintf (stderr,
1457d142f99836471d4245250247cc9ac7bc5a1391fasewardj               "Can't use both --pid and -l options\n");
1458d142f99836471d4245250247cc9ac7bc5a1391fasewardj   }
1459d142f99836471d4245250247cc9ac7bc5a1391fasewardj
1460992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (int_port > 0 && last_command != -1) {
1461992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      arg_errors++;
1462992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      fprintf (stderr,
1463992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj               "Can't use --port to send commands\n");
1464992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   }
1465992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
14663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (arg_errors > 0) {
14673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf (stderr, "args error. Try `vgdb --help` for more information\n");
14683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit(1);
14693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
14703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_show_shared_mem = show_shared_mem;
1472d142f99836471d4245250247cc9ac7bc5a1391fasewardj   *p_show_list = show_list;
14733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_arg_pid = arg_pid;
14743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_check_trials = check_trials;
1475992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   *p_port = int_port;
14763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   *p_last_command = last_command;
14773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
14783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14793b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint main(int argc, char** argv)
14803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{
14813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int i;
14823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int pid;
14833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   Bool show_shared_mem;
1485d142f99836471d4245250247cc9ac7bc5a1391fasewardj   Bool show_list;
14863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int arg_pid;
14873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int check_trials;
1488992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   int in_port;
14893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   int last_command;
14903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   char *commands[argc]; // we will never have more commands than args.
14913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
14923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   parse_options(argc, argv,
14933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &show_shared_mem,
1494d142f99836471d4245250247cc9ac7bc5a1391fasewardj                 &show_list,
14953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &arg_pid,
14963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &check_trials,
1497992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj                 &in_port,
14983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 &last_command,
14993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj                 commands);
15003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   /* when we are working as a relay for gdb, handle some signals by
15023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      only reporting them (according to debug level). Also handle these
15033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      when ptrace will be used: vgdb must clean up the ptrace effect before
15043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      dying. */
15053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (max_invoke_ms > 0 || last_command == -1)
15063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      install_handlers();
15073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1508d142f99836471d4245250247cc9ac7bc5a1391fasewardj   pid = search_arg_pid (arg_pid, check_trials, show_list);
15093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   prepare_fifos_and_shared_mem(pid);
15113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
1512992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj   if (in_port > 0)
1513992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj      wait_for_gdb_connect(in_port);
1514992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj
15153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (show_shared_mem) {
15163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      fprintf(stderr,
15173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb %d "
15183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "written_by_vgdb %d "
15193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "seen_by_valgrind %d\n"
15203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              "vgdb pid %d\n",
15213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid,
15223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_written_by_vgdb,
15233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_seen_by_valgrind,
15243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj              VS_vgdb_pid);
15253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      exit (0);
15263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
15273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   if (last_command >= 0) {
15293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      standalone_send_commands(pid, last_command, commands);
15303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   } else {
15313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      gdb_relay(pid);
15323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   }
15333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (from_gdb_to_pid);
15363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (to_gdb_from_pid);
15373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   free (shared_mem);
15383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj
15393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   for (i = 0; i <= last_command; i++)
15403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj      free (commands[i]);
15413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj   return 0;
15423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj}
1543