vgdb.c revision ae52a9398788dfa1b4d51b03013e8665268ad6df
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 91568e17cf07007c677274ce877973c7ed9357df2sewardj Copyright (C) 2011-2011 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 29cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_basics.h" 30cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_vki.h" 31cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_libcsetjmp.h" 32cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_threadstate.h" 33cbe385015145f16e3e88f919d8979df628a535easewardj#include "pub_core_gdbserver.h" 34b985e2de52983cafd2d17cc6c9e60064847777fdflorian#include "config.h" 35cbe385015145f16e3e88f919d8979df628a535easewardj 3630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#include <limits.h> 3756501b67e44eb4d012449e16aafe49d885b557f1sewardj#include <unistd.h> 383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <string.h> 393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <poll.h> 403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <pthread.h> 413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdlib.h> 423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <stdio.h> 433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <fcntl.h> 443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <dirent.h> 453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/stat.h> 463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/time.h> 473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <errno.h> 48e7f8f3f669763ac7b4f83428771f563ba55d74e2sewardj#include <signal.h> 49992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/types.h> 50992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/socket.h> 51992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <netinet/in.h> 52992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <arpa/inet.h> 533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/mman.h> 543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/ptrace.h> 553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#include <sys/wait.h> 56cbe385015145f16e3e88f919d8979df628a535easewardj#include <assert.h> 573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* vgdb has two usages: 583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1. relay application between gdb and the gdbserver embedded in valgrind. 593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2. standalone to send monitor commands to a running valgrind-ified process 603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj It is made of a main program which reads arguments. If no 623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arguments are given or only --pid and --vgdb-prefix, then usage 1 is 633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assumed. 643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj As relay application, vgdb reads bytes from gdb on stdin and 663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj writes these bytes to valgrind. Bytes read from valgrind are 673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj written to gdb on stdout. Read/Write from/to valgrind is done 683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj using FIFOs. There is one thread reading from stdin, writing to 693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind on a FIFO. There is one thread reading from valgrind on a 703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj FIFO, writing to gdb on stdout 713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj As a standalone utility, vgdb builds command packets to write to valgrind, 733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sends it and reads the reply. The same two threads are used to write/read. 743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Once all the commands are sent and their replies received, vgdb will exit. 753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/ 773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* define PTRACEINVOKER to compile the ptrace related code 793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj which ensures a valgrind process blocked in a system call 803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj can be "waken up". PTRACEINVOKER implies some architecture 813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj specific code and/or some OS specific code. */ 823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_arm) || defined(VGA_x86) || defined(VGA_amd64) \ 833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj || defined(VGA_ppc32) || defined(VGA_ppc64) || defined(VGA_s390x) 843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PTRACEINVOKER 853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjI_die_here : (PTRACEINVOKER) architecture missing in vgdb.c 873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Some darwin specific stuff is needed as ptrace is not 903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fully supported on MacOS. Till we find someone courageous 913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj having access to Darwin, there is no PTRACEINVOKER. */ 923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGO_darwin) 933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef PTRACEINVOKER 943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 96992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGPV_arm_linux_android) 97992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#undef PTRACEINVOKER 98992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif 99992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 100992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(PTRACEINVOKER) 101992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#include <sys/user.h> 102992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGO_linux) 103992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj# include <sys/prctl.h> 104992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj# include <linux/ptrace.h> 105992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif 106992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif 107992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 108992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 10930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// Outputs information for the user about ptrace_scope protection 11030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj// or ptrace not working. 11130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic void ptrace_restrictions_msg(void); 11230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj 1133b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int debuglevel; 1143b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct timeval dbgtv; 1153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if level <= debuglevel, print timestamp, then print provided by debug info */ 1163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define DEBUG(level, ...) (level <= debuglevel ? \ 1173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj gettimeofday(&dbgtv, NULL), \ 1183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, "%ld.%6.6ld ", \ 1193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (long int)dbgtv.tv_sec, \ 1203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (long int)dbgtv.tv_usec), \ 1213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, __VA_ARGS__),fflush(stderr) \ 1223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj : 0) 1233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as DEBUG but does not print time stamp info */ 1253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PDEBUG(level, ...) (level <= debuglevel ? \ 1263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, __VA_ARGS__),fflush(stderr) \ 1273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj : 0) 1283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* if errno != 0, 1303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj report the errno and fprintf the ... varargs on stderr. */ 1313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define ERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \ 1323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, __VA_ARGS__), \ 1333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fflush(stderr)) 1343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* same as ERROR, but also exits with status 1 */ 1353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define XERROR(errno, ...) ((errno == 0 ? 0 : perror("syscall failed")), \ 1363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, __VA_ARGS__), \ 1373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fflush(stderr), \ 1383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit(1)) 1393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 140b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic char *vgdb_prefix = NULL; 1413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Will be set to True when any condition indicating we have to shutdown 1433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj is encountered. */ 1443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool shutting_down = False; 1453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared32 *shared32; 1473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbShared64 *shared64; 1483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_written_by_vgdb (shared32 != NULL ? \ 1493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared32->written_by_vgdb \ 1503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj : shared64->written_by_vgdb) 1513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_seen_by_valgrind (shared32 != NULL ? \ 1523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared32->seen_by_valgrind \ 1533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj : shared64->seen_by_valgrind) 1543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define VS_vgdb_pid (shared32 != NULL ? shared32->vgdb_pid : shared64->vgdb_pid) 1563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls malloc (size). Exits if memory can't be allocated. */ 1583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 1593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vmalloc(size_t size) 1603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 1613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj void * mem = malloc(size); 1623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (mem == NULL) 1633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "can't allocate memory\n"); 1643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return mem; 1653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 1663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Calls realloc (size). Exits if memory can't be allocated. */ 1683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 1693b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *vrealloc(void *ptr,size_t size) 1703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 1713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj void * mem = realloc(ptr, size); 1723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (mem == NULL) 1733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "can't reallocate memory\n"); 1743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return mem; 1753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 1763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 177b985e2de52983cafd2d17cc6c9e60064847777fdflorian/* Return the name of a directory for temporary files. */ 178b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic 179b985e2de52983cafd2d17cc6c9e60064847777fdflorianconst char *vgdb_tmpdir(void) 180b985e2de52983cafd2d17cc6c9e60064847777fdflorian{ 181b985e2de52983cafd2d17cc6c9e60064847777fdflorian const char *tmpdir; 182b985e2de52983cafd2d17cc6c9e60064847777fdflorian 183b985e2de52983cafd2d17cc6c9e60064847777fdflorian tmpdir = getenv("TMPDIR"); 184ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe if (tmpdir == NULL || *tmpdir == '\0') 185ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe tmpdir = VG_TMPDIR; 186ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe if (tmpdir == NULL || *tmpdir == '\0') 187ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe tmpdir = "/tmp"; /* fallback */ 188b985e2de52983cafd2d17cc6c9e60064847777fdflorian 189b985e2de52983cafd2d17cc6c9e60064847777fdflorian return tmpdir; 190b985e2de52983cafd2d17cc6c9e60064847777fdflorian} 191b985e2de52983cafd2d17cc6c9e60064847777fdflorian 192ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe/* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb 193b985e2de52983cafd2d17cc6c9e60064847777fdflorian to communicate with valgrind */ 194b985e2de52983cafd2d17cc6c9e60064847777fdflorianstatic 195b985e2de52983cafd2d17cc6c9e60064847777fdflorianchar *vgdb_prefix_default(void) 196b985e2de52983cafd2d17cc6c9e60064847777fdflorian{ 197ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe static HChar *prefix; 198ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe 199ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe if (prefix == NULL) { 200ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe const char *tmpdir = vgdb_tmpdir(); 201ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe prefix = vmalloc(strlen(tmpdir) + strlen("/vgdb-pipe") + 1); 202ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe strcpy(prefix, tmpdir); 203ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe strcat(prefix, "/vgdb-pipe"); 204ae52a9398788dfa1b4d51b03013e8665268ad6dfphilippe } 205b985e2de52983cafd2d17cc6c9e60064847777fdflorian return prefix; 206b985e2de52983cafd2d17cc6c9e60064847777fdflorian} 207b985e2de52983cafd2d17cc6c9e60064847777fdflorian 2083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* add nrw to the written_by_vgdb field of shared32 or shared64 */ 2093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 2103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid add_written(int nrw) 2113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 2123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared32 != NULL) 2133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared32->written_by_vgdb += nrw; 2143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (shared64 != NULL) 2153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared64->written_by_vgdb += nrw; 2163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 2173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); 2183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 2193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2203b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int shared_mem_fd = -1; 2213b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 2223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid map_vgdbshared (char* shared_mem) 2233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 2243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct stat fdstat; 2253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj void **s; 2263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared_mem_fd = open(shared_mem, O_RDWR); 2273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* shared_mem_fd will not be closed till vgdb exits. */ 2283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared_mem_fd == -1) 2303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "error opening %s shared memory file\n", shared_mem); 2313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fstat(shared_mem_fd, &fdstat) != 0) 2333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "fstat"); 2343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fdstat.st_size == sizeof(VgdbShared64)) 2363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj s = (void*) &shared64; 2373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (fdstat.st_size == sizeof(VgdbShared32)) 2383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj s = (void*) &shared32; 2393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 2403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8 2413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (0, 2423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "error size shared memory file %s.\n" 2433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "expecting size %d (64bits) or %d (32bits) got %ld.\n", 2443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared_mem, 2453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (int) sizeof(VgdbShared64), (int) sizeof(VgdbShared32), 2463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (long int)fdstat.st_size); 2473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4 2483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (0, 2493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "error size shared memory file %s.\n" 2503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "expecting size %d (32bits) got %ld.\n", 2513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared_mem, 2523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (int) sizeof(VgdbShared32), 2533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fdstat.st_size); 2543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 2553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize" 2563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 2573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 4 2593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared64 != NULL) 2603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (0, "cannot use 32 bits vgdb with a 64bits valgrind process\n"); 2613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* But we can use a 64 bits vgdb with a 32 bits valgrind */ 2623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 2633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *s = (void*) mmap (NULL, fdstat.st_size, 2653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj PROT_READ|PROT_WRITE, MAP_SHARED, 2663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared_mem_fd, 0); 2673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (*s == (void *) -1) 2693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "error mmap shared memory file %s\n", shared_mem); 2703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 2723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if VEX_HOST_WORDSIZE == 8 2743b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 CORE_ADDR; 2753b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr64 PTRACE_XFER_TYPE; 2763b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE; 2773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif VEX_HOST_WORDSIZE == 4 2783b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 CORE_ADDR; 2793b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef Addr32 PTRACE_XFER_TYPE; 2803b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef void* PTRACE_ARG3_TYPE; 2813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 2823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# error "unexpected wordsize" 2833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 2843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2853b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool pid_of_save_regs_continued = False; 2863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// True if we have continued pid_of_save_regs after PTRACE_ATTACH 2873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2883b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic Bool dying = False; 2893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// Set to True when loss of connection indicating that the Valgrind 2903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// process is dying. 2913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* To be called when connection with valgrind is lost. In case we 2933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjhave lost the connection, it means that Valgrind has closed the 2943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjconnection and is busy exiting. We can't and don't have to stop it in 2953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjthis case. */ 2963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 2973b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid valgrind_dying(void) 2983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 2993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs_continued = False; 3003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj dying = True; 3013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 3023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER 3053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* ptrace_(read|write)_memory are modified extracts of linux-low.c 3063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from gdb 6.6. Copyrighted FSF */ 3073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes from inferior's memory starting at MEMADDR 3083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to debugger memory starting at MYADDR. */ 3093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3103b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 3113b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_read_memory (pid_t inferior_pid, CORE_ADDR memaddr, 3123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj unsigned char *myaddr, int len) 3133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 3143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register int i; 3153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Round starting address down to longword boundary. */ 3163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 3173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Round ending address up; get number of longwords that makes. */ 3183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register int count 3193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 3203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj / sizeof (PTRACE_XFER_TYPE); 3213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Allocate buffer of that many longwords. */ 3223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register PTRACE_XFER_TYPE *buffer 3233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 3243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Read all the longwords */ 3263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 3273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj errno = 0; 3283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 3293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (PTRACE_ARG3_TYPE) addr, 0); 3303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (errno) 3313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return errno; 3323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 3333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Copy appropriate bytes out of the buffer. */ 3353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj memcpy (myaddr, 3363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); 3373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return 0; 3393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 3403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Copy LEN bytes of data from debugger memory at MYADDR 3423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to inferior's memory at MEMADDR. 3433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj On failure (cannot write the inferior) 3443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj returns the value of errno. */ 3453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 3473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint ptrace_write_memory (pid_t inferior_pid, CORE_ADDR memaddr, 3483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const unsigned char *myaddr, int len) 3493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 3503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register int i; 3513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Round starting address down to longword boundary. */ 3523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); 3533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Round ending address up; get number of longwords that makes. */ 3543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register int count 3553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) 3563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj / sizeof (PTRACE_XFER_TYPE); 3573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Allocate buffer of that many longwords. */ 3583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj register PTRACE_XFER_TYPE *buffer 3593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); 3603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (debuglevel >= 1) { 3623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG (1, "Writing "); 3633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < len; i++) 3643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj PDEBUG (1, "%02x", (unsigned)myaddr[i]); 3653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj PDEBUG(1, " to %p\n", (void *) memaddr); 3663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 3673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Fill start and end extra bytes of buffer with existing memory data. */ 3693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, 3713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (PTRACE_ARG3_TYPE) addr, 0); 3723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (count > 1) { 3743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buffer[count - 1] 3753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj = ptrace (PTRACE_PEEKTEXT, inferior_pid, 3763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (PTRACE_ARG3_TYPE) (addr + (count - 1) 3773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj * sizeof (PTRACE_XFER_TYPE)), 3783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 0); 3793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 3803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Copy data to be written over corresponding part of buffer */ 3823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), 3843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj myaddr, len); 3853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Write the entire buffer. */ 3873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) { 3893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj errno = 0; 3903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ptrace (PTRACE_POKETEXT, inferior_pid, 3913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (PTRACE_ARG3_TYPE) addr, buffer[i]); 3923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (errno) 3933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return errno; 3943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 3953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return 0; 3973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 3983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 3993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* subset of VG_(threads) needed for vgdb ptrace. 4003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj This is initialized when process is attached. */ 4013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef struct { 4023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ThreadStatus status; 4033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Int lwpid; 4043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 4053b290486cd4cd601b20e04340e593c9ed9717e5fsewardjVgdbThreadState; 4063b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic VgdbThreadState vgdb_threads[VG_N_THREADS]; 4073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4083b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const 4093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjHChar* name_of_ThreadStatus ( ThreadStatus status ) 4103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 4113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj switch (status) { 4123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_Empty: return "VgTs_Empty"; 4133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_Init: return "VgTs_Init"; 4143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_Runnable: return "VgTs_Runnable"; 4153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_WaitSys: return "VgTs_WaitSys"; 4163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_Yielding: return "VgTs_Yielding"; 4173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case VgTs_Zombie: return "VgTs_Zombie"; 4183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj default: return "VgTs_???"; 4193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 4213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 4233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *status_image (int status) 4243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 4253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj static char result[256]; 4263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int sz = 0; 4273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define APPEND(...) sz += snprintf (result+sz, 256 - sz - 1, __VA_ARGS__) 4283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj result[0] = 0; 4303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WIFEXITED(status)) 4323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj APPEND ("WIFEXITED %d ", WEXITSTATUS(status)); 4333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WIFSIGNALED(status)) { 4353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj APPEND ("WIFSIGNALED %d ", WTERMSIG(status)); 4363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WCOREDUMP(status)) APPEND ("WCOREDUMP "); 4373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WIFSTOPPED(status)) 4403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj APPEND ("WIFSTOPPED %d ", WSTOPSIG(status)); 4413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WIFCONTINUED(status)) 4433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj APPEND ("WIFCONTINUED "); 4443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return result; 4463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#undef APPEND 4473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 4483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Wait till the process pid is reported as stopped with signal_expected. 4503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If other signal(s) than signal_expected are received, waitstopped 4513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj will pass them to pid, waiting for signal_expected to stop pid. 4523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True when process is in stopped state with signal_expected. 4533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns False if a problem was encountered while waiting for pid 4543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to be stopped. 4553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If pid is reported as being dead/exited, waitstopped will return False. 4573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/ 4583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 4593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool waitstopped (int pid, int signal_expected, char *msg) 4603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 4613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_t p; 4623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int status = 0; 4633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int signal_received; 4643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int res; 4653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (1) { 4673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "waitstopped %s before waitpid signal_expected %d\n", 4683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj msg, signal_expected); 4693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj p = waitpid(pid, &status, __WALL); 4703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "after waitpid pid %d p %d status 0x%x %s\n", pid, p, 4713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj status, status_image (status)); 4723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (p != pid) { 4733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "%s waitpid pid %d in waitstopped %d status 0x%x %s\n", 4743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj msg, pid, p, status, status_image (status)); 4753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 4763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (WIFEXITED(status)) { 4793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 4803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 4813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert (WIFSTOPPED(status)); 4843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj signal_received = WSTOPSIG(status); 4853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (signal_received == signal_expected) 4863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 4873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* pid received a signal which is not the signal we are waiting for. 4893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj We continue pid, transmitting this signal. */ 4903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "waitstopped PTRACE_CONT with signal %d\n", signal_received); 4913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = ptrace (PTRACE_CONT, pid, NULL, signal_received); 4923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) { 4933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "waitstopped PTRACE_CONT\n"); 4943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 4953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 4973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 4983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return True; 4993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 5003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Stops the given pid, wait for the process to be stopped. 5023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if succesful, False otherwise. 5033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj msg is used in tracing and error reporting. */ 5043b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 5053b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool stop (int pid, char *msg) 5063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 5073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj long res; 5083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "%s SIGSTOP pid %d\n", msg, pid); 5103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = kill (pid, SIGSTOP); 5113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) { 5123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "%s SIGSTOP pid %d %ld\n", msg, pid, res); 5133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 5143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return waitstopped (pid, SIGSTOP, msg); 5173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 5193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Attaches to given pid, wait for the process to be stopped. 5213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if succesful, False otherwise. 5223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj msg is used in tracing and error reporting. */ 5233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 5243b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool attach (int pid, char *msg) 5253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 5263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj long res; 52730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj static Bool output_error = True; 52830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj static Bool initial_attach = True; 52930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // For a ptrace_scope protected system, we do not want to output 53030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // repetitively attach error. We will output once an error 53130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // for the initial_attach. Once the 1st attach has succeeded, we 53230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // again show all errors. 5333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "%s PTRACE_ATTACH pid %d\n", msg, pid); 5353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = ptrace (PTRACE_ATTACH, pid, NULL, NULL); 5363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) { 53730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (output_error || debuglevel > 0) { 53830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj ERROR(errno, "%s PTRACE_ATTACH pid %d %ld\n", msg, pid, res); 53930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (initial_attach) 54030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj output_error = False; 54130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 5423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 5433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 54530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj initial_attach = False; 54630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj output_error = True; 5473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return waitstopped(pid, SIGSTOP, msg); 5483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 5493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* once we are attached to the pid, get the list of threads and stop 5513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj them all. 5523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if all threads properly suspended, False otherwise. */ 5533b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 5543b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool acquire_and_suspend_threads(int pid) 5553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 5563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 5573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int rw; 5583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool pid_found = False; 5593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Addr vgt; 5603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int sz_tst; 5613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int off_status; 5623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int off_lwpid; 5633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nr_live_threads = 0; 5643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared32 != NULL) { 5663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgt = shared32->threads; 5673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sz_tst = shared32->sizeof_ThreadState; 5683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj off_status = shared32->offset_status; 5693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj off_lwpid = shared32->offset_lwpid; 5703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (shared64 != NULL) { 5723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgt = shared64->threads; 5733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sz_tst = shared64->sizeof_ThreadState; 5743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj off_status = shared64->offset_status; 5753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj off_lwpid = shared64->offset_lwpid; 5763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 5773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert (0); 5783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* note: the entry 0 is unused */ 5813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 1; i < VG_N_THREADS; i++) { 5823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgt += sz_tst; 5833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_read_memory(pid, vgt+off_status, 5843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *)&(vgdb_threads[i].status), 5853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sizeof(ThreadStatus)); 5863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 5873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "status ptrace_read_memory\n"); 5883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 5893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_read_memory(pid, vgt+off_lwpid, 5923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *)&(vgdb_threads[i].lwpid), 5933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sizeof(Int)); 5943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 5953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "lwpid ptrace_read_memory\n"); 5963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 5973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 5983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 5993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].status != VgTs_Empty) { 6003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "found tid %d status %s lwpid %d\n", 6013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj i, name_of_ThreadStatus(vgdb_threads[i].status), 6023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid); 6033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nr_live_threads++; 6043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].lwpid <= 1) { 6053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].lwpid == 0 6063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj && vgdb_threads[i].status == VgTs_Init) { 6073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "not set lwpid tid %d status %s lwpid %d\n", 6083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj i, name_of_ThreadStatus(vgdb_threads[i].status), 6093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid); 6103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 6113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(1, "unexpected lwpid tid %d status %s lwpid %d\n", 6123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj i, name_of_ThreadStatus(vgdb_threads[i].status), 6133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid); 6143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* in case we have a VtTs_Init thread with lwpid not yet set, 6163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj we try again later. */ 6173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 6183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].lwpid == pid) { 6203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert (!pid_found); 6213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert (i == 1); 6223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_found = True; 6233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 6243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!attach(vgdb_threads[i].lwpid, "attach_thread")) { 6253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(0, "ERROR attach pid %d tid %d\n", 6263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid, i); 6273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 6283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* If we found no thread, it means the process is stopping, and 6333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj we better do not force anything to happen during that. */ 6343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nr_live_threads > 0) 6353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return True; 6363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 6373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 6383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 6393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 6403b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 6413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid detach_from_all_threads(int pid) 6423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 6433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 6443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj long res; 6453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool pid_found = False; 6463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 6473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* detach from all the threads */ 6483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 1; i < VG_N_THREADS; i++) { 6493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].status != VgTs_Empty) { 6503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].status == VgTs_Init 6513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj && vgdb_threads[i].lwpid == 0) { 6523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "skipping PTRACE_DETACH pid %d tid %d status %s\n", 6533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid, i, 6543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj name_of_ThreadStatus (vgdb_threads[i].status)); 6553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 6563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_threads[i].lwpid == pid) { 6573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert (!pid_found); 6583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_found = True; 6593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "PTRACE_DETACH pid %d tid %d status %s\n", 6613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid, i, 6623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj name_of_ThreadStatus (vgdb_threads[i].status)); 6633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = ptrace (PTRACE_DETACH, vgdb_threads[i].lwpid, NULL, NULL); 6643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) { 6653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "PTRACE_DETACH pid %d tid %d status %s res %ld\n", 6663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_threads[i].lwpid, i, 6673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj name_of_ThreadStatus (vgdb_threads[i].status), 6683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res); 6693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 6743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!pid_found && pid) { 6753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* No threads are live. Process is busy stopping. 6763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj We need to detach from pid explicitely. */ 6773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "no thread live => PTRACE_DETACH pid %d\n", pid); 6783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = ptrace (PTRACE_DETACH, pid, NULL, NULL); 6793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) 6803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "PTRACE_DETACH pid %d res %ld\n", pid, res); 6813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 6823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 6833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 6843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj// if > 0, pid for which registers have to be restored. 6853b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int pid_of_save_regs = 0; 6863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic struct user user_save; 6873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 688eefeeb7a60a347bc851605fadd52672cbd927201sewardj// The below indicates if ptrace_getregs (and ptrace_setregs) can be used. 689eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note that some linux versions are defining PTRACE_GETREGS but using 690eefeeb7a60a347bc851605fadd52672cbd927201sewardj// it gives back EIO. 691eefeeb7a60a347bc851605fadd52672cbd927201sewardj// has_working_ptrace_getregs can take the following values: 692eefeeb7a60a347bc851605fadd52672cbd927201sewardj// -1 : PTRACE_GETREGS is defined 693eefeeb7a60a347bc851605fadd52672cbd927201sewardj// runtime check not yet done. 694eefeeb7a60a347bc851605fadd52672cbd927201sewardj// 0 : PTRACE_GETREGS runtime check has failed. 695eefeeb7a60a347bc851605fadd52672cbd927201sewardj// 1 : PTRACE_GETREGS defined and runtime check ok. 696eefeeb7a60a347bc851605fadd52672cbd927201sewardj#ifdef PTRACE_GETREGS 697eefeeb7a60a347bc851605fadd52672cbd927201sewardjstatic int has_working_ptrace_getregs = -1; 698eefeeb7a60a347bc851605fadd52672cbd927201sewardj#endif 699eefeeb7a60a347bc851605fadd52672cbd927201sewardj 7003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Get the registers from pid into regs. 701eefeeb7a60a347bc851605fadd52672cbd927201sewardj regs_bsz value gives the length of *regs. 7023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if all ok, otherwise False. */ 7033b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 704eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool getregs (int pid, void *regs, long regs_bsz) 7053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 706eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "getregs regs_bsz %ld\n", regs_bsz); 707eefeeb7a60a347bc851605fadd52672cbd927201sewardj# ifdef PTRACE_GETREGS 708eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (has_working_ptrace_getregs) { 709eefeeb7a60a347bc851605fadd52672cbd927201sewardj // Platforms having GETREGS 710eefeeb7a60a347bc851605fadd52672cbd927201sewardj long res; 711eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "getregs PTRACE_GETREGS\n"); 712eefeeb7a60a347bc851605fadd52672cbd927201sewardj res = ptrace (PTRACE_GETREGS, pid, NULL, regs); 713eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (res == 0) { 714eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (has_working_ptrace_getregs == -1) { 715eefeeb7a60a347bc851605fadd52672cbd927201sewardj // First call to PTRACE_GETREGS succesful => 716eefeeb7a60a347bc851605fadd52672cbd927201sewardj has_working_ptrace_getregs = 1; 717eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "detected a working PTRACE_GETREGS\n"); 718eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 719eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (has_working_ptrace_getregs == 1); 720eefeeb7a60a347bc851605fadd52672cbd927201sewardj return True; 721eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 722eefeeb7a60a347bc851605fadd52672cbd927201sewardj else if (has_working_ptrace_getregs == 1) { 723eefeeb7a60a347bc851605fadd52672cbd927201sewardj // We had a working call, but now it fails. 724eefeeb7a60a347bc851605fadd52672cbd927201sewardj // This is unexpected. 725eefeeb7a60a347bc851605fadd52672cbd927201sewardj ERROR(errno, "PTRACE_GETREGS %ld\n", res); 7263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 727eefeeb7a60a347bc851605fadd52672cbd927201sewardj } else { 728eefeeb7a60a347bc851605fadd52672cbd927201sewardj // Check this is the first call: 729eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (has_working_ptrace_getregs == -1); 730eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (errno == EIO) { 731eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "detected a broken PTRACE_GETREGS with EIO\n"); 732eefeeb7a60a347bc851605fadd52672cbd927201sewardj has_working_ptrace_getregs = 0; 733eefeeb7a60a347bc851605fadd52672cbd927201sewardj // Fall over to the PTRACE_PEEKUSER case. 734eefeeb7a60a347bc851605fadd52672cbd927201sewardj } else { 735eefeeb7a60a347bc851605fadd52672cbd927201sewardj ERROR(errno, "broken PTRACE_GETREGS unexpected errno %ld\n", res); 736eefeeb7a60a347bc851605fadd52672cbd927201sewardj return False; 737eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 7383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 7393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 7403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# endif 741eefeeb7a60a347bc851605fadd52672cbd927201sewardj 742eefeeb7a60a347bc851605fadd52672cbd927201sewardj // We assume PTRACE_PEEKUSER is defined everywhere. 743eefeeb7a60a347bc851605fadd52672cbd927201sewardj { 744eefeeb7a60a347bc851605fadd52672cbd927201sewardj# ifdef PT_ENDREGS 745eefeeb7a60a347bc851605fadd52672cbd927201sewardj long peek_bsz = PT_ENDREGS; 746eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (peek_bsz <= regs_bsz); 747eefeeb7a60a347bc851605fadd52672cbd927201sewardj# else 748eefeeb7a60a347bc851605fadd52672cbd927201sewardj long peek_bsz = regs_bsz-1; 749eefeeb7a60a347bc851605fadd52672cbd927201sewardj# endif 750eefeeb7a60a347bc851605fadd52672cbd927201sewardj char *pregs = (char *) regs; 751eefeeb7a60a347bc851605fadd52672cbd927201sewardj long offset; 752eefeeb7a60a347bc851605fadd52672cbd927201sewardj errno = 0; 753eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "getregs PTRACE_PEEKUSER(s) peek_bsz %ld\n", peek_bsz); 754eefeeb7a60a347bc851605fadd52672cbd927201sewardj for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 755eefeeb7a60a347bc851605fadd52672cbd927201sewardj *(long *)(pregs+offset) = ptrace(PTRACE_PEEKUSER, pid, offset, NULL); 756eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (errno != 0) { 757eefeeb7a60a347bc851605fadd52672cbd927201sewardj ERROR(errno, "PTRACE_PEEKUSER offset %ld\n", offset); 758eefeeb7a60a347bc851605fadd52672cbd927201sewardj return False; 759eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 760eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 761eefeeb7a60a347bc851605fadd52672cbd927201sewardj return True; 762eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 763eefeeb7a60a347bc851605fadd52672cbd927201sewardj 764eefeeb7a60a347bc851605fadd52672cbd927201sewardj // If neither PTRACE_GETREGS not PTRACE_PEEKUSER have returned, 765eefeeb7a60a347bc851605fadd52672cbd927201sewardj // then we are in serious trouble. 766eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (0); 7673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 7683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 7693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Set the registers of pid to regs. 770eefeeb7a60a347bc851605fadd52672cbd927201sewardj regs_bsz value gives the length of *regs. 7713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if all ok, otherwise False. */ 7723b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 773eefeeb7a60a347bc851605fadd52672cbd927201sewardjBool setregs (int pid, void *regs, long regs_bsz) 7743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 775eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "setregs regs_bsz %ld\n", regs_bsz); 776eefeeb7a60a347bc851605fadd52672cbd927201sewardj// Note : the below is checking for GETREGS, not SETREGS 777eefeeb7a60a347bc851605fadd52672cbd927201sewardj// as if one is defined and working, the other one should also work. 778eefeeb7a60a347bc851605fadd52672cbd927201sewardj# ifdef PTRACE_GETREGS 779eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (has_working_ptrace_getregs) { 780eefeeb7a60a347bc851605fadd52672cbd927201sewardj // Platforms having SETREGS 781eefeeb7a60a347bc851605fadd52672cbd927201sewardj long res; 782eefeeb7a60a347bc851605fadd52672cbd927201sewardj // setregs can never be called before getregs has done a runtime check. 783eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (has_working_ptrace_getregs == 1); 784eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "setregs PTRACE_SETREGS\n"); 785eefeeb7a60a347bc851605fadd52672cbd927201sewardj res = ptrace (PTRACE_SETREGS, pid, NULL, regs); 786eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (res != 0) { 787eefeeb7a60a347bc851605fadd52672cbd927201sewardj ERROR(errno, "PTRACE_SETREGS %ld\n", res); 7883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 7893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 790eefeeb7a60a347bc851605fadd52672cbd927201sewardj return True; 7913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 7923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# endif 793eefeeb7a60a347bc851605fadd52672cbd927201sewardj 794eefeeb7a60a347bc851605fadd52672cbd927201sewardj { 795eefeeb7a60a347bc851605fadd52672cbd927201sewardj char *pregs = (char *) regs; 796eefeeb7a60a347bc851605fadd52672cbd927201sewardj long offset; 797eefeeb7a60a347bc851605fadd52672cbd927201sewardj long res; 798eefeeb7a60a347bc851605fadd52672cbd927201sewardj# ifdef PT_ENDREGS 799eefeeb7a60a347bc851605fadd52672cbd927201sewardj long peek_bsz = PT_ENDREGS; 800eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (peek_bsz <= regs_bsz); 801eefeeb7a60a347bc851605fadd52672cbd927201sewardj# else 802eefeeb7a60a347bc851605fadd52672cbd927201sewardj long peek_bsz = regs_bsz-1; 803eefeeb7a60a347bc851605fadd52672cbd927201sewardj# endif 804eefeeb7a60a347bc851605fadd52672cbd927201sewardj errno = 0; 805eefeeb7a60a347bc851605fadd52672cbd927201sewardj DEBUG(1, "setregs PTRACE_POKEUSER(s) %ld\n", peek_bsz); 806eefeeb7a60a347bc851605fadd52672cbd927201sewardj for (offset = 0; offset < peek_bsz; offset = offset + sizeof(long)) { 807eefeeb7a60a347bc851605fadd52672cbd927201sewardj res = ptrace(PTRACE_POKEUSER, pid, offset, *(long*)(pregs+offset)); 808eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (errno != 0) { 809eefeeb7a60a347bc851605fadd52672cbd927201sewardj ERROR(errno, "PTRACE_POKEUSER offset %ld res %ld\n", offset, res); 810eefeeb7a60a347bc851605fadd52672cbd927201sewardj return False; 811eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 812eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 813eefeeb7a60a347bc851605fadd52672cbd927201sewardj return True; 814eefeeb7a60a347bc851605fadd52672cbd927201sewardj } 815eefeeb7a60a347bc851605fadd52672cbd927201sewardj 816eefeeb7a60a347bc851605fadd52672cbd927201sewardj // If neither PTRACE_SETREGS not PTRACE_POKEUSER have returned, 817eefeeb7a60a347bc851605fadd52672cbd927201sewardj // then we are in serious trouble. 818eefeeb7a60a347bc851605fadd52672cbd927201sewardj assert (0); 8193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 8203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Restore the registers to the saved value, then detaches from all threads */ 8223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 8233b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid restore_and_detach(int pid) 8243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 8253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pid_of_save_regs) { 8263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* In case the 'main pid' has been continued, we need to stop it 8273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj before resetting the registers. */ 8283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pid_of_save_regs_continued) { 8293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs_continued = False; 8303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!stop(pid_of_save_regs, "sigstop before reset regs")) 8313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(0, "Could not sigstop before reset"); 8323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 8333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "setregs restore registers pid %d\n", pid_of_save_regs); 835eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (!setregs(pid_of_save_regs, &user_save.regs, sizeof(user_save.regs))) { 8363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "setregs restore registers pid %d after cont\n", 8373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs); 8383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 8393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs = 0; 8403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 8413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "PTRACE_SETREGS restore registers: no pid\n"); 8423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 8433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 8443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 8453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Ensures that the gdbserver code is invoked by pid. 8473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If an error occurs, resets to the valgrind process 8483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to the state it has before being ptrace-d. 8493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if invoke successful, False otherwise. 8503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj*/ 8513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 8523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool invoke_gdbserver (int pid) 8533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 85430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj static Bool ptrace_restrictions_msg_given = False; 8553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj long res; 8563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool stopped; 8573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct user user_mod; 8583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Addr sp; 8593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* A specific int value is passed to invoke_gdbserver, to check 8603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj everything goes according to the plan. */ 8613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const int check = 0x8BADF00D; // ate bad food. 8623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const Addr bad_return = 0; 8643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // A bad return address will be pushed on the stack. 8653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // The function invoke_gdbserver cannot return. If ever it returns, a NULL 8663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // address pushed on the stack should ensure this is detected. 8673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Not yet attached. If problem, vgdb can abort, 8693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj no cleanup needed. 8703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj On Ubuntu>= 10.10, a /proc setting can disable ptrace. 8723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj So, Valgrind has to SET_PTRACER this vgdb. Once this 8733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj is done, this vgdb can ptrace the valgrind process. */ 8743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "attach to 'main' pid %d\n", pid); 8763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!attach(pid, "attach main pid")) { 87730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (!ptrace_restrictions_msg_given) { 87830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj ptrace_restrictions_msg_given = True; 87930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj ERROR(0, "error attach main pid %d\n", pid); 88030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj ptrace_restrictions_msg(); 88130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 8823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 8833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 8843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Now, we are attached. If problem, detach and return. */ 8863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 8873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!acquire_and_suspend_threads(pid)) { 8883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 8893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* if the pid does not exist anymore, we better stop */ 8903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (kill(pid, 0) != 0) 8913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "invoke_gdbserver: check for pid %d existence failed\n", 8923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid); 8933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 8943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 8953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 896eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (!getregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { 8973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 8983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 8993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 9003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_save = user_mod; 9013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86) 9033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.esp; 9043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64) 9053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.rsp; 9063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared32 != NULL) { 9073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* 64bit vgdb speaking with a 32bit executable. 9083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj To have system call restart properly, we need to sign extend rax. 9093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj For more info: 9103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj web search '[patch] Fix syscall restarts for amd64->i386 biarch' 9113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj e.g. http://sourceware.org/ml/gdb-patches/2009-11/msg00592.html */ 9123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *(long *)&user_save.regs.rax = *(int*)&user_save.regs.rax; 9133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "Sign extending %8.8lx to %8.8lx\n", 9143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rax, user_save.regs.rax); 9153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 9163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm) 9173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.uregs[13]; 9183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32) 9193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.gpr[1]; 9203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64) 9213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.gpr[1]; 9223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x) 9233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = user_mod.regs.gprs[15]; 9243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 9253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj I_die_here : (sp) architecture missing in vgdb.c 9263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 9273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // the magic below is derived from spying what gdb sends to 9303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // the (classical) gdbserver when invoking a C function. 9313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared32 != NULL) { 9323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // vgdb speaking with a 32bit executable. 9333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86) || defined(VGA_amd64) 9343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const int regsize = 4; 9353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int rw; 9363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* push check arg on the stack */ 9373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = sp - regsize; 9383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "push check arg ptrace_write_memory\n"); 9393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(regsize == sizeof(check)); 9403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_write_memory(pid, sp, 9413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *) &check, 9423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj regsize); 9433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 9443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "push check arg ptrace_write_memory"); 9453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 9463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 9473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 9483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = sp - regsize; 9503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 9513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // Note that for a 64 bits vgdb, only 4 bytes of NULL bad_return 9523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // are written. 9533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_write_memory(pid, sp, 9543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *) &bad_return, 9553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj regsize); 9563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 9573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "push bad_return return address ptrace_write_memory"); 9583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 9593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 9603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 9613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86) 9623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // compiled in 32bits, speaking with a 32bits exe 9643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.ebp = sp; // bp set to sp 9653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.esp = sp; 9663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.eip = shared32->invoke_gdbserver; 9673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.orig_eax = -1L; 9683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64) 9693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* set ebp, esp, eip and orig_eax to invoke gdbserver */ 9703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // compiled in 64bits, speaking with a 32bits exe 9713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rbp = sp; // bp set to sp 9723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rsp = sp; 9733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rip = shared32->invoke_gdbserver; 9743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.orig_rax = -1L; 9753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 9763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj I_die_here : not x86 or amd64 in x86/amd64 section/ 9773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 9783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32) || defined(VGA_ppc64) 9803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.nip = shared32->invoke_gdbserver; 9813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.trap = -1L; 9823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put check arg in register 3 */ 9833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gpr[3] = check; 9843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put NULL return address in Link Register */ 9853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.link = bad_return; 9863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm) 9883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put check arg in register 0 */ 9893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.uregs[0] = check; 9903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put NULL return address in Link Register */ 9913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.uregs[14] = bad_return; 9923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.uregs[15] = shared32->invoke_gdbserver; 9933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 9943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x) 9953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR(0, "(fn32) s390x has no 32bits implementation"); 9963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 9973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj I_die_here : architecture missing in vgdb.c 9983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 9993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (shared64 != NULL) { 10023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#if defined(VGA_x86) 10033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 10043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_amd64) 10053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // vgdb speaking with a 64 bit executable. 10063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const int regsize = 8; 10073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int rw; 10083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* give check arg in rdi */ 10103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rdi = check; 10113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* push return address on stack : return to breakaddr */ 10133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = sp - regsize; 10143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "push bad_return return address ptrace_write_memory\n"); 10153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_write_memory(pid, sp, 10163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *) &bad_return, 10173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sizeof(bad_return)); 10183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 10193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "push bad_return return address ptrace_write_memory"); 10203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 10213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 10223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* set rbp, rsp, rip and orig_rax to invoke gdbserver */ 10253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rbp = sp; // bp set to sp 10263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rsp = sp; 10273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.rip = shared64->invoke_gdbserver; 10283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.orig_rax = -1L; 10293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_arm) 10313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 10323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc32) 10333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); // cannot vgdb a 64 bits executable with a 32 bits exe 10343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_ppc64) 10353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Addr64 func_addr; 10363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Addr64 toc_addr; 10373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int rw; 10383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_read_memory(pid, shared64->invoke_gdbserver, 10393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *)&func_addr, 10403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sizeof(Addr64)); 10413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 10423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "ppc64 read func_addr\n"); 10433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 10443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 10453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj rw = ptrace_read_memory(pid, shared64->invoke_gdbserver+8, 10473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (unsigned char *)&toc_addr, 10483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sizeof(Addr64)); 10493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (rw != 0) { 10503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(rw, "ppc64 read toc_addr\n"); 10513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 10523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 10533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // We are not pushing anything on the stack, so it is not 10553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // very clear why the sp has to be decreased, but it seems 10563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj // needed. The ppc64 ABI might give some lights on this ? 10573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gpr[1] = sp - 220; 10583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gpr[2] = toc_addr; 10593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.nip = func_addr; 10603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.trap = -1L; 10613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put check arg in register 3 */ 10623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gpr[3] = check; 10633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put bad_return return address in Link Register */ 10643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.link = bad_return; 10653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#elif defined(VGA_s390x) 10663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* put check arg in register r2 */ 10673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gprs[2] = check; 10683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* bad_return Return address is in r14 */ 10693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gprs[14] = bad_return; 10703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* minimum stack frame */ 10713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sp = sp - 160; 10723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.gprs[15] = sp; 10733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* set program counter */ 10743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj user_mod.regs.psw.addr = shared64->invoke_gdbserver; 10753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#else 10763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj I_die_here: architecture missing in vgdb.c 10773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 10783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else { 10803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); 10813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1083eefeeb7a60a347bc851605fadd52672cbd927201sewardj if (!setregs(pid, &user_mod.regs, sizeof(user_mod.regs))) { 10843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj detach_from_all_threads(pid); 10853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 10863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 10873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Now that we have modified the registers, we set 10883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs to indicate that restore_and_detach 10893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj must restore the registers in case of cleanup. */ 10903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs = pid; 10913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs_continued = False; 10923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 10943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* We PTRACE_CONT-inue pid. 10953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Either gdbserver will be invoked directly (if all 10963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj threads are interruptible) or gdbserver will be 10973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj called soon by the scheduler. In the first case, 10983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid will stop on the break inserted above when 10993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj gdbserver returns. In the 2nd case, the break will 11003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj be encountered directly. */ 11013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "PTRACE_CONT to invoke\n"); 11023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj res = ptrace (PTRACE_CONT, pid, NULL, NULL); 11033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (res != 0) { 11043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "PTRACE_CONT\n"); 11053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj restore_and_detach(pid); 11063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 11073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 11083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs_continued = True; 1109b2572b52b37d56d302408395f7fed9f509423af1sewardj /* Wait for SIGSTOP generated by m_gdbserver.c give_control_back_to_vgdb */ 1110b2572b52b37d56d302408395f7fed9f509423af1sewardj stopped = waitstopped (pid, SIGSTOP, 11113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "waitpid status after PTRACE_CONT to invoke"); 11123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (stopped) { 11133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Here pid has properly stopped on the break. */ 11143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid_of_save_regs_continued = False; 11153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj restore_and_detach(pid); 11163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return True; 11173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 11183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Whatever kind of problem happened. We shutdown */ 11193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 11203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 11213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 11223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 11233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 11243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 11253b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 11263b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid cleanup_restore_and_detach(void *v_pid) 11273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 11283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "cleanup_restore_and_detach dying: %d\n", dying); 11293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#ifdef PTRACEINVOKER 11303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!dying) 11313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj restore_and_detach(*(int*)v_pid); 11323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#endif 11333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 11343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 11353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* This function loops till shutting_down becomes true. In this loop, 11363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj it verifies if valgrind process is reading the characters written 11373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj by vgdb. The verification is done every max_invoke_ms ms. If 11383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind is not reading characters, it will use invoke_gdbserver 11393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (if PTRACE_INVOKER is defined) to ensure that the gdbserver code is 11403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj called soon by valgrind. */ 11413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int max_invoke_ms = 100; 114230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj#define NEVER 99999999 114330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjstatic int cmd_time_out = NEVER; 11443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 11453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid *invoke_gdbserver_in_valgrind(void *v_pid) 11463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 114730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj struct timeval cmd_max_end_time; 114830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj Bool cmd_started = False; 114930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj struct timeval invoke_time; 115030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj 11513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int pid = *(int *)v_pid; 11523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int written_by_vgdb_before_sleep; 11533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int seen_by_valgrind_before_sleep; 11543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 11553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int invoked_written = -1; 115630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj unsigned int usecs; 11573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 11583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pthread_cleanup_push(cleanup_restore_and_detach, v_pid); 11593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 11603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (!shutting_down) { 11613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj written_by_vgdb_before_sleep = VS_written_by_vgdb; 11623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj seen_by_valgrind_before_sleep = VS_seen_by_valgrind; 11633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(3, 11643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "written_by_vgdb_before_sleep %d " 11653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "seen_by_valgrind_before_sleep %d\n", 11663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj written_by_vgdb_before_sleep, 11673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj seen_by_valgrind_before_sleep); 116830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (cmd_time_out != NEVER 116930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj && !cmd_started 117030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) { 117130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj /* A command was started. Record the time at which it was started. */ 117230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj DEBUG(1, "IO for command started\n"); 117330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj gettimeofday(&cmd_max_end_time, NULL); 117430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj cmd_max_end_time.tv_sec += cmd_time_out; 117530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj cmd_started = True; 117630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 117730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (max_invoke_ms > 0) { 117830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj usecs = 1000 * max_invoke_ms; 117930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj gettimeofday(&invoke_time, NULL); 118030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj invoke_time.tv_sec += max_invoke_ms / 1000; 118130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000); 118230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000); 118330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000); 118430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } else { 118530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj usecs = 0; 118630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 118730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (cmd_started) { 118830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // 0 usecs here means the thread just has to check gdbserver eats 118930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // the characters in <= cmd_time_out seconds. 119030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // We will just wait by 1 second max at a time. 119130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (usecs == 0 || usecs > 1000 * 1000) 119230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj usecs = 1000 * 1000; 119330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 1194992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj usleep(usecs); 1195992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 119630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj /* If nothing happened during our sleep, let's try to wake up valgrind 119730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj or check for cmd time out. */ 11983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (written_by_vgdb_before_sleep == VS_written_by_vgdb 11993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj && seen_by_valgrind_before_sleep == VS_seen_by_valgrind 12003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj && VS_written_by_vgdb > VS_seen_by_valgrind) { 120130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj struct timeval now; 120230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj gettimeofday(&now, NULL); 12033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, 12043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "after sleep " 12053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "written_by_vgdb %d " 12063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "seen_by_valgrind %d " 12073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "invoked_written %d\n", 12083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_written_by_vgdb, 12093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_seen_by_valgrind, 12103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj invoked_written); 12113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* if the pid does not exist anymore, we better stop */ 12123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (kill(pid, 0) != 0) 12133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, 12143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "invoke_gdbserver_in_valgrind: " 12153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "check for pid %d existence failed\n", pid); 121630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (cmd_started) { 121730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (timercmp (&now, &cmd_max_end_time, >)) 121830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj XERROR (0, 121930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj "pid %d did not handle a command in %d seconds\n", 122030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj pid, cmd_time_out); 122130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 122230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) { 122330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj #if defined(PTRACEINVOKER) 122430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj /* only need to wake up if the nr written has changed since 122530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj last invoke. */ 122630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (invoked_written != written_by_vgdb_before_sleep) { 122730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (invoke_gdbserver(pid)) { 122830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj /* If invoke succesful, no need to invoke again 122930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj for the same value of written_by_vgdb_before_sleep. */ 123030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj invoked_written = written_by_vgdb_before_sleep; 123130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 12323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 123330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj #else 123430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj DEBUG(2, "invoke_gdbserver via ptrace not (yet) implemented\n"); 123530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj #endif 123630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 123730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } else { 123830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj // Something happened => restart timer check. 123930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (cmd_time_out != NEVER) { 124030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj DEBUG(2, "some IO was done => restart command\n"); 124130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj cmd_started = False; 12423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 12433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 12443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 12453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pthread_cleanup_pop(0); 12463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return NULL; 12473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 12483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 12503b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint open_fifo (char* name, int flags, char* desc) 12513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 12523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int fd; 12533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "opening %s %s\n", name, desc); 12543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fd = open(name, flags); 12553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fd == -1) 12563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "error opening %s %s\n", name, desc); 12573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "opened %s %s fd %d\n", name, desc, fd); 12593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return fd; 12603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 12613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* acquire a lock on the first byte of the given fd. If not successful, 12633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exits with error. 12643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj This allows to avoid having two vgdb speaking with the same Valgrind 12653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj gdbserver as this causes serious headaches to the protocol. */ 12663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 12673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid acquire_lock (int fd, int valgrind_pid) 12683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 1269992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj struct flock fl; 1270992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fl.l_type = F_WRLCK; 1271992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fl.l_whence = SEEK_SET; 1272992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fl.l_start = 0; 1273992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fl.l_len = 1; 1274992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (fcntl(fd, F_SETLK, &fl) < 0) { 12753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (errno == EAGAIN || errno == EACCES) { 12763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR(errno, 12773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "Cannot acquire lock.\n" 12783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "Probably vgdb pid %d already speaks with Valgrind pid %d\n", 12793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_vgdb_pid, 12803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind_pid); 12813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 12823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR(errno, "cannot acquire lock.\n"); 12833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 12843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 12853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Here, we have the lock. It will be released when fd will be closed. */ 12873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* We indicate our pid to Valgrind gdbserver */ 12883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shared32 != NULL) 12893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared32->vgdb_pid = getpid(); 12903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (shared64 != NULL) 12913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shared64->vgdb_pid = getpid(); 12923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 12933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assert(0); 12943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 12953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj#define PBUFSIZ 16384 /* keep in sync with server.h */ 12973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 12983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* read some characters from fd. 12993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns the nr of characters read, -1 if error. 13003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj desc is a string used in tracing */ 13013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 13023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint read_buf (int fd, char* buf, char* desc) 13033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 13043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nrread; 13053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "reading %s\n", desc); 13063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrread = read(fd, buf, PBUFSIZ); 13073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrread == -1) { 13083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR (errno, "error reading %s\n", desc); 13093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return -1; 13103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 13113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buf[nrread] = '\0'; 13123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "read %s %s\n", desc, buf); 13133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return nrread; 13143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 13153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 13163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* write size bytes from buf to fd. 13173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj desc is a description of the action for which the write is done. 13183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If notify, then add size to the shared cntr indicating to the 13193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind process that there is new data. 13203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns True if write is ok, False if there was a problem. */ 13213b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 13223b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool write_buf(int fd, char* buf, int size, char* desc, Bool notify) 13233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 13243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nrwritten; 13253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nrw; 13263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "writing %s len %d %s notify: %d\n", desc, size, buf, notify); 13273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrwritten = 0; 13283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (nrwritten < size) { 13293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrw = write (fd, buf+nrwritten, size - nrwritten); 13303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrw == -1) { 13313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "error write %s\n", desc); 13323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 13333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 13343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrwritten = nrwritten + nrw; 13353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (notify) 13363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj add_written(nrw); 13373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 13383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return True; 13393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 13403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 13413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjtypedef enum { 13423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj FROM_GDB, 13433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj TO_GDB, 13443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj FROM_PID, 13453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj TO_PID } ConnectionKind; 13463b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic const int NumConnectionKind = TO_PID+1; 13473b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 13483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjchar *ppConnectionKind (ConnectionKind con) 13493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 13503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj switch (con) { 13513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case FROM_GDB: return "FROM_GDB"; 13523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case TO_GDB: return "TO_GDB"; 13533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case FROM_PID: return "FROM_PID"; 13543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case TO_PID: return "TO_PID"; 13553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj default: return "invalid connection kind"; 13563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 13573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 13583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 13593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *shared_mem; 13603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1361992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int from_gdb = 0; /* stdin by default, changed if --port is given. */ 13623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *from_gdb_to_pid; /* fifo name to write gdb command to pid */ 13633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly. 13643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns False in case of error. 13653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to_pid is the file descriptor to write to the process pid. */ 13663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 13673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_gdb_write_to_pid(int to_pid) 13683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 13691d76a80d63502951cb9cbf6f696d663f093083faphilippe char buf[PBUFSIZ+1]; // +1 for trailing \0 13703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nrread; 13713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 13723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrread = read_buf(from_gdb, buf, "from gdb on stdin"); 13733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrread <= 0) { 13743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrread == 0) 13753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "read 0 bytes from gdb => assume exit\n"); 13763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 13773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "error reading bytes from gdb\n"); 13783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj close (from_gdb); 13793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 13803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 13813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 13823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return write_buf(to_pid, buf, nrread, "to_pid", /* notify */ True); 13833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 13843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1385992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic int to_gdb = 1; /* stdout by default, changed if --port is given. */ 13863b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic char *to_gdb_from_pid; /* fifo name to read pid replies */ 13873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns True in case read/write operations were done properly. 13883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns False in case of error. 13893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from_pid is the file descriptor to read data from the process pid. */ 13903b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 13913b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool read_from_pid_write_to_gdb(int from_pid) 13923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 13931d76a80d63502951cb9cbf6f696d663f093083faphilippe char buf[PBUFSIZ+1]; // +1 for trailing \0 13943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nrread; 13953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 13963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nrread = read_buf(from_pid, buf, "from pid"); 13973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrread <= 0) { 13983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nrread == 0) 13993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "read 0 bytes from pid => assume exit\n"); 14003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 14013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "error reading bytes from pid\n"); 14023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj close (from_pid); 14033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 14043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 14053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 14063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return write_buf(to_gdb, buf, nrread, "to_gdb", /* notify */ False); 14073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 14083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1409992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjstatic 1410992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardjvoid wait_for_gdb_connect (int in_port) 1411992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj{ 1412992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj struct sockaddr_in addr; 1413992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1414992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj int listen_gdb = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); 1415992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj int gdb_connect; 1416992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1417992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (-1 == listen_gdb) { 1418992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj XERROR(errno, "cannot create socket"); 1419992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 1420992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1421992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj memset(&addr, 0, sizeof(addr)); 1422992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1423992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj addr.sin_family = AF_INET; 1424992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj addr.sin_port = htons((unsigned short int)in_port); 1425992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj addr.sin_addr.s_addr = INADDR_ANY; 1426992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1427992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (-1 == bind(listen_gdb,(struct sockaddr *)&addr, sizeof(addr))) { 1428992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj XERROR(errno, "bind failed"); 1429992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 1430992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fprintf(stderr, "listening on port %d ...", in_port); 1431992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fflush(stderr); 1432992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (-1 == listen(listen_gdb, 1)) { 1433992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj XERROR(errno, "error listen failed"); 1434992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 1435992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 1436992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj gdb_connect = accept(listen_gdb, NULL, NULL); 1437992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (gdb_connect < 0) { 1438992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj XERROR(errno, "accept failed"); 1439992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 1440992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fprintf(stderr, "connected.\n"); 1441992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fflush(stderr); 1442992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj close(listen_gdb); 1443992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj from_gdb = gdb_connect; 1444992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj to_gdb = gdb_connect; 1445992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj} 1446992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 14473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* prepares the FIFOs filenames, map the shared memory. */ 14483b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 14493b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid prepare_fifos_and_shared_mem(int pid) 14503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 1451ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian const HChar *user, *host; 1452ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian unsigned len; 1453ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian 1454ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian user = getenv("LOGNAME"); 1455ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian if (user == NULL) user = getenv("USER"); 1456ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian if (user == NULL) user = "???"; 1457ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian 1458ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian host = getenv("HOST"); 1459ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian if (host == NULL) host = getenv("HOSTNAME"); 1460ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian if (host == NULL) host = "???"; 1461ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian 1462ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian len = strlen(vgdb_prefix) + strlen(user) + strlen(host) + 40; 1463ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian from_gdb_to_pid = vmalloc (len); 1464ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian to_gdb_from_pid = vmalloc (len); 1465ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian shared_mem = vmalloc (len); 14663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* below 3 lines must match the equivalent in remote-utils.c */ 1467ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian sprintf(from_gdb_to_pid, "%s-from-vgdb-to-%d-by-%s-on-%s", vgdb_prefix, 1468ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian pid, user, host); 1469ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian sprintf(to_gdb_from_pid, "%s-to-vgdb-from-%d-by-%s-on-%s", vgdb_prefix, 1470ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian pid, user, host); 1471ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian sprintf(shared_mem, "%s-shared-mem-vgdb-%d-by-%s-on-%s", vgdb_prefix, 1472ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian pid, user, host); 14733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG (1, "vgdb: using %s %s %s\n", 14743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from_gdb_to_pid, to_gdb_from_pid, shared_mem); 14753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 14763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj map_vgdbshared(shared_mem); 14773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 14783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 14793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Convert hex digit A to a number. */ 14803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 14813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int 14823b290486cd4cd601b20e04340e593c9ed9717e5fsewardjfromhex (int a) 14833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 14843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (a >= '0' && a <= '9') 14853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return a - '0'; 14863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (a >= 'a' && a <= 'f') 14873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return a - 'a' + 10; 14883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 14893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR(0, "Reply contains invalid hex digit %c\n", a); 14903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return 0; 14913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 14923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 14933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Returns next char from fd. -1 if error, -2 if EOF. 14943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj NB: must always call it with the same fd */ 14953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int 14963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjreadchar (int fd) 14973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 14981d76a80d63502951cb9cbf6f696d663f093083faphilippe static unsigned char buf[PBUFSIZ+1]; // +1 for trailing \0 14993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj static int bufcnt = 0; 15003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj static unsigned char *bufp; 15013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (bufcnt-- > 0) 15033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return *bufp++; 15043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15051d76a80d63502951cb9cbf6f696d663f093083faphilippe bufcnt = read_buf (fd, buf, "static buf readchar"); 15063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (bufcnt <= 0) { 15083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (bufcnt == 0) { 15093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "readchar: Got EOF\n"); 15103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return -2; 15113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 15123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR (errno, "readchar\n"); 15133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return -1; 15143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj bufp = buf; 15183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj bufcnt--; 15193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return *bufp++; 15203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 15213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Read a packet from fromfd, with error checking, 15233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj and store it in BUF. 15243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns length of packet, or -1 if error or -2 if EOF. 15253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Writes ack on ackfd */ 15263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15273b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int 15283b290486cd4cd601b20e04340e593c9ed9717e5fsewardjgetpkt (char *buf, int fromfd, int ackfd) 15293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 15303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *bp; 15313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj unsigned char csum, c1, c2; 15323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int c; 15333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (1) { 15353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj csum = 0; 15363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (1) { 15383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj c = readchar (fromfd); 15393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (c == '$') 15403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 15413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "[getpkt: discarding char '%c']\n", c); 15423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (c < 0) 15433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return c; 15443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj bp = buf; 15473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (1) { 15483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj c = readchar (fromfd); 15493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (c < 0) 15503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return c; 15513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (c == '#') 15523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 15533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (c == '*') { 15543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int repeat; 15553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int r; 15563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int prev; 15573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj prev = *(bp-1); 15583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj csum += c; 15593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj repeat = readchar (fromfd); 15603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj csum += repeat; 15613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (r = 0; r < repeat - 29; r ++) 15623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *bp++ = prev; 15633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 15643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *bp++ = c; 15653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj csum += c; 15663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *bp = 0; 15693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj c1 = fromhex (readchar (fromfd)); 15713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj c2 = fromhex (readchar (fromfd)); 15723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (csum == (c1 << 4) + c2) 15743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 15753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", 15773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (c1 << 4) + c2, csum, buf); 15783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (write (ackfd, "-", 1) != 1) 15793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(0, "error when writing - (nack)\n"); 15803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 15813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj add_written(1); 15823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 15833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "getpkt (\"%s\"); [sending ack] \n", buf); 15853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (write (ackfd, "+", 1) != 1) 15863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(0, "error when writing + (ack)\n"); 15873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 15883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj add_written(1); 15893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return bp - buf; 15903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 15913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 15923b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigint = 0; 15933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigterm = 0; 15943b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigpipe = 0; 15953b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sighup = 0; 15963b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1 = 0; 15973b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigalrm = 0; 15983b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int sigusr1_fd = -1; 15993b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic pthread_t invoke_gdbserver_in_valgrind_thread; 16003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16013b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 16023b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid received_signal (int signum) 16033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 16043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (signum == SIGINT) 16053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigint++; 16063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (signum == SIGUSR1) { 16073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigusr1++; 16083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigusr1_fd >= 0) { 16093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char control_c = '\003'; 16103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj write_buf(sigusr1_fd, &control_c, 1, 16113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "write \\003 on SIGUSR1", /* notify */ True); 16123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 16133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 16143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (signum == SIGTERM) { 16153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 16163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigterm++; 16173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (signum == SIGHUP) { 16183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 16193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sighup++; 16203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (signum == SIGPIPE) { 16213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigpipe++; 16223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (signum == SIGALRM) { 16233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigalrm++; 1624992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#if defined(VGPV_arm_linux_android) 1625992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj /* Android has no pthread_cancel. As it also does not have 1626992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj PTRACE_INVOKER, there is no need for cleanup action. 1627992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj So, we just do nothing. */ 1628992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj DEBUG(1, "sigalrm received, no action on android\n"); 1629992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#else 16303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Note: we cannot directly invoke restore_and_detach : this must 16313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj be done by the thread that has attached. 16323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj We have in this thread pushed a cleanup handler that will 16333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cleanup what is needed. */ 1634992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj DEBUG(1, "pthread_cancel invoke_gdbserver_in_valgrind_thread\n"); 16353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pthread_cancel(invoke_gdbserver_in_valgrind_thread); 1636992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj#endif 16373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 16383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(0, "unexpected signal %d\n", signum); 16393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 16403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 16413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* install the signal handlers allowing e.g. vgdb to cleanup in 16433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case of termination. */ 16443b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 16453b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid install_handlers(void) 16463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 16473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct sigaction action, oldaction; 16483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj action.sa_handler = received_signal; 16503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigemptyset (&action.sa_mask); 16513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj action.sa_flags = 0; 16523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* SIGINT: when user types C-c in gdb, this sends 16543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj a SIGINT to vgdb + causes a character to be sent to remote gdbserver. 16553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj The later is enough to wakeup the valgrind process. */ 16563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigaction (SIGINT, &action, &oldaction) != 0) 16573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error sigaction SIGINT\n"); 16583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* We might do something more intelligent than just 16593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj reporting this SIGINT E.g. behave similarly to the gdb: two 16603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj control-C without feedback from the debugged process would 16613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj mean to stop debugging it. */ 16623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* SIGUSR1: this is used to facilitate automatic testing. When 16643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb receives this signal, it will simulate the user typing C-c. */ 16653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigaction (SIGUSR1, &action, &oldaction) != 0) 16663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error sigaction SIGUSR1\n"); 16673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* SIGTERM: can receive this signal (e.g. from gdb) to terminate vgdb 16703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj when detaching or similar. A clean shutdown will be done as both 16713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj the read and write side will detect an end of file. */ 16723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigaction (SIGTERM, &action, &oldaction) != 0) 16733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error sigaction SIGTERM\n"); 16743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* SIGPIPE: can receive this signal when gdb detaches or kill the 16763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj process debugged: gdb will close its pipes to vgdb. vgdb 16773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj must resist to this signal to allow a clean shutdown. */ 16783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigaction (SIGPIPE, &action, &oldaction) != 0) 16793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error sigaction SIGPIPE\n"); 16803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* SIGALRM: in case invoke thread is blocked, alarm is used 16823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to cleanup. */ 16833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (sigaction (SIGALRM, &action, &oldaction) != 0) 16843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error sigaction SIGALRM\n"); 16853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 16863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* close the FIFOs provided connections, terminate the invoker thread. */ 16883b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 16893b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid close_connection(int to_pid, int from_pid) 16903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 16913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "nr received signals: sigint %d sigterm %d sighup %d sigpipe %d\n", 16923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigint, sigterm, sighup, sigpipe); 16933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* Note that we do not forward sigterm to the valgrind process: 16943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj a sigterm signal is (probably) received from gdb if the user wants to 16953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj kill the debugged process. The kill instruction has been given to 16963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj the valgrind process, which should execute a clean exit. */ 16973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 16983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* We first close the connection to pid. The pid will then 16993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj terminates its gdbserver work. We keep the from pid 17003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fifo opened till the invoker thread is finished. 17013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj This allows the gdbserver to finish sending its last reply. */ 17023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (close(to_pid) != 0) 17033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "close to_pid\n"); 17043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* if there is a task that was busy trying to wake up valgrind 17063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj process, we wait for it to be terminated otherwise threads 17073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj in the valgrind process can stay stopped if vgdb main 17083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exits before the invoke thread had time to detach from 17093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj all valgrind threads. */ 171030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (max_invoke_ms > 0 || cmd_time_out != NEVER) { 17113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int join; 17123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* It is surprisingly complex to properly shutdown or exit the 17143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind process in which gdbserver has been invoked through 17153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ptrace. In the normal case (gdb detaches from the process, 17163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj or process is continued), the valgrind process will reach the 17173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj breakpoint place. Using ptrace, vgdb will ensure the 17183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj previous activity of the process is resumed (e.g. restart a 17193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj blocking system call). The special case is when gdb asks the 17203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind process to exit (using either the "kill" command or 17213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "monitor exit"). In such a case, the valgrind process will 17223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj call exit. But a ptraced process will be blocked in exit, 17233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj waiting for the ptracing process to detach or die. vgdb 17243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cannot detach unconditionally as otherwise, in the normal 1725b2572b52b37d56d302408395f7fed9f509423af1sewardj case, the valgrind process would stop abnormally with SIGSTOP 17263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (as vgdb would not be there to catch it). vgdb can also not 17273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj die unconditionally otherwise again, similar problem. So, we 17283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj assume that most of the time, we arrive here in the normal 17293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case, and so, the breakpoint has been encountered by the 17303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind process, so the invoker thread will exit and the 17313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj join will succeed. For the "kill" case, we cause an alarm 17323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj signal to be sent after a few seconds. This means that in the 17333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj normal case, the gdbserver code in valgrind process must have 17343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj returned the control in less than the alarm nr of seconds, 1735b2572b52b37d56d302408395f7fed9f509423af1sewardj otherwise, valgrind will stop abnormally with SIGSTOP. */ 17363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (void) alarm (3); 17373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "joining with invoke_gdbserver_in_valgrind_thread\n"); 17393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj join = pthread_join(invoke_gdbserver_in_valgrind_thread, NULL); 17403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (join != 0) 17413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR 17423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (join, 17433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "vgdb error pthread_join invoke_gdbserver_in_valgrind_thread\n"); 17443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 17453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (close(from_pid) != 0) 17463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR(errno, "close from_pid\n"); 17473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 17483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Relay data between gdb and Valgrind gdbserver, till EOF or an 17503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj error is encountered. */ 17513b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 17523b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid gdb_relay (int pid) 17533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 17543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int from_pid = -1; /* fd to read from pid */ 17553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int to_pid = -1; /* fd to write to pid */ 17563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int shutdown_loop = 0; 17583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "relaying data between gdb and process %d\n", pid); 17593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fflush (stderr); 17603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (max_invoke_ms > 0) 17623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL, 17633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj invoke_gdbserver_in_valgrind, (void *) &pid); 17643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid"); 17653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj acquire_lock (shared_mem_fd, pid); 17663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from_pid = open_fifo (to_gdb_from_pid, O_RDONLY|O_NONBLOCK, 17683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "read mode from pid"); 17693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sigusr1_fd = to_pid; /* allow simulating user typing control-c */ 17713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (1) { 17733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ConnectionKind ck; 17743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int ret; 17753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct pollfd pollfds[NumConnectionKind]; 17763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* watch data written by gdb, watch POLLERR on both gdb fd */ 17783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_GDB].fd = from_gdb; 17793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_GDB].events = POLLIN; 17803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_GDB].revents = 0; 17813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_GDB].fd = to_gdb; 17823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_GDB].events = 0; 17833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_GDB].revents = 0; 17843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* watch data written by pid, watch POLLERR on both pid fd */ 17863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_PID].fd = from_pid; 17873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_PID].events = POLLIN; 17883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[FROM_PID].revents = 0; 17893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_PID].fd = to_pid; 17903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_PID].events = 0; 17913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pollfds[TO_PID].revents = 0; 17923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 17933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ret = poll(pollfds, 17943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj NumConnectionKind, 17953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (shutting_down ? 17963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 1 /* one second */ 17973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj : -1 /* infinite */)); 17983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(2, "poll ret %d errno %d\n", ret, errno); 17993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* check for unexpected error */ 18013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (ret <= 0 && errno != EINTR) { 18023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR (errno, "unexpected poll ret %d\n", ret); 18033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 18043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 18053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* check for data to read */ 18083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (ck = 0; ck < NumConnectionKind; ck ++) { 18093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pollfds[ck].revents & POLLIN) { 18103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj switch (ck) { 18113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj case FROM_GDB: 18123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!read_from_gdb_write_to_pid(to_pid)) 18133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 18143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 18151d76a80d63502951cb9cbf6f696d663f093083faphilippe case FROM_PID: 18161d76a80d63502951cb9cbf6f696d663f093083faphilippe if (!read_from_pid_write_to_gdb(from_pid)) 18171d76a80d63502951cb9cbf6f696d663f093083faphilippe shutting_down = True; 18181d76a80d63502951cb9cbf6f696d663f093083faphilippe break; 18193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj default: XERROR(0, "unexpected POLLIN on %s\n", 18203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ppConnectionKind(ck)); 18213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* check for an fd being in error condition */ 18263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (ck = 0; ck < NumConnectionKind; ck ++) { 18273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pollfds[ck].revents & POLLERR) { 18283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "connection %s fd %d POLLERR error condition\n", 18293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ppConnectionKind(ck), pollfds[ck].fd); 18303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind_dying(); 18313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 18323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pollfds[ck].revents & POLLHUP) { 18343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "connection %s fd %d POLLHUP error condition\n", 18353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ppConnectionKind(ck), pollfds[ck].fd); 18363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind_dying(); 18373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 18383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pollfds[ck].revents & POLLNVAL) { 18403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "connection %s fd %d POLLNVAL error condition\n", 18413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ppConnectionKind(ck), pollfds[ck].fd); 18423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind_dying(); 18433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 18443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shutting_down) { 18483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* we let some time to the final packets to be transferred */ 18493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutdown_loop++; 18503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (shutdown_loop > 3) 18513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 18523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 18543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj close_connection(to_pid, from_pid); 18553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 18563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18573b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic int packet_len_for_command(char *cmd) 18583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 18593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* cmd will be send as a packet $qRcmd,xxxx....................xx#cc */ 18603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return 7+ 2*strlen(cmd) +3 + 1; 18613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 18623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* hyper-minimal protocol implementation that 18643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sends the provided commands (using qRcmd packets) 18653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj and read and display their replies. */ 18663b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 18673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid standalone_send_commands(int pid, 18683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int last_command, 18693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *commands[] ) 18703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 18713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int from_pid = -1; /* fd to read from pid */ 18723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int to_pid = -1; /* fd to write to pid */ 18733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 18753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int hi; 18763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj unsigned char hex[3]; 18773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj unsigned char cksum; 18783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj unsigned char *hexcommand; 18791d76a80d63502951cb9cbf6f696d663f093083faphilippe unsigned char buf[PBUFSIZ+1]; // +1 for trailing \0 18803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int buflen; 18813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nc; 18823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 188430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (max_invoke_ms > 0 || cmd_time_out != NEVER) 18853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL, 18863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj invoke_gdbserver_in_valgrind, (void *) &pid); 18873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid"); 18893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj acquire_lock (shared_mem_fd, pid); 18903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 18913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* first send a C-c \003 to pid, so that it wakes up the process 18923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj After that, we can open the fifo from the pid in read mode 18933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj We then start to wait for packets (normally first a resume reply) 18943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj At that point, we send our command and expect replies */ 18953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buf[0] = '\003'; 18963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj write_buf(to_pid, buf, 1, "write \\003 to wake up", /* notify */ True); 18973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from_pid = open_fifo(to_gdb_from_pid, O_RDONLY, 18983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "read cmd result from pid"); 18993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (nc = 0; nc <= last_command; nc++) { 19013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "sending command %s to pid %d\n", commands[nc], pid); 19023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fflush (stderr); 19033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* prepare hexcommand $qRcmd,xxxx....................xx#cc */ 19053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj hexcommand = vmalloc (packet_len_for_command(commands[nc])); 19063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj hexcommand[0] = 0; 19073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (hexcommand, "$qRcmd,"); 19083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < strlen(commands[nc]); i++) { 19093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sprintf(hex, "%02x", commands[nc][i]); 19103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (hexcommand, hex); 19113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* checksum (but without the $) */ 19133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cksum = 0; 19143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (hi = 1; hi < strlen(hexcommand); hi++) 19153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cksum+=hexcommand[hi]; 19163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat(hexcommand, "#"); 19173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sprintf(hex, "%02x", cksum); 19183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat(hexcommand, hex); 19193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj write_buf(to_pid, hexcommand, strlen(hexcommand), 19203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "writing hex command to pid", /* notify */ True); 19213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* we exit of the below loop explicitely when the command has 19233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj been handled or because a signal handler will set 19243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down. */ 19253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while (!shutting_down) { 19263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buflen = getpkt(buf, from_pid, to_pid); 19273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buflen < 0) { 19283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR (0, "error reading packet\n"); 19293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buflen == -2) 19303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj valgrind_dying(); 19313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 19323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (strlen(buf) == 0) { 19343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(0, "empty packet rcvd (packet qRcmd not recognised?)\n"); 19353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 19363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (strcmp(buf, "OK") == 0) { 19383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "OK packet rcvd\n"); 19393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 19403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buf[0] == 'E') { 19423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(0, 19433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "E NN error packet rcvd: %s (unknown monitor command?)\n", 19443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buf); 19453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 19463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buf[0] == 'W') { 19483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(0, "W stopped packet rcvd: %s\n", buf); 19493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 19503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buf[0] == 'T') { 19523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "T resume reply packet received: %s\n", buf); 19533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj continue; 19543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* must be here an O packet with hex encoded string reply 19573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj => decode and print it */ 19583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (buf[0] != 'O') { 19593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(0, "expecting O packet, received: %s\n", buf); 19603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj continue; 19613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj { 19633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char buf_print[buflen/2 + 1]; 19643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 1; i < buflen; i = i + 2) 19653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buf_print[i/2] = (fromhex(*(buf+i)) << 4) 19663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj + fromhex(*(buf+i+1)); 19673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj buf_print[buflen/2] = 0; 19683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj printf("%s", buf_print); 19693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fflush(stdout); 19703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (hexcommand); 19733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 19743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj shutting_down = True; 19753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj close_connection(to_pid, from_pid); 19773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 19783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* report to user the existence of a vgdb-able valgrind process 19803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj with given pid */ 19813b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 198230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid report_pid (int pid, Bool on_stdout) 19833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 19843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char cmdline_file[100]; 19853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char cmdline[1000]; 19863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int fd; 19873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i, sz; 19883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 19893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sprintf(cmdline_file, "/proc/%d/cmdline", pid); 19903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fd = open (cmdline_file, O_RDONLY); 19913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fd == -1) { 19923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "error opening cmdline file %s %s\n", 19933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cmdline_file, strerror(errno)); 19943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sprintf(cmdline, "(could not obtain process command line)"); 19953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 19963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sz = read(fd, cmdline, 1000); 19973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < sz; i++) 19983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (cmdline[i] == 0) 19993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cmdline[i] = ' '; 20003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj cmdline[sz] = 0; 2001d8c12f178d9d03b934ce10d6fcb45c27503889dcsewardj close (fd); 20023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 200330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf((on_stdout ? stdout : stderr), "use --pid=%d for %s\n", pid, cmdline); 200430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fflush((on_stdout ? stdout : stderr)); 20053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 20063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 200730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* Possibly produces additional usage information documenting the 20083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ptrace restrictions. */ 20093b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 201030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardjvoid ptrace_restrictions_msg(void) 20113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 20123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# ifdef PR_SET_PTRACER 20133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *ptrace_scope_setting_file = "/proc/sys/kernel/yama/ptrace_scope"; 20143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int fd = -1; 20153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char ptrace_scope = 'X'; 20163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fd = open (ptrace_scope_setting_file, O_RDONLY, 0); 20173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fd >= 0 && (read (fd, &ptrace_scope, 1) == 1) && (ptrace_scope != '0')) { 20183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, 20193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "Note: your kernel restricts ptrace invoker using %s\n" 20203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "vgdb will only be able to attach to a Valgrind process\n" 20213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "blocked in a system call *after* an initial successful attach\n", 20223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ptrace_scope_setting_file); 20233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (ptrace_scope == 'X') { 2024d142f99836471d4245250247cc9ac7bc5a1391fasewardj DEBUG (1, 2025d142f99836471d4245250247cc9ac7bc5a1391fasewardj "PR_SET_PTRACER defined" 2026d142f99836471d4245250247cc9ac7bc5a1391fasewardj " but could not determine ptrace scope from %s\n", 2027d142f99836471d4245250247cc9ac7bc5a1391fasewardj ptrace_scope_setting_file); 20283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 20293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (fd >= 0) 20303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj close (fd); 20313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# endif 20323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 20333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# ifndef PTRACEINVOKER 20343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, 20353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "Note: ptrace invoker not implemented\n" 20363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "For more info: read user manual section" 20373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj " 'Limitations of the Valgrind gdbserver'\n"); 20383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj# endif 20393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 20403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 20413b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 20423b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid usage(void) 20433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 20443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, 20453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"Usage: vgdb [OPTION]... [[-c] COMMAND]...\n" 20463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"vgdb (valgrind gdb) has two usages\n" 20473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" 1. standalone to send monitor commands to a Valgrind gdbserver.\n" 20483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" The OPTION(s) must be followed by the command to send\n" 20493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" To send more than one command, separate the commands with -c\n" 20503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" 2. relay application between gdb and a Valgrind gdbserver.\n" 20513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" Only OPTION(s) can be given.\n" 20523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n" 20533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n" 205430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" [--wait=<number>] [--max-invoke-ms=<number>]\n" 2055992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj" [--port=<portnr>\n" 205630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" [--cmd-time-out=<number>] [-l] [-D] [-d]\n" 205730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" \n" 20583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" --pid arg must be given if multiple Valgrind gdbservers are found.\n" 20593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n" 20603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" if you want to change the default prefix for the FIFOs communication\n" 20613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" between the Valgrind gdbserver and vgdb.\n" 206230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" --wait (default 0) tells vgdb to check during the specified number\n" 20633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj" of seconds if a Valgrind gdbserver can be found.\n" 206430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n" 206530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" will force the invocation of the Valgrind gdbserver (if the Valgrind\n" 206630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" process is blocked in a system call).\n" 2067992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj" --port instructs vgdb to listen for gdb on the specified port nr.\n" 206830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n" 206930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" gdbserver has not processed a command after number seconds\n" 2070d142f99836471d4245250247cc9ac7bc5a1391fasewardj" -l arg tells to show the list of running Valgrind gdbserver and then exit.\n" 207130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" -D arg tells to show shared mem status and then exit.\n" 207230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj" -d arg tells to show debug info. Multiple -d args for more debug info\n" 2073d142f99836471d4245250247cc9ac7bc5a1391fasewardj"\n" 2074d142f99836471d4245250247cc9ac7bc5a1391fasewardj" -h --help shows this message\n" 2075d142f99836471d4245250247cc9ac7bc5a1391fasewardj" To get help from the Valgrind gdbserver, use vgdb help\n" 20763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj"\n" 20773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ); 207830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj ptrace_restrictions_msg(); 20793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 20803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 208130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj/* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated. 2082d142f99836471d4245250247cc9ac7bc5a1391fasewardj and then exits. 2083d142f99836471d4245250247cc9ac7bc5a1391fasewardj 2084d142f99836471d4245250247cc9ac7bc5a1391fasewardj else if arg_pid == -1, waits maximum check_trials seconds to discover 20853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj a valgrind pid appearing. 2086d142f99836471d4245250247cc9ac7bc5a1391fasewardj 20873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Otherwise verify arg_pid is valid and corresponds to a Valgrind process 20883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj with gdbserver activated. 20893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 20903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Returns the pid to work with 20913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj or exits in case of error (e.g. no pid found corresponding to arg_pid */ 20923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 20933b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 2094d142f99836471d4245250247cc9ac7bc5a1391fasewardjint search_arg_pid(int arg_pid, int check_trials, Bool show_list) 20953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 20963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 20973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int pid = -1; 20983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 20993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (arg_pid == 0 || arg_pid < -1) { 21003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "vgdb error: invalid pid %d given\n", arg_pid); 21013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit (1); 21023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 21033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* search for a matching named fifo. 21043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If we have been given a pid, we will check that the matching FIFO is 21053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj there (or wait the nr of check_trials for this to appear). 21063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If no pid has been given, then if we find only one FIFO, 21073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj we will use this to build the pid to use. 21083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj If we find multiple processes with valid FIFO, we report them and will 21093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit with an error. */ 21103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DIR *vgdb_dir; 21113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *vgdb_dir_name = vmalloc (strlen (vgdb_prefix) + 3); 21123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct dirent *f; 21133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int is; 21143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int nr_valid_pid = 0; 21153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const char *suffix = "-from-vgdb-to-"; /* followed by pid */ 21163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *vgdb_format = vmalloc (strlen(vgdb_prefix) + strlen(suffix) + 1); 21173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcpy (vgdb_format, vgdb_prefix); 21193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (vgdb_format, suffix); 21203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcpy (vgdb_dir_name, vgdb_prefix); 21223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (is = strlen(vgdb_prefix) - 1; is >= 0; is--) 21243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_dir_name[is] == '/') { 21253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_dir_name[is+1] = '\0'; 21263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 21273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (strlen(vgdb_dir_name) == 0) 21293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcpy (vgdb_dir_name, "./"); 21303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "searching pid in directory %s format %s\n", 21323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_dir_name, vgdb_format); 21333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* try to find FIFOs with valid pid. 21353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj On exit of the loop, pid is set to: 2136d142f99836471d4245250247cc9ac7bc5a1391fasewardj the last pid found if show_list (or -1 if no process was listed) 21373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj -1 if no FIFOs matching a running process is found 21383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj -2 if multiple FIFOs of running processes are found 21393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj otherwise it is set to the (only) pid found that can be debugged 21403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj */ 21413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i < check_trials; i++) { 21423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(1, "check_trial %d \n", i); 21433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (i > 0) 21443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* wait one second before checking again */ 21453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj sleep(1); 21463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_dir = opendir (vgdb_dir_name); 21483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (vgdb_dir == NULL) 21493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, 21503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "vgdb error: opening directory %s searching vgdb fifo\n", 21513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_dir_name); 21523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj errno = 0; /* avoid complain if vgdb_dir is empty */ 21543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj while ((f = readdir (vgdb_dir))) { 21553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj struct stat st; 21563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char pathname[strlen(vgdb_dir_name) + strlen(f->d_name)]; 21573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *wrongpid; 21583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int newpid; 21593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 21603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcpy (pathname, vgdb_dir_name); 21613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (pathname, f->d_name); 21623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(3, "trying %s\n", pathname); 21633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (stat (pathname, &st) != 0) { 21643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (debuglevel >= 3) 21653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj ERROR (errno, "vgdb error: stat %s searching vgdb fifo\n", 21663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pathname); 21673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (S_ISFIFO (st.st_mode)) { 21683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj DEBUG(3, "trying %s\n", pathname); 21693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (strncmp (pathname, vgdb_format, 21703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strlen (vgdb_format)) == 0) { 21713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj newpid = strtol(pathname + strlen (vgdb_format), 21723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj &wrongpid, 10); 2173ab8630fd1c559a3d8a3e429cf8e9f2e4b94a3ff6florian if (*wrongpid == '-' && newpid > 0 21743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj && kill (newpid, 0) == 0) { 21753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj nr_valid_pid++; 2176d142f99836471d4245250247cc9ac7bc5a1391fasewardj if (show_list) { 217730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj report_pid (newpid, /*on_stdout*/ True); 2178d142f99836471d4245250247cc9ac7bc5a1391fasewardj pid = newpid; 2179d142f99836471d4245250247cc9ac7bc5a1391fasewardj } else if (arg_pid != -1) { 21803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (arg_pid == newpid) { 21813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid = newpid; 21823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (nr_valid_pid > 1) { 21843b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (nr_valid_pid == 2) { 21853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf 21863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj (stderr, 21873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "no --pid= arg given" 21883b290486cd4cd601b20e04340e593c9ed9717e5fsewardj " and multiple valgrind pids found:\n"); 218930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj report_pid (pid, /*on_stdout*/ False); 21903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid = -2; 219230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj report_pid (newpid, /*on_stdout*/ False); 21933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 21943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj pid = newpid; 21953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 21993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj errno = 0; /* avoid complain if at the end of vgdb_dir */ 22003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 22013b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (f == NULL && errno != 0) 22023b290486cd4cd601b20e04340e593c9ed9717e5fsewardj XERROR (errno, "vgdb error: reading directory %s for vgdb fifo\n", 22033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_dir_name); 22043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj closedir (vgdb_dir); 22063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (pid != -1) 22073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj break; 22083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 22093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (vgdb_dir_name); 22113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (vgdb_format); 22123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 2213d142f99836471d4245250247cc9ac7bc5a1391fasewardj 2214d142f99836471d4245250247cc9ac7bc5a1391fasewardj if (show_list) { 2215d142f99836471d4245250247cc9ac7bc5a1391fasewardj exit (1); 2216d142f99836471d4245250247cc9ac7bc5a1391fasewardj } else if (pid == -1) { 22173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (arg_pid == -1) 22183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "vgdb error: no FIFO found and no pid given\n"); 22193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 22203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "vgdb error: no FIFO found matching pid %d\n", 22213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_pid); 22223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit (1); 22233b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 22243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else if (pid == -2) { 22253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* no arg_pid given, multiple FIFOs found */ 22263b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit (1); 22273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 22283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else { 22293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return pid; 22303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 22313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 22323b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* return true if the numeric value of an option of the 22343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj form --xxxxxxxxx=<number> could properly be extracted 22353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj from arg. If True is returned, *value contains the 22363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj extracted value.*/ 22373b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 22383b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool numeric_val(char* arg, int *value) 22393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 22403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj const char *eq_pos = strchr(arg, '='); 22413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *wrong; 224230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj long long int long_value; 22433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (eq_pos == NULL) 22453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 22463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 224730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj long_value = strtoll(eq_pos+1, &wrong, 10); 224830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (long_value < 0 || long_value > INT_MAX) 224930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj return False; 22503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (*wrong) 22513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return False; 22523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 225330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj *value = (int) long_value; 22543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return True; 22553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 22563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* true if arg matches the provided option */ 22583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 22593b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool is_opt(char* arg, char *option) 22603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 22613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int option_len = strlen(option); 22623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (option[option_len-1] == '=') 22633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return (0 == strncmp(option, arg, option_len)); 22643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj else 22653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return (0 == strcmp(option, arg)); 22663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 22673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj/* Parse command lines options. If error(s), exits. 22693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Otherwise returns the options in *p_... args. 22703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands must be big enough for the commands extracted from argv. 22713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj On return, *p_last_command gives the position in commands where 22723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj the last command has been allocated (using vmalloc). */ 22733b290486cd4cd601b20e04340e593c9ed9717e5fsewardjstatic 22743b290486cd4cd601b20e04340e593c9ed9717e5fsewardjvoid parse_options(int argc, char** argv, 22753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool *p_show_shared_mem, 2276d142f99836471d4245250247cc9ac7bc5a1391fasewardj Bool *p_show_list, 22773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int *p_arg_pid, 22783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int *p_check_trials, 2279992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj int *p_port, 22803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int *p_last_command, 22813b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *commands[]) 22823b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 22833b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool show_shared_mem = False; 2284d142f99836471d4245250247cc9ac7bc5a1391fasewardj Bool show_list = False; 22853b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int arg_pid = -1; 22863b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int check_trials = 1; 22873b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int last_command = -1; 2288992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj int int_port = 0; 22893b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22903b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 22913b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int arg_errors = 0; 22923b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 22933b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 1; i < argc; i++) { 22943b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (is_opt(argv[i], "--help") || is_opt(argv[i], "-h")) { 22953b290486cd4cd601b20e04340e593c9ed9717e5fsewardj usage(); 22963b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit(0); 22973b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "-d")) { 22983b290486cd4cd601b20e04340e593c9ed9717e5fsewardj debuglevel++; 22993b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "-D")) { 23003b290486cd4cd601b20e04340e593c9ed9717e5fsewardj show_shared_mem = True; 2301d142f99836471d4245250247cc9ac7bc5a1391fasewardj } else if (is_opt(argv[i], "-l")) { 2302d142f99836471d4245250247cc9ac7bc5a1391fasewardj show_list = True; 23033b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "--pid=")) { 23043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int newpid; 23053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!numeric_val(argv[i], &newpid)) { 230630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, "invalid --pid argument %s\n", argv[i]); 23073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (arg_pid != -1) { 230930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, "multiple --pid arguments given\n"); 23103b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 23123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_pid = newpid; 23133b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 23143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "--wait=")) { 23153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!numeric_val(argv[i], &check_trials)) { 231630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, "invalid --wait argument %s\n", argv[i]); 23173b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 23193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "--max-invoke-ms=")) { 23203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (!numeric_val(argv[i], &max_invoke_ms)) { 232130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]); 232230b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj arg_errors++; 232330b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 232430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } else if (is_opt(argv[i], "--cmd-time-out=")) { 232530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (!numeric_val(argv[i], &cmd_time_out)) { 232630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]); 23273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 2329992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } else if (is_opt(argv[i], "--port=")) { 2330992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (!numeric_val(argv[i], &int_port)) { 2331992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fprintf (stderr, "invalid --port argument %s\n", argv[i]); 2332992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj arg_errors++; 2333992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 23343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "--vgdb-prefix=")) { 23353b290486cd4cd601b20e04340e593c9ed9717e5fsewardj vgdb_prefix = argv[i] + 14; 23363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (is_opt(argv[i], "-c")) { 23373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj last_command++; 23383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands[last_command] = vmalloc (1); 23393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands[last_command][0] = '\0'; 23403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else if (0 == strncmp(argv[i], "-", 1)) { 23413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "unknown or invalid argument %s\n", argv[i]); 23423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 23443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int len; 23453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (last_command == -1) { 23463b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* only one command, no -c command indicator */ 23473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj last_command++; 23483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands[last_command] = vmalloc (1); 23493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands[last_command][0] = '\0'; 23503b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 23513b290486cd4cd601b20e04340e593c9ed9717e5fsewardj len = strlen(commands[last_command]); 23523b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands[last_command] = vrealloc (commands[last_command], 23533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj len + 1 + strlen(argv[i]) + 1); 23543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (len > 0) 23553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (commands[last_command], " "); 23563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj strcat (commands[last_command], argv[i]); 23573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (packet_len_for_command(commands[last_command]) > PBUFSIZ) { 23583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "command %s too long\n", commands[last_command]); 23593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj arg_errors++; 23603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 23613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 23623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 23633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 2364d142f99836471d4245250247cc9ac7bc5a1391fasewardj 2365b985e2de52983cafd2d17cc6c9e60064847777fdflorian if (vgdb_prefix == NULL) 2366b985e2de52983cafd2d17cc6c9e60064847777fdflorian vgdb_prefix = vgdb_prefix_default(); 2367b985e2de52983cafd2d17cc6c9e60064847777fdflorian 2368d142f99836471d4245250247cc9ac7bc5a1391fasewardj if (isatty(0) 2369d142f99836471d4245250247cc9ac7bc5a1391fasewardj && !show_shared_mem 2370d142f99836471d4245250247cc9ac7bc5a1391fasewardj && !show_list 2371992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj && int_port == 0 2372d142f99836471d4245250247cc9ac7bc5a1391fasewardj && last_command == -1) { 2373d142f99836471d4245250247cc9ac7bc5a1391fasewardj arg_errors++; 2374d142f99836471d4245250247cc9ac7bc5a1391fasewardj fprintf (stderr, 2375d142f99836471d4245250247cc9ac7bc5a1391fasewardj "Using vgdb standalone implies to give -D or -l or a COMMAND\n"); 2376d142f99836471d4245250247cc9ac7bc5a1391fasewardj } 2377d142f99836471d4245250247cc9ac7bc5a1391fasewardj 2378d142f99836471d4245250247cc9ac7bc5a1391fasewardj if (show_shared_mem && show_list) { 2379d142f99836471d4245250247cc9ac7bc5a1391fasewardj arg_errors++; 2380d142f99836471d4245250247cc9ac7bc5a1391fasewardj fprintf (stderr, 2381d142f99836471d4245250247cc9ac7bc5a1391fasewardj "Can't use both -D and -l options\n"); 2382d142f99836471d4245250247cc9ac7bc5a1391fasewardj } 2383d142f99836471d4245250247cc9ac7bc5a1391fasewardj 238430b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj if (max_invoke_ms > 0 238530b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj && cmd_time_out != NEVER 238630b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj && (cmd_time_out * 1000) <= max_invoke_ms) { 238730b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj arg_errors++; 238830b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj fprintf (stderr, 238930b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj "--max-invoke-ms must be < --cmd-time-out * 1000\n"); 239030b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj } 239130b3eca94e609214d9ac8dabfee9be3f3ab46d85sewardj 2392d142f99836471d4245250247cc9ac7bc5a1391fasewardj if (show_list && arg_pid != -1) { 2393d142f99836471d4245250247cc9ac7bc5a1391fasewardj arg_errors++; 2394d142f99836471d4245250247cc9ac7bc5a1391fasewardj fprintf (stderr, 2395d142f99836471d4245250247cc9ac7bc5a1391fasewardj "Can't use both --pid and -l options\n"); 2396d142f99836471d4245250247cc9ac7bc5a1391fasewardj } 2397d142f99836471d4245250247cc9ac7bc5a1391fasewardj 2398992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (int_port > 0 && last_command != -1) { 2399992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj arg_errors++; 2400992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj fprintf (stderr, 2401992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj "Can't use --port to send commands\n"); 2402992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj } 2403992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 24043b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (arg_errors > 0) { 24053b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf (stderr, "args error. Try `vgdb --help` for more information\n"); 24063b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit(1); 24073b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 24083b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24093b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *p_show_shared_mem = show_shared_mem; 2410d142f99836471d4245250247cc9ac7bc5a1391fasewardj *p_show_list = show_list; 24113b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *p_arg_pid = arg_pid; 24123b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *p_check_trials = check_trials; 2413992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj *p_port = int_port; 24143b290486cd4cd601b20e04340e593c9ed9717e5fsewardj *p_last_command = last_command; 24153b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 24163b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24173b290486cd4cd601b20e04340e593c9ed9717e5fsewardjint main(int argc, char** argv) 24183b290486cd4cd601b20e04340e593c9ed9717e5fsewardj{ 24193b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int i; 24203b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int pid; 24213b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24223b290486cd4cd601b20e04340e593c9ed9717e5fsewardj Bool show_shared_mem; 2423d142f99836471d4245250247cc9ac7bc5a1391fasewardj Bool show_list; 24243b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int arg_pid; 24253b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int check_trials; 2426992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj int in_port; 24273b290486cd4cd601b20e04340e593c9ed9717e5fsewardj int last_command; 24283b290486cd4cd601b20e04340e593c9ed9717e5fsewardj char *commands[argc]; // we will never have more commands than args. 24293b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24303b290486cd4cd601b20e04340e593c9ed9717e5fsewardj parse_options(argc, argv, 24313b290486cd4cd601b20e04340e593c9ed9717e5fsewardj &show_shared_mem, 2432d142f99836471d4245250247cc9ac7bc5a1391fasewardj &show_list, 24333b290486cd4cd601b20e04340e593c9ed9717e5fsewardj &arg_pid, 24343b290486cd4cd601b20e04340e593c9ed9717e5fsewardj &check_trials, 2435992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj &in_port, 24363b290486cd4cd601b20e04340e593c9ed9717e5fsewardj &last_command, 24373b290486cd4cd601b20e04340e593c9ed9717e5fsewardj commands); 24383b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24393b290486cd4cd601b20e04340e593c9ed9717e5fsewardj /* when we are working as a relay for gdb, handle some signals by 24403b290486cd4cd601b20e04340e593c9ed9717e5fsewardj only reporting them (according to debug level). Also handle these 24413b290486cd4cd601b20e04340e593c9ed9717e5fsewardj when ptrace will be used: vgdb must clean up the ptrace effect before 24423b290486cd4cd601b20e04340e593c9ed9717e5fsewardj dying. */ 24433b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (max_invoke_ms > 0 || last_command == -1) 24443b290486cd4cd601b20e04340e593c9ed9717e5fsewardj install_handlers(); 24453b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2446d142f99836471d4245250247cc9ac7bc5a1391fasewardj pid = search_arg_pid (arg_pid, check_trials, show_list); 24473b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24483b290486cd4cd601b20e04340e593c9ed9717e5fsewardj prepare_fifos_and_shared_mem(pid); 24493b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 2450992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj if (in_port > 0) 2451992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj wait_for_gdb_connect(in_port); 2452992d3cc883bd5ee2da28f2a9c307cc006cb1768bsewardj 24533b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (show_shared_mem) { 24543b290486cd4cd601b20e04340e593c9ed9717e5fsewardj fprintf(stderr, 24553b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "vgdb %d " 24563b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "written_by_vgdb %d " 24573b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "seen_by_valgrind %d\n" 24583b290486cd4cd601b20e04340e593c9ed9717e5fsewardj "vgdb pid %d\n", 24593b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_vgdb_pid, 24603b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_written_by_vgdb, 24613b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_seen_by_valgrind, 24623b290486cd4cd601b20e04340e593c9ed9717e5fsewardj VS_vgdb_pid); 24633b290486cd4cd601b20e04340e593c9ed9717e5fsewardj exit (0); 24643b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 24653b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24663b290486cd4cd601b20e04340e593c9ed9717e5fsewardj if (last_command >= 0) { 24673b290486cd4cd601b20e04340e593c9ed9717e5fsewardj standalone_send_commands(pid, last_command, commands); 24683b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } else { 24693b290486cd4cd601b20e04340e593c9ed9717e5fsewardj gdb_relay(pid); 24703b290486cd4cd601b20e04340e593c9ed9717e5fsewardj } 24713b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24723b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24733b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (from_gdb_to_pid); 24743b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (to_gdb_from_pid); 24753b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (shared_mem); 24763b290486cd4cd601b20e04340e593c9ed9717e5fsewardj 24773b290486cd4cd601b20e04340e593c9ed9717e5fsewardj for (i = 0; i <= last_command; i++) 24783b290486cd4cd601b20e04340e593c9ed9717e5fsewardj free (commands[i]); 24793b290486cd4cd601b20e04340e593c9ed9717e5fsewardj return 0; 24803b290486cd4cd601b20e04340e593c9ed9717e5fsewardj} 2481