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