• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*--------------------------------------------------------------------*/
2 /*--- Relay between gdb and gdbserver embedded in valgrind  vgdb.c ---*/
3 /*--------------------------------------------------------------------*/
4 
5 /*
6    This file is part of Valgrind, a dynamic binary instrumentation
7    framework.
8 
9    Copyright (C) 2011-2013 Philippe Waroquiers
10 
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2 of the
14    License, or (at your option) any later version.
15 
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24    02111-1307, USA.
25 
26    The GNU General Public License is contained in the file COPYING.
27 */
28 
29 #include "vgdb.h"
30 
31 #include "config.h"
32 
33 #include <assert.h>
34 #include <dirent.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <limits.h>
38 #include <poll.h>
39 #include <pthread.h>
40 #include <signal.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <unistd.h>
45 #include <netinet/in.h>
46 #include <sys/mman.h>
47 #include <sys/socket.h>
48 #include <sys/stat.h>
49 #include <sys/time.h>
50 
51 /* vgdb has two usages:
52    1. relay application between gdb and the gdbserver embedded in valgrind.
53    2. standalone to send monitor commands to a running valgrind-ified process
54 
55    It is made of a main program which reads arguments.  If no
56    arguments are given or only --pid and --vgdb-prefix, then usage 1 is
57    assumed.
58 
59    As relay application, vgdb reads bytes from gdb on stdin and
60    writes these bytes to valgrind.  Bytes read from valgrind are
61    written to gdb on stdout.  Read/Write from/to valgrind is done
62    using FIFOs.  There is one thread reading from stdin, writing to
63    valgrind on a FIFO.  There is one thread reading from valgrind on a
64    FIFO, writing to gdb on stdout
65 
66    As a standalone utility, vgdb builds command packets to write to valgrind,
67    sends it and reads the reply. The same two threads are used to write/read.
68    Once all the commands are sent and their replies received, vgdb will exit.
69 */
70 
71 int debuglevel;
72 struct timeval dbgtv;
73 static char *vgdb_prefix = NULL;
74 
75 /* Will be set to True when any condition indicating we have to shutdown
76    is encountered. */
77 Bool shutting_down = False;
78 
79 VgdbShared32 *shared32;
80 VgdbShared64 *shared64;
81 #define VS_written_by_vgdb (shared32 != NULL ?        \
82                             shared32->written_by_vgdb \
83                             : shared64->written_by_vgdb)
84 #define VS_seen_by_valgrind (shared32 != NULL ?         \
85                              shared32->seen_by_valgrind \
86                              : shared64->seen_by_valgrind)
87 
88 #define VS_vgdb_pid (shared32 != NULL ? shared32->vgdb_pid : shared64->vgdb_pid)
89 
vmalloc(size_t size)90 void *vmalloc(size_t size)
91 {
92    void * mem = malloc(size);
93    if (mem == NULL)
94       XERROR (errno, "can't allocate memory\n");
95    return mem;
96 }
97 
vrealloc(void * ptr,size_t size)98 void *vrealloc(void *ptr,size_t size)
99 {
100    void * mem = realloc(ptr, size);
101    if (mem == NULL)
102       XERROR (errno, "can't reallocate memory\n");
103    return mem;
104 }
105 
106 /* Return the name of a directory for temporary files. */
107 static
vgdb_tmpdir(void)108 const char *vgdb_tmpdir(void)
109 {
110    const char *tmpdir;
111 
112    tmpdir = getenv("TMPDIR");
113    if (tmpdir == NULL || *tmpdir == '\0')
114      tmpdir = VG_TMPDIR;
115    if (tmpdir == NULL || *tmpdir == '\0')
116      tmpdir = "/tmp";    /* fallback */
117 
118    return tmpdir;
119 }
120 
121 /* Return the default path prefix for the named pipes (FIFOs) used by vgdb/gdb
122    to communicate with valgrind */
123 static
vgdb_prefix_default(void)124 char *vgdb_prefix_default(void)
125 {
126    static HChar *prefix;
127 
128    if (prefix == NULL) {
129       const char *tmpdir = vgdb_tmpdir();
130       prefix = vmalloc(strlen(tmpdir) + strlen("/vgdb-pipe") + 1);
131       strcpy(prefix, tmpdir);
132       strcat(prefix, "/vgdb-pipe");
133    }
134    return prefix;
135 }
136 
137 /* add nrw to the written_by_vgdb field of shared32 or shared64 */
138 static
add_written(int nrw)139 void add_written(int nrw)
140 {
141    if (shared32 != NULL)
142       shared32->written_by_vgdb += nrw;
143    else if (shared64 != NULL)
144       shared64->written_by_vgdb += nrw;
145    else
146       assert(0);
147 }
148 
149 static int shared_mem_fd = -1;
150 static
map_vgdbshared(char * shared_mem)151 void map_vgdbshared (char* shared_mem)
152 {
153    struct stat fdstat;
154    void **s;
155    shared_mem_fd = open(shared_mem, O_RDWR);
156    /* shared_mem_fd will not be closed till vgdb exits. */
157 
158    if (shared_mem_fd == -1)
159       XERROR (errno, "error opening %s shared memory file\n", shared_mem);
160 
161    if (fstat(shared_mem_fd, &fdstat) != 0)
162       XERROR (errno, "fstat");
163 
164    if (fdstat.st_size == sizeof(VgdbShared64))
165       s = (void*) &shared64;
166    else if (fdstat.st_size == sizeof(VgdbShared32))
167       s = (void*) &shared32;
168    else
169 #if VEX_HOST_WORDSIZE == 8
170       XERROR (0,
171               "error size shared memory file %s.\n"
172               "expecting size %d (64bits) or %d (32bits) got %ld.\n",
173               shared_mem,
174               (int) sizeof(VgdbShared64), (int) sizeof(VgdbShared32),
175               (long int)fdstat.st_size);
176 #elif VEX_HOST_WORDSIZE == 4
177       XERROR (0,
178               "error size shared memory file %s.\n"
179               "expecting size %d (32bits) got %ld.\n",
180               shared_mem,
181               (int) sizeof(VgdbShared32),
182               fdstat.st_size);
183 #else
184 # error "unexpected wordsize"
185 #endif
186 
187 #if VEX_HOST_WORDSIZE == 4
188    if (shared64 != NULL)
189       XERROR (0, "cannot use 32 bits vgdb with a 64bits valgrind process\n");
190    /* But we can use a 64 bits vgdb with a 32 bits valgrind */
191 #endif
192 
193    *s = (void*) mmap (NULL, fdstat.st_size,
194                       PROT_READ|PROT_WRITE, MAP_SHARED,
195                       shared_mem_fd, 0);
196 
197    if (*s == (void *) -1)
198       XERROR (errno, "error mmap shared memory file %s\n", shared_mem);
199 
200 }
201 
202 /* This function loops till shutting_down becomes true.  In this loop,
203    it verifies if valgrind process is reading the characters written
204    by vgdb.  The verification is done every max_invoke_ms ms.  If
205    valgrind is not reading characters, it will use invoker_invoke_gdbserver
206    to ensure that the gdbserver code is called soon by valgrind. */
207 static int max_invoke_ms = 100;
208 #define NEVER 99999999
209 static int cmd_time_out = NEVER;
210 static
invoke_gdbserver_in_valgrind(void * v_pid)211 void *invoke_gdbserver_in_valgrind(void *v_pid)
212 {
213    struct timeval cmd_max_end_time;
214    Bool cmd_started = False;
215    struct timeval invoke_time;
216 
217    int pid = *(int *)v_pid;
218    int written_by_vgdb_before_sleep;
219    int seen_by_valgrind_before_sleep;
220 
221    int invoked_written = -1;
222    unsigned int usecs;
223 
224    pthread_cleanup_push(invoker_cleanup_restore_and_detach, v_pid);
225 
226    while (!shutting_down) {
227       written_by_vgdb_before_sleep = VS_written_by_vgdb;
228       seen_by_valgrind_before_sleep = VS_seen_by_valgrind;
229       DEBUG(3,
230             "written_by_vgdb_before_sleep %d "
231             "seen_by_valgrind_before_sleep %d\n",
232             written_by_vgdb_before_sleep,
233             seen_by_valgrind_before_sleep);
234       if (cmd_time_out != NEVER
235           && !cmd_started
236           && written_by_vgdb_before_sleep > seen_by_valgrind_before_sleep) {
237          /* A command was started. Record the time at which it was started. */
238          DEBUG(1, "IO for command started\n");
239          gettimeofday(&cmd_max_end_time, NULL);
240          cmd_max_end_time.tv_sec += cmd_time_out;
241          cmd_started = True;
242       }
243       if (max_invoke_ms > 0) {
244          usecs = 1000 * max_invoke_ms;
245          gettimeofday(&invoke_time, NULL);
246          invoke_time.tv_sec += max_invoke_ms / 1000;
247          invoke_time.tv_usec += 1000 * (max_invoke_ms % 1000);
248          invoke_time.tv_sec += invoke_time.tv_usec / (1000 * 1000);
249          invoke_time.tv_usec = invoke_time.tv_usec % (1000 * 1000);
250       } else {
251          usecs = 0;
252       }
253       if (cmd_started) {
254          // 0 usecs here means the thread just has to check gdbserver eats
255          // the characters in <= cmd_time_out seconds.
256          // We will just wait by 1 second max at a time.
257          if (usecs == 0 || usecs > 1000 * 1000)
258             usecs = 1000 * 1000;
259       }
260       usleep(usecs);
261 
262       /* If nothing happened during our sleep, let's try to wake up valgrind
263          or check for cmd time out. */
264       if (written_by_vgdb_before_sleep == VS_written_by_vgdb
265           && seen_by_valgrind_before_sleep == VS_seen_by_valgrind
266           && VS_written_by_vgdb > VS_seen_by_valgrind) {
267          struct timeval now;
268          gettimeofday(&now, NULL);
269          DEBUG(2,
270                "after sleep "
271                "written_by_vgdb %d "
272                "seen_by_valgrind %d "
273                "invoked_written %d\n",
274                VS_written_by_vgdb,
275                VS_seen_by_valgrind,
276                invoked_written);
277          /* if the pid does not exist anymore, we better stop */
278          if (kill(pid, 0) != 0)
279            XERROR (errno,
280                    "invoke_gdbserver_in_valgrind: "
281                    "check for pid %d existence failed\n", pid);
282          if (cmd_started) {
283             if (timercmp (&now, &cmd_max_end_time, >))
284                XERROR (0,
285                        "pid %d did not handle a command in %d seconds\n",
286                        pid, cmd_time_out);
287          }
288          if (max_invoke_ms > 0 && timercmp (&now, &invoke_time, >=)) {
289             /* only need to wake up if the nr written has changed since
290                last invoke. */
291             if (invoked_written != written_by_vgdb_before_sleep) {
292                if (invoker_invoke_gdbserver(pid)) {
293                   /* If invoke succesful, no need to invoke again
294                      for the same value of written_by_vgdb_before_sleep. */
295                   invoked_written = written_by_vgdb_before_sleep;
296                }
297             }
298          }
299       } else {
300          // Something happened => restart timer check.
301          if (cmd_time_out != NEVER) {
302             DEBUG(2, "some IO was done => restart command\n");
303             cmd_started = False;
304          }
305       }
306    }
307    pthread_cleanup_pop(0);
308    return NULL;
309 }
310 
311 static
open_fifo(const char * name,int flags,const char * desc)312 int open_fifo (const char* name, int flags, const char* desc)
313 {
314    int fd;
315    DEBUG(1, "opening %s %s\n", name, desc);
316    fd = open(name, flags);
317    if (fd == -1)
318       XERROR (errno, "error opening %s %s\n", name, desc);
319 
320    DEBUG(1, "opened %s %s fd %d\n", name, desc, fd);
321    return fd;
322 }
323 
324 /* acquire a lock on the first byte of the given fd. If not successful,
325    exits with error.
326    This allows to avoid having two vgdb speaking with the same Valgrind
327    gdbserver as this causes serious headaches to the protocol. */
328 static
acquire_lock(int fd,int valgrind_pid)329 void acquire_lock (int fd, int valgrind_pid)
330 {
331    struct flock fl;
332    fl.l_type = F_WRLCK;
333    fl.l_whence = SEEK_SET;
334    fl.l_start = 0;
335    fl.l_len = 1;
336    if (fcntl(fd, F_SETLK, &fl) < 0) {
337       if (errno == EAGAIN || errno == EACCES) {
338          XERROR(errno,
339                 "Cannot acquire lock.\n"
340                 "Probably vgdb pid %d already speaks with Valgrind pid %d\n",
341                 VS_vgdb_pid,
342                 valgrind_pid);
343       } else {
344          XERROR(errno, "cannot acquire lock.\n");
345       }
346    }
347 
348    /* Here, we have the lock. It will be released when fd will be closed. */
349    /* We indicate our pid to Valgrind gdbserver */
350    if (shared32 != NULL)
351       shared32->vgdb_pid = getpid();
352    else if (shared64 != NULL)
353       shared64->vgdb_pid = getpid();
354    else
355       assert(0);
356 }
357 
358 #define PBUFSIZ 16384 /* keep in sync with server.h */
359 
360 /* read some characters from fd.
361    Returns the nr of characters read, -1 if error.
362    desc is a string used in tracing */
363 static
read_buf(int fd,char * buf,const char * desc)364 int read_buf (int fd, char* buf, const char* desc)
365 {
366    int nrread;
367    DEBUG(2, "reading %s\n", desc);
368    nrread = read(fd, buf, PBUFSIZ);
369    if (nrread == -1) {
370       ERROR (errno, "error reading %s\n", desc);
371       return -1;
372    }
373    buf[nrread] = '\0';
374    DEBUG(2, "read %s %s\n", desc, buf);
375    return nrread;
376 }
377 
378 /* write size bytes from buf to fd.
379    desc is a description of the action for which the write is done.
380    If notify, then add size to the shared cntr indicating to the
381    valgrind process that there is new data.
382    Returns True if write is ok, False if there was a problem. */
383 static
write_buf(int fd,char * buf,int size,const char * desc,Bool notify)384 Bool write_buf(int fd, char* buf, int size, const char* desc, Bool notify)
385 {
386    int nrwritten;
387    int nrw;
388    DEBUG(2, "writing %s len %d %.*s notify: %d\n", desc, size,
389          size, buf, notify);
390    nrwritten = 0;
391    while (nrwritten < size) {
392       nrw = write (fd, buf+nrwritten, size - nrwritten);
393       if (nrw == -1) {
394          ERROR(errno, "error write %s\n", desc);
395          return False;
396       }
397       nrwritten = nrwritten + nrw;
398       if (notify)
399          add_written(nrw);
400    }
401    return True;
402 }
403 
404 typedef enum {
405    FROM_GDB,
406    TO_GDB,
407    FROM_PID,
408    TO_PID } ConnectionKind;
409 static const int NumConnectionKind = TO_PID+1;
410 static
ppConnectionKind(ConnectionKind con)411 const char *ppConnectionKind (ConnectionKind con)
412 {
413    switch (con) {
414    case FROM_GDB: return "FROM_GDB";
415    case TO_GDB:   return "TO_GDB";
416    case FROM_PID: return "FROM_PID";
417    case TO_PID:   return "TO_PID";
418    default:       return "invalid connection kind";
419    }
420 }
421 
422 static char *shared_mem;
423 
424 static int from_gdb = 0; /* stdin by default, changed if --port is given. */
425 static char *from_gdb_to_pid; /* fifo name to write gdb command to pid */
426 /* Returns True in case read/write operations were done properly.
427    Returns False in case of error.
428    to_pid is the file descriptor to write to the process pid. */
429 static
read_from_gdb_write_to_pid(int to_pid)430 Bool read_from_gdb_write_to_pid(int to_pid)
431 {
432    char buf[PBUFSIZ+1]; // +1 for trailing \0
433    int nrread;
434 
435    nrread = read_buf(from_gdb, buf, "from gdb on stdin");
436    if (nrread <= 0) {
437       if (nrread == 0)
438          DEBUG(1, "read 0 bytes from gdb => assume exit\n");
439       else
440          DEBUG(1, "error reading bytes from gdb\n");
441       close (from_gdb);
442       shutting_down = True;
443       return False;
444    }
445    return write_buf(to_pid, buf, nrread, "to_pid", /* notify */ True);
446 }
447 
448 static int to_gdb = 1; /* stdout by default, changed if --port is given. */
449 static char *to_gdb_from_pid; /* fifo name to read pid replies */
450 /* Returns True in case read/write operations were done properly.
451    Returns False in case of error.
452    from_pid is the file descriptor to read data from the process pid. */
453 static
read_from_pid_write_to_gdb(int from_pid)454 Bool read_from_pid_write_to_gdb(int from_pid)
455 {
456    char buf[PBUFSIZ+1]; // +1 for trailing \0
457    int nrread;
458 
459    nrread = read_buf(from_pid, buf, "from pid");
460    if (nrread <= 0) {
461       if (nrread == 0)
462          DEBUG(1, "read 0 bytes from pid => assume exit\n");
463       else
464          DEBUG(1, "error reading bytes from pid\n");
465       close (from_pid);
466       shutting_down = True;
467       return False;
468    }
469    return write_buf(to_gdb, buf, nrread, "to_gdb", /* notify */ False);
470 }
471 
472 static
wait_for_gdb_connect(int in_port)473 void wait_for_gdb_connect (int in_port)
474 {
475    struct sockaddr_in addr;
476 
477    int listen_gdb = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
478    int gdb_connect;
479 
480    if (-1 == listen_gdb) {
481       XERROR(errno, "cannot create socket");
482    }
483 
484     memset(&addr, 0, sizeof(addr));
485 
486     addr.sin_family = AF_INET;
487     addr.sin_port = htons((unsigned short int)in_port);
488     addr.sin_addr.s_addr = INADDR_ANY;
489 
490     if (-1 == bind(listen_gdb,(struct sockaddr *)&addr, sizeof(addr))) {
491       XERROR(errno, "bind failed");
492     }
493     fprintf(stderr, "listening on port %d ...", in_port);
494     fflush(stderr);
495     if (-1 == listen(listen_gdb, 1)) {
496       XERROR(errno, "error listen failed");
497     }
498 
499     gdb_connect = accept(listen_gdb, NULL, NULL);
500     if (gdb_connect < 0) {
501         XERROR(errno, "accept failed");
502     }
503     fprintf(stderr, "connected.\n");
504     fflush(stderr);
505     close(listen_gdb);
506     from_gdb = gdb_connect;
507     to_gdb = gdb_connect;
508 }
509 
510 /* prepares the FIFOs filenames, map the shared memory. */
511 static
prepare_fifos_and_shared_mem(int pid)512 void prepare_fifos_and_shared_mem(int pid)
513 {
514    const HChar *user, *host;
515    unsigned len;
516 
517    user = getenv("LOGNAME");
518    if (user == NULL) user = getenv("USER");
519    if (user == NULL) user = "???";
520    if (strchr(user, '/')) user = "???";
521 
522    host = getenv("HOST");
523    if (host == NULL) host = getenv("HOSTNAME");
524    if (host == NULL) host = "???";
525    if (strchr(host, '/')) host = "???";
526 
527    len = strlen(vgdb_prefix) + strlen(user) + strlen(host) + 40;
528    from_gdb_to_pid = vmalloc (len);
529    to_gdb_from_pid = vmalloc (len);
530    shared_mem      = vmalloc (len);
531    /* below 3 lines must match the equivalent in remote-utils.c */
532    sprintf(from_gdb_to_pid, "%s-from-vgdb-to-%d-by-%s-on-%s",    vgdb_prefix,
533            pid, user, host);
534    sprintf(to_gdb_from_pid, "%s-to-vgdb-from-%d-by-%s-on-%s",    vgdb_prefix,
535            pid, user, host);
536    sprintf(shared_mem,      "%s-shared-mem-vgdb-%d-by-%s-on-%s", vgdb_prefix,
537            pid, user, host);
538    DEBUG (1, "vgdb: using %s %s %s\n",
539           from_gdb_to_pid, to_gdb_from_pid, shared_mem);
540 
541    map_vgdbshared(shared_mem);
542 }
543 
544 /* Convert hex digit A to a number.  */
545 
546 static int
fromhex(int a)547 fromhex (int a)
548 {
549    if (a >= '0' && a <= '9')
550       return a - '0';
551    else if (a >= 'a' && a <= 'f')
552       return a - 'a' + 10;
553    else
554       XERROR(0, "Reply contains invalid hex digit %c\n", a);
555   return 0;
556 }
557 
558 /* Returns next char from fd.  -1 if error, -2 if EOF.
559    NB: must always call it with the same fd */
560 static int
readchar(int fd)561 readchar (int fd)
562 {
563   static char buf[PBUFSIZ+1]; // +1 for trailing \0
564   static int bufcnt = 0;
565   static unsigned char *bufp;
566   // unsigned bufp to e.g. avoid having 255 converted to int -1
567 
568   if (bufcnt-- > 0)
569      return *bufp++;
570 
571   bufcnt = read_buf (fd, buf, "static buf readchar");
572 
573   if (bufcnt <= 0) {
574      if (bufcnt == 0) {
575         fprintf (stderr, "readchar: Got EOF\n");
576         return -2;
577      } else {
578         ERROR (errno, "readchar\n");
579         return -1;
580      }
581   }
582 
583   bufp = (unsigned char *)buf;
584   bufcnt--;
585   return *bufp++;
586 }
587 
588 /* Read a packet from fromfd, with error checking,
589    and store it in BUF.
590    Returns length of packet, or -1 if error or -2 if EOF.
591    Writes ack on ackfd */
592 
593 static int
getpkt(char * buf,int fromfd,int ackfd)594 getpkt (char *buf, int fromfd, int ackfd)
595 {
596   char *bp;
597   unsigned char csum, c1, c2;
598   int c;
599 
600   while (1) {
601      csum = 0;
602 
603      while (1) {
604         c = readchar (fromfd);
605         if (c == '$')
606            break;
607         DEBUG(2, "[getpkt: discarding char '%c']\n", c);
608         if (c < 0)
609            return c;
610      }
611 
612      bp = buf;
613      while (1) {
614         c = readchar (fromfd);
615         if (c < 0)
616            return c;
617         if (c == '#')
618            break;
619         if (c == '*') {
620            int repeat;
621            int r;
622            int prev;
623            prev = *(bp-1);
624            csum += c;
625            repeat = readchar (fromfd);
626            csum += repeat;
627            for (r = 0; r < repeat - 29; r ++)
628               *bp++ = prev;
629         } else {
630            *bp++ = c;
631            csum += c;
632         }
633      }
634      *bp = 0;
635 
636      c1 = fromhex (readchar (fromfd));
637      c2 = fromhex (readchar (fromfd));
638 
639      if (csum == (c1 << 4) + c2)
640 	break;
641 
642      fprintf (stderr, "Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
643               (c1 << 4) + c2, csum, buf);
644      if (write (ackfd, "-", 1) != 1)
645         ERROR(0, "error when writing - (nack)\n");
646      else
647         add_written(1);
648   }
649 
650   DEBUG(2, "getpkt (\"%s\");  [sending ack] \n", buf);
651   if (write (ackfd, "+", 1) != 1)
652      ERROR(0, "error when writing + (ack)\n");
653   else
654      add_written(1);
655   return bp - buf;
656 }
657 
658 static int sigint = 0;
659 static int sigterm = 0;
660 static int sigpipe = 0;
661 static int sighup = 0;
662 static int sigusr1 = 0;
663 static int sigalrm = 0;
664 static int sigusr1_fd = -1;
665 static pthread_t invoke_gdbserver_in_valgrind_thread;
666 
667 static
received_signal(int signum)668 void received_signal (int signum)
669 {
670    if (signum == SIGINT)
671       sigint++;
672    else if (signum == SIGUSR1) {
673       sigusr1++;
674       if (sigusr1_fd >= 0) {
675          char control_c = '\003';
676          write_buf(sigusr1_fd, &control_c, 1,
677                    "write \\003 on SIGUSR1", /* notify */ True);
678       }
679    }
680    else if (signum == SIGTERM) {
681       shutting_down = True;
682       sigterm++;
683    } else if (signum == SIGHUP) {
684       shutting_down = True;
685       sighup++;
686    } else if (signum == SIGPIPE) {
687       sigpipe++;
688    } else if (signum == SIGALRM) {
689       sigalrm++;
690 #if defined(__ANDROID__)
691       /* Android has no pthread_cancel. As it also does not have
692          an invoker implementation, there is no need for cleanup action.
693          So, we just do nothing. */
694       DEBUG(1, "sigalrm received, no action on android\n");
695 #else
696       /* Note: we cannot directly invoke restore_and_detach : this must
697          be done by the thread that has attached.
698          We have in this thread pushed a cleanup handler that will
699          cleanup what is needed. */
700       DEBUG(1, "pthread_cancel invoke_gdbserver_in_valgrind_thread\n");
701       pthread_cancel(invoke_gdbserver_in_valgrind_thread);
702 #endif
703    } else {
704       ERROR(0, "unexpected signal %d\n", signum);
705    }
706 }
707 
708 /* install the signal handlers allowing e.g. vgdb to cleanup in
709    case of termination. */
710 static
install_handlers(void)711 void install_handlers(void)
712 {
713    struct sigaction action, oldaction;
714 
715    action.sa_handler = received_signal;
716    sigemptyset (&action.sa_mask);
717    action.sa_flags = 0;
718 
719    /* SIGINT: when user types C-c in gdb, this sends
720       a SIGINT to vgdb + causes a character to be sent to remote gdbserver.
721       The later is enough to wakeup the valgrind process. */
722    if (sigaction (SIGINT, &action, &oldaction) != 0)
723       XERROR (errno, "vgdb error sigaction SIGINT\n");
724    /* We might do something more intelligent than just
725       reporting this SIGINT E.g. behave similarly to the gdb: two
726       control-C without feedback from the debugged process would
727       mean to stop debugging it. */
728 
729    /* SIGUSR1: this is used to facilitate automatic testing.  When
730       vgdb receives this signal, it will simulate the user typing C-c. */
731    if (sigaction (SIGUSR1, &action, &oldaction) != 0)
732       XERROR (errno, "vgdb error sigaction SIGUSR1\n");
733 
734 
735    /* SIGTERM: can receive this signal (e.g. from gdb) to terminate vgdb
736       when detaching or similar. A clean shutdown will be done as both
737       the read and write side will detect an end of file. */
738    if (sigaction (SIGTERM, &action, &oldaction) != 0)
739       XERROR (errno, "vgdb error sigaction SIGTERM\n");
740 
741    /* SIGPIPE: can receive this signal when gdb detaches or kill the
742       process debugged: gdb will close its pipes to vgdb. vgdb
743       must resist to this signal to allow a clean shutdown. */
744    if (sigaction (SIGPIPE, &action, &oldaction) != 0)
745       XERROR (errno, "vgdb error sigaction SIGPIPE\n");
746 
747    /* SIGALRM: in case invoke thread is blocked, alarm is used
748       to cleanup.  */
749    if (sigaction (SIGALRM, &action, &oldaction) != 0)
750       XERROR (errno, "vgdb error sigaction SIGALRM\n");
751 
752    /* unmask all signals, in case the process that launched vgdb
753       masked some. */
754    if (sigprocmask (SIG_SETMASK, &action.sa_mask, NULL) != 0)
755       XERROR (errno, "vgdb error sigprocmask");
756 }
757 
758 /* close the FIFOs provided connections, terminate the invoker thread.  */
759 static
close_connection(int to_pid,int from_pid)760 void close_connection(int to_pid, int from_pid)
761 {
762    DEBUG(1, "nr received signals: sigint %d sigterm %d sighup %d sigpipe %d\n",
763          sigint, sigterm, sighup, sigpipe);
764    /* Note that we do not forward sigterm to the valgrind process:
765       a sigterm signal is (probably) received from gdb if the user wants to
766       kill the debugged process. The kill instruction has been given to
767       the valgrind process, which should execute a clean exit. */
768 
769    /* We first close the connection to pid. The pid will then
770       terminates its gdbserver work. We keep the from pid
771       fifo opened till the invoker thread is finished.
772       This allows the gdbserver to finish sending its last reply. */
773    if (close(to_pid) != 0)
774       ERROR(errno, "close to_pid\n");
775 
776    /* if there is a task that was busy trying to wake up valgrind
777       process, we wait for it to be terminated otherwise threads
778       in the valgrind process can stay stopped if vgdb main
779       exits before the invoke thread had time to detach from
780       all valgrind threads. */
781    if (max_invoke_ms > 0 || cmd_time_out != NEVER) {
782       int join;
783 
784       /* It is surprisingly complex to properly shutdown or exit the
785          valgrind process in which gdbserver has been invoked through
786          ptrace.  In the normal case (gdb detaches from the process,
787          or process is continued), the valgrind process will reach the
788          breakpoint place.  Using ptrace, vgdb will ensure the
789          previous activity of the process is resumed (e.g. restart a
790          blocking system call).  The special case is when gdb asks the
791          valgrind process to exit (using either the "kill" command or
792          "monitor exit").  In such a case, the valgrind process will
793          call exit.  But a ptraced process will be blocked in exit,
794          waiting for the ptracing process to detach or die. vgdb
795          cannot detach unconditionally as otherwise, in the normal
796          case, the valgrind process would stop abnormally with SIGSTOP
797          (as vgdb would not be there to catch it). vgdb can also not
798          die unconditionally otherwise again, similar problem.  So, we
799          assume that most of the time, we arrive here in the normal
800          case, and so, the breakpoint has been encountered by the
801          valgrind process, so the invoker thread will exit and the
802          join will succeed.  For the "kill" case, we cause an alarm
803          signal to be sent after a few seconds. This means that in the
804          normal case, the gdbserver code in valgrind process must have
805          returned the control in less than the alarm nr of seconds,
806          otherwise, valgrind will stop abnormally with SIGSTOP. */
807       (void) alarm (3);
808 
809       DEBUG(1, "joining with invoke_gdbserver_in_valgrind_thread\n");
810       join = pthread_join(invoke_gdbserver_in_valgrind_thread, NULL);
811       if (join != 0)
812          XERROR
813             (join,
814              "vgdb error pthread_join invoke_gdbserver_in_valgrind_thread\n");
815    }
816    if (close(from_pid) != 0)
817       ERROR(errno, "close from_pid\n");
818 }
819 
820 /* Relay data between gdb and Valgrind gdbserver, till EOF or an
821    error is encountered. */
822 static
gdb_relay(int pid)823 void gdb_relay (int pid)
824 {
825    int from_pid = -1; /* fd to read from pid */
826    int to_pid = -1; /* fd to write to pid */
827 
828    int shutdown_loop = 0;
829    fprintf (stderr, "relaying data between gdb and process %d\n", pid);
830    fflush (stderr);
831 
832    if (max_invoke_ms > 0)
833       pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
834                      invoke_gdbserver_in_valgrind, (void *) &pid);
835    to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
836    acquire_lock (shared_mem_fd, pid);
837 
838    from_pid = open_fifo (to_gdb_from_pid, O_RDONLY|O_NONBLOCK,
839                          "read mode from pid");
840 
841    sigusr1_fd = to_pid; /* allow simulating user typing control-c */
842 
843    while (1) {
844       ConnectionKind ck;
845       int ret;
846       struct pollfd pollfds[NumConnectionKind];
847 
848       /* watch data written by gdb, watch POLLERR on both gdb fd */
849       pollfds[FROM_GDB].fd = from_gdb;
850       pollfds[FROM_GDB].events = POLLIN;
851       pollfds[FROM_GDB].revents = 0;
852       pollfds[TO_GDB].fd = to_gdb;
853       pollfds[TO_GDB].events = 0;
854       pollfds[TO_GDB].revents = 0;
855 
856       /* watch data written by pid, watch POLLERR on both pid fd */
857       pollfds[FROM_PID].fd = from_pid;
858       pollfds[FROM_PID].events = POLLIN;
859       pollfds[FROM_PID].revents = 0;
860       pollfds[TO_PID].fd = to_pid;
861       pollfds[TO_PID].events = 0;
862       pollfds[TO_PID].revents = 0;
863 
864       ret = poll(pollfds,
865                  NumConnectionKind,
866                  (shutting_down ?
867                   1 /* one second */
868                   : -1 /* infinite */));
869       DEBUG(2, "poll ret %d errno %d\n", ret, errno);
870 
871       /* check for unexpected error */
872       if (ret <= 0 && errno != EINTR) {
873          ERROR (errno, "unexpected poll ret %d\n", ret);
874          shutting_down = True;
875          break;
876       }
877 
878       /* check for data to read */
879       for (ck = 0; ck < NumConnectionKind; ck ++) {
880          if (pollfds[ck].revents & POLLIN) {
881             switch (ck) {
882             case FROM_GDB:
883                if (!read_from_gdb_write_to_pid(to_pid))
884                   shutting_down = True;
885                break;
886             case FROM_PID:
887                if (!read_from_pid_write_to_gdb(from_pid))
888                   shutting_down = True;
889                break;
890             default: XERROR(0, "unexpected POLLIN on %s\n",
891                                ppConnectionKind(ck));
892             }
893          }
894       }
895 
896       /* check for an fd being in error condition */
897       for (ck = 0; ck < NumConnectionKind; ck ++) {
898          if (pollfds[ck].revents & POLLERR) {
899             DEBUG(1, "connection %s fd %d POLLERR error condition\n",
900                      ppConnectionKind(ck), pollfds[ck].fd);
901             invoker_valgrind_dying();
902             shutting_down = True;
903          }
904          if (pollfds[ck].revents & POLLHUP) {
905             DEBUG(1, "connection %s fd %d POLLHUP error condition\n",
906                   ppConnectionKind(ck), pollfds[ck].fd);
907             invoker_valgrind_dying();
908             shutting_down = True;
909          }
910          if (pollfds[ck].revents & POLLNVAL) {
911             DEBUG(1, "connection %s fd %d POLLNVAL error condition\n",
912                   ppConnectionKind(ck), pollfds[ck].fd);
913             invoker_valgrind_dying();
914             shutting_down = True;
915          }
916       }
917 
918       if (shutting_down) {
919          /* we let some time to the final packets to be transferred */
920          shutdown_loop++;
921          if (shutdown_loop > 3)
922             break;
923       }
924    }
925    close_connection(to_pid, from_pid);
926 }
927 
packet_len_for_command(char * cmd)928 static int packet_len_for_command(char *cmd)
929 {
930    /* cmd will be send as a packet $qRcmd,xxxx....................xx#cc      */
931    return                          7+     2*strlen(cmd)             +3  + 1;
932 }
933 
934 /* hyper-minimal protocol implementation that
935    sends the provided commands (using qRcmd packets)
936    and read and display their replies. */
937 static
standalone_send_commands(int pid,int last_command,char * commands[])938 void standalone_send_commands(int pid,
939                               int last_command,
940                               char *commands[] )
941 {
942    int from_pid = -1; /* fd to read from pid */
943    int to_pid = -1; /* fd to write to pid */
944 
945    int i;
946    int hi;
947    char hex[3];
948    unsigned char cksum;
949    char *hexcommand;
950    char buf[PBUFSIZ+1]; // +1 for trailing \0
951    int buflen;
952    int nc;
953 
954 
955    if (max_invoke_ms > 0 || cmd_time_out != NEVER)
956       pthread_create(&invoke_gdbserver_in_valgrind_thread, NULL,
957                      invoke_gdbserver_in_valgrind, (void *) &pid);
958 
959    to_pid = open_fifo(from_gdb_to_pid, O_WRONLY, "write to pid");
960    acquire_lock (shared_mem_fd, pid);
961 
962    /* first send a C-c \003 to pid, so that it wakes up the process
963       After that, we can open the fifo from the pid in read mode
964       We then start to wait for packets (normally first a resume reply)
965       At that point, we send our command and expect replies */
966    buf[0] = '\003';
967    i = 0;
968    while (!write_buf(to_pid, buf, 1,
969                      "write \\003 to wake up", /* notify */ True)) {
970       /* If write fails, retries up to 10 times every 0.5 seconds
971          This aims at solving the race condition described in
972          remote-utils.c remote_finish function. */
973       usleep(500*1000);
974       i++;
975       if (i >= 10)
976          XERROR (errno, "failed to send wake up char after 10 trials\n");
977    }
978    from_pid = open_fifo(to_gdb_from_pid, O_RDONLY,
979                         "read cmd result from pid");
980 
981    for (nc = 0; nc <= last_command; nc++) {
982       fprintf (stderr, "sending command %s to pid %d\n", commands[nc], pid);
983       fflush (stderr);
984 
985       /* prepare hexcommand $qRcmd,xxxx....................xx#cc      */
986       hexcommand = vmalloc (packet_len_for_command(commands[nc]));
987       hexcommand[0] = 0;
988       strcat (hexcommand, "$qRcmd,");
989       for (i = 0; i < strlen(commands[nc]); i++) {
990          sprintf(hex, "%02x", (unsigned char) commands[nc][i]);
991          // Need to use unsigned char, to avoid sign extension.
992          strcat (hexcommand, hex);
993       }
994       /* checksum (but without the $) */
995       cksum = 0;
996       for (hi = 1; hi < strlen(hexcommand); hi++)
997          cksum+=hexcommand[hi];
998       strcat(hexcommand, "#");
999       sprintf(hex, "%02x", cksum);
1000       strcat(hexcommand, hex);
1001       write_buf(to_pid, hexcommand, strlen(hexcommand),
1002                 "writing hex command to pid", /* notify */ True);
1003 
1004       /* we exit of the below loop explicitely when the command has
1005          been handled or because a signal handler will set
1006          shutting_down. */
1007       while (!shutting_down) {
1008          buflen = getpkt(buf, from_pid, to_pid);
1009          if (buflen < 0) {
1010             ERROR (0, "error reading packet\n");
1011             if (buflen == -2)
1012                invoker_valgrind_dying();
1013             break;
1014          }
1015          if (strlen(buf) == 0) {
1016             DEBUG(0, "empty packet rcvd (packet qRcmd not recognised?)\n");
1017             break;
1018          }
1019          if (strcmp(buf, "OK") == 0) {
1020             DEBUG(1, "OK packet rcvd\n");
1021             break;
1022          }
1023          if (buf[0] == 'E') {
1024             DEBUG(0,
1025                   "E NN error packet rcvd: %s (unknown monitor command?)\n",
1026                   buf);
1027             break;
1028          }
1029          if (buf[0] == 'W') {
1030             DEBUG(0, "W stopped packet rcvd: %s\n", buf);
1031             break;
1032          }
1033          if (buf[0] == 'T') {
1034             DEBUG(1, "T resume reply packet received: %s\n", buf);
1035             continue;
1036          }
1037 
1038          /* must be here an O packet with hex encoded string reply
1039             => decode and print it */
1040          if (buf[0] != 'O') {
1041             DEBUG(0, "expecting O packet, received: %s\n", buf);
1042             continue;
1043          }
1044          {
1045             char buf_print[buflen/2 + 1];
1046             for (i = 1; i < buflen; i = i + 2)
1047                buf_print[i/2] = (fromhex(*(buf+i)) << 4)
1048                      + fromhex(*(buf+i+1));
1049             buf_print[buflen/2] = 0;
1050             printf("%s", buf_print);
1051             fflush(stdout);
1052          }
1053       }
1054       free (hexcommand);
1055    }
1056    shutting_down = True;
1057 
1058    close_connection(to_pid, from_pid);
1059 }
1060 
1061 /* report to user the existence of a vgdb-able valgrind process
1062    with given pid.
1063    Note: this function does not use XERROR if an error is encountered
1064    while producing the command line for pid, as this is not critical
1065    and at least on MacOS, reading cmdline is not available. */
1066 static
report_pid(int pid,Bool on_stdout)1067 void report_pid (int pid, Bool on_stdout)
1068 {
1069    char cmdline_file[50];   // large enough
1070    int fd, i;
1071    FILE *out = on_stdout ? stdout : stderr;
1072 
1073    fprintf(out, "use --pid=%d for ", pid);
1074 
1075    sprintf(cmdline_file, "/proc/%d/cmdline", pid);
1076    fd = open (cmdline_file, O_RDONLY);
1077    if (fd == -1) {
1078       DEBUG(1, "error opening cmdline file %s %s\n",
1079             cmdline_file, strerror(errno));
1080       fprintf(out, "(could not open process command line)\n");
1081    } else {
1082       char cmdline[100];
1083       ssize_t sz;
1084       while ((sz = read(fd, cmdline, sizeof cmdline - 1)) != 0) {
1085          for (i = 0; i < sz; i++)
1086             if (cmdline[i] == 0)
1087                cmdline[i] = ' ';
1088          cmdline[sz] = 0;
1089          fprintf(out, "%s", cmdline);
1090       }
1091       if (sz == -1) {
1092          DEBUG(1, "error reading cmdline file %s %s\n",
1093                cmdline_file, strerror(errno));
1094          fprintf(out, "(error reading process command line)");
1095       }
1096       fprintf(out, "\n");
1097       close (fd);
1098    }
1099    fflush(out);
1100 }
1101 
1102 static
usage(void)1103 void usage(void)
1104 {
1105    fprintf(stderr,
1106 "Usage: vgdb [OPTION]... [[-c] COMMAND]...\n"
1107 "vgdb (valgrind gdb) has two usages\n"
1108 "  1. standalone to send monitor commands to a Valgrind gdbserver.\n"
1109 "     The OPTION(s) must be followed by the command to send\n"
1110 "     To send more than one command, separate the commands with -c\n"
1111 "  2. relay application between gdb and a Valgrind gdbserver.\n"
1112 "     Only OPTION(s) can be given.\n"
1113 "\n"
1114 " OPTIONS are [--pid=<number>] [--vgdb-prefix=<prefix>]\n"
1115 "             [--wait=<number>] [--max-invoke-ms=<number>]\n"
1116 "             [--port=<portnr>\n"
1117 "             [--cmd-time-out=<number>] [-l] [-D] [-d]\n"
1118 "             \n"
1119 "  --pid arg must be given if multiple Valgrind gdbservers are found.\n"
1120 "  --vgdb-prefix arg must be given to both Valgrind and vgdb utility\n"
1121 "      if you want to change the prefix (default %s) for the FIFOs communication\n"
1122 "      between the Valgrind gdbserver and vgdb.\n"
1123 "  --wait (default 0) tells vgdb to check during the specified number\n"
1124 "      of seconds if a Valgrind gdbserver can be found.\n"
1125 "  --max-invoke-ms (default 100) gives the nr of milli-seconds after which vgdb\n"
1126 "      will force the invocation of the Valgrind gdbserver (if the Valgrind\n"
1127 "         process is blocked in a system call).\n"
1128 "  --port instructs vgdb to listen for gdb on the specified port nr.\n"
1129 "  --cmd-time-out (default 99999999) tells vgdb to exit if the found Valgrind\n"
1130 "     gdbserver has not processed a command after number seconds\n"
1131 "  -l  arg tells to show the list of running Valgrind gdbserver and then exit.\n"
1132 "  -D  arg tells to show shared mem status and then exit.\n"
1133 "  -d  arg tells to show debug info. Multiple -d args for more debug info\n"
1134 "\n"
1135 "  -h --help shows this message\n"
1136 "  To get help from the Valgrind gdbserver, use vgdb help\n"
1137 "\n", vgdb_prefix_default()
1138            );
1139    invoker_restrictions_msg();
1140 }
1141 
1142 /* If show_list, outputs on stdout the list of Valgrind processes with gdbserver activated.
1143                  and then exits.
1144 
1145    else if arg_pid == -1, waits maximum check_trials seconds to discover
1146    a valgrind pid appearing.
1147 
1148    Otherwise verify arg_pid is valid and corresponds to a Valgrind process
1149    with gdbserver activated.
1150 
1151    Returns the pid to work with
1152    or exits in case of error (e.g. no pid found corresponding to arg_pid */
1153 
1154 static
search_arg_pid(int arg_pid,int check_trials,Bool show_list)1155 int search_arg_pid(int arg_pid, int check_trials, Bool show_list)
1156 {
1157    int i;
1158    int pid = -1;
1159 
1160    if (arg_pid == 0 || arg_pid < -1) {
1161       fprintf (stderr, "vgdb error: invalid pid %d given\n", arg_pid);
1162       exit (1);
1163    } else {
1164       /* search for a matching named fifo.
1165          If we have been given a pid, we will check that the matching FIFO is
1166          there (or wait the nr of check_trials for this to appear).
1167          If no pid has been given, then if we find only one FIFO,
1168          we will use this to build the pid to use.
1169          If we find multiple processes with valid FIFO, we report them and will
1170          exit with an error. */
1171       DIR *vgdb_dir;
1172       char *vgdb_dir_name = vmalloc (strlen (vgdb_prefix) + 3);
1173       struct dirent *f;
1174       int is;
1175       int nr_valid_pid = 0;
1176       const char *suffix = "-from-vgdb-to-"; /* followed by pid */
1177       char *vgdb_format = vmalloc (strlen(vgdb_prefix) + strlen(suffix) + 1);
1178 
1179       strcpy (vgdb_format, vgdb_prefix);
1180       strcat (vgdb_format, suffix);
1181 
1182       if (strchr(vgdb_prefix, '/') != NULL) {
1183          strcpy (vgdb_dir_name, vgdb_prefix);
1184          for (is = strlen(vgdb_prefix) - 1; is >= 0; is--)
1185             if (vgdb_dir_name[is] == '/') {
1186                vgdb_dir_name[is+1] = '\0';
1187                break;
1188             }
1189       } else {
1190          strcpy (vgdb_dir_name, "");
1191       }
1192 
1193       DEBUG(1, "searching pid in directory %s format %s\n",
1194             vgdb_dir_name, vgdb_format);
1195 
1196       /* try to find FIFOs with valid pid.
1197          On exit of the loop, pid is set to:
1198          the last pid found if show_list (or -1 if no process was listed)
1199          -1 if no FIFOs matching a running process is found
1200          -2 if multiple FIFOs of running processes are found
1201          otherwise it is set to the (only) pid found that can be debugged
1202       */
1203       for (i = 0; i < check_trials; i++) {
1204          DEBUG(1, "check_trial %d \n", i);
1205          if (i > 0)
1206            /* wait one second before checking again */
1207            sleep(1);
1208 
1209          vgdb_dir = opendir (strlen (vgdb_dir_name) ? vgdb_dir_name : "./");
1210          if (vgdb_dir == NULL)
1211             XERROR (errno,
1212                     "vgdb error: opening directory %s searching vgdb fifo\n",
1213                     vgdb_dir_name);
1214 
1215          errno = 0; /* avoid complain if vgdb_dir is empty */
1216          while ((f = readdir (vgdb_dir))) {
1217             struct stat st;
1218             char pathname[strlen(vgdb_dir_name) + strlen(f->d_name) + 1];
1219             char *wrongpid;
1220             int newpid;
1221 
1222             strcpy (pathname, vgdb_dir_name);
1223             strcat (pathname, f->d_name);
1224             DEBUG(3, "checking pathname is FIFO %s\n", pathname);
1225             if (stat (pathname, &st) != 0) {
1226                if (debuglevel >= 3)
1227                   ERROR (errno, "vgdb error: stat %s searching vgdb fifo\n",
1228                          pathname);
1229             } else if (S_ISFIFO (st.st_mode)) {
1230                DEBUG(3, "trying FIFO %s\n", pathname);
1231                if (strncmp (pathname, vgdb_format,
1232                             strlen (vgdb_format)) == 0) {
1233                   newpid = strtol(pathname + strlen (vgdb_format),
1234                                   &wrongpid, 10);
1235                   if (*wrongpid == '-' && newpid > 0
1236                       && kill (newpid, 0) == 0) {
1237                      nr_valid_pid++;
1238                      if (show_list) {
1239                         report_pid (newpid, /*on_stdout*/ True);
1240                         pid = newpid;
1241                      } else if (arg_pid != -1) {
1242                         if (arg_pid == newpid) {
1243                            pid = newpid;
1244                         }
1245                      } else if (nr_valid_pid > 1) {
1246                         if (nr_valid_pid == 2) {
1247                            fprintf
1248                               (stderr,
1249                                "no --pid= arg given"
1250                                " and multiple valgrind pids found:\n");
1251                            report_pid (pid, /*on_stdout*/ False);
1252                         }
1253                         pid = -2;
1254                         report_pid (newpid, /*on_stdout*/ False);
1255                      } else {
1256                         pid = newpid;
1257                      }
1258                   }
1259                }
1260             }
1261             errno = 0; /* avoid complain if at the end of vgdb_dir */
1262          }
1263          if (f == NULL && errno != 0)
1264             XERROR (errno, "vgdb error: reading directory %s for vgdb fifo\n",
1265                     vgdb_dir_name);
1266 
1267          closedir (vgdb_dir);
1268          if (pid != -1)
1269             break;
1270       }
1271 
1272       free (vgdb_dir_name);
1273       free (vgdb_format);
1274    }
1275 
1276    if (show_list) {
1277       exit (1);
1278    } else if (pid == -1) {
1279       if (arg_pid == -1)
1280          fprintf (stderr, "vgdb error: no FIFO found and no pid given\n");
1281       else
1282          fprintf (stderr, "vgdb error: no FIFO found matching pid %d\n",
1283                   arg_pid);
1284       exit (1);
1285    }
1286    else if (pid == -2) {
1287       /* no arg_pid given, multiple FIFOs found */
1288       exit (1);
1289    }
1290    else {
1291       return pid;
1292    }
1293 }
1294 
1295 /* return true if the numeric value of an option of the
1296    form --xxxxxxxxx=<number> could properly be extracted
1297    from arg. If True is returned, *value contains the
1298    extracted value.*/
1299 static
numeric_val(char * arg,int * value)1300 Bool numeric_val(char* arg, int *value)
1301 {
1302    const char *eq_pos = strchr(arg, '=');
1303    char *wrong;
1304    long long int long_value;
1305 
1306    if (eq_pos == NULL)
1307       return False;
1308 
1309    long_value = strtoll(eq_pos+1, &wrong, 10);
1310    if (long_value < 0 || long_value > INT_MAX)
1311       return False;
1312    if (*wrong)
1313       return False;
1314 
1315    *value = (int) long_value;
1316    return True;
1317 }
1318 
1319 /* true if arg matches the provided option */
1320 static
is_opt(char * arg,const char * option)1321 Bool is_opt(char* arg, const char *option)
1322 {
1323    int option_len = strlen(option);
1324    if (option[option_len-1] == '=')
1325       return (0 == strncmp(option, arg, option_len));
1326    else
1327       return (0 == strcmp(option, arg));
1328 }
1329 
1330 /* Parse command lines options. If error(s), exits.
1331    Otherwise returns the options in *p_... args.
1332    commands must be big enough for the commands extracted from argv.
1333    On return, *p_last_command gives the position in commands where
1334    the last command has been allocated (using vmalloc). */
1335 static
parse_options(int argc,char ** argv,Bool * p_show_shared_mem,Bool * p_show_list,int * p_arg_pid,int * p_check_trials,int * p_port,int * p_last_command,char * commands[])1336 void parse_options(int argc, char** argv,
1337                    Bool *p_show_shared_mem,
1338                    Bool *p_show_list,
1339                    int *p_arg_pid,
1340                    int *p_check_trials,
1341                    int *p_port,
1342                    int *p_last_command,
1343                    char *commands[])
1344 {
1345    Bool show_shared_mem = False;
1346    Bool show_list = False;
1347    int arg_pid = -1;
1348    int check_trials = 1;
1349    int last_command = -1;
1350    int int_port = 0;
1351 
1352    int i;
1353    int arg_errors = 0;
1354 
1355    for (i = 1; i < argc; i++) {
1356       if (is_opt(argv[i], "--help") || is_opt(argv[i], "-h")) {
1357          usage();
1358          exit(0);
1359       } else if (is_opt(argv[i], "-d")) {
1360          debuglevel++;
1361       } else if (is_opt(argv[i], "-D")) {
1362          show_shared_mem = True;
1363       } else if (is_opt(argv[i], "-l")) {
1364          show_list = True;
1365       } else if (is_opt(argv[i], "--pid=")) {
1366          int newpid;
1367          if (!numeric_val(argv[i], &newpid)) {
1368             fprintf (stderr, "invalid --pid argument %s\n", argv[i]);
1369             arg_errors++;
1370          } else if (arg_pid != -1) {
1371             fprintf (stderr, "multiple --pid arguments given\n");
1372             arg_errors++;
1373          } else {
1374             arg_pid = newpid;
1375          }
1376       } else if (is_opt(argv[i], "--wait=")) {
1377          if (!numeric_val(argv[i], &check_trials)) {
1378             fprintf (stderr, "invalid --wait argument %s\n", argv[i]);
1379             arg_errors++;
1380          }
1381       } else if (is_opt(argv[i], "--max-invoke-ms=")) {
1382          if (!numeric_val(argv[i], &max_invoke_ms)) {
1383             fprintf (stderr, "invalid --max-invoke-ms argument %s\n", argv[i]);
1384             arg_errors++;
1385          }
1386       } else if (is_opt(argv[i], "--cmd-time-out=")) {
1387          if (!numeric_val(argv[i], &cmd_time_out)) {
1388             fprintf (stderr, "invalid --cmd-time-out argument %s\n", argv[i]);
1389             arg_errors++;
1390          }
1391       } else if (is_opt(argv[i], "--port=")) {
1392          if (!numeric_val(argv[i], &int_port)) {
1393             fprintf (stderr, "invalid --port argument %s\n", argv[i]);
1394             arg_errors++;
1395          }
1396       } else if (is_opt(argv[i], "--vgdb-prefix=")) {
1397          vgdb_prefix = argv[i] + 14;
1398       } else if (is_opt(argv[i], "-c")) {
1399          last_command++;
1400          commands[last_command] = vmalloc (1);
1401          commands[last_command][0] = '\0';
1402       } else if (0 == strncmp(argv[i], "-", 1)) {
1403          fprintf (stderr, "unknown or invalid argument %s\n", argv[i]);
1404          arg_errors++;
1405       } else {
1406          int len;
1407          if (last_command == -1) {
1408             /* only one command, no -c command indicator */
1409             last_command++;
1410             commands[last_command] = vmalloc (1);
1411             commands[last_command][0] = '\0';
1412          }
1413          len = strlen(commands[last_command]);
1414          commands[last_command] = vrealloc (commands[last_command],
1415                                             len + 1 + strlen(argv[i]) + 1);
1416          if (len > 0)
1417             strcat (commands[last_command], " ");
1418          strcat (commands[last_command], argv[i]);
1419          if (packet_len_for_command(commands[last_command]) > PBUFSIZ) {
1420             fprintf (stderr, "command %s too long\n", commands[last_command]);
1421             arg_errors++;
1422          }
1423 
1424       }
1425    }
1426 
1427    if (vgdb_prefix == NULL)
1428       vgdb_prefix = vgdb_prefix_default();
1429 
1430    if (isatty(0)
1431        && !show_shared_mem
1432        && !show_list
1433        && int_port == 0
1434        && last_command == -1) {
1435       arg_errors++;
1436       fprintf (stderr,
1437                "Using vgdb standalone implies to give -D or -l or a COMMAND\n");
1438    }
1439 
1440    if (show_shared_mem && show_list) {
1441       arg_errors++;
1442       fprintf (stderr,
1443                "Can't use both -D and -l options\n");
1444    }
1445 
1446    if (max_invoke_ms > 0
1447        && cmd_time_out != NEVER
1448        && (cmd_time_out * 1000) <= max_invoke_ms) {
1449       arg_errors++;
1450       fprintf (stderr,
1451                "--max-invoke-ms must be < --cmd-time-out * 1000\n");
1452    }
1453 
1454    if (show_list && arg_pid != -1) {
1455       arg_errors++;
1456       fprintf (stderr,
1457                "Can't use both --pid and -l options\n");
1458    }
1459 
1460    if (int_port > 0 && last_command != -1) {
1461       arg_errors++;
1462       fprintf (stderr,
1463                "Can't use --port to send commands\n");
1464    }
1465 
1466    if (arg_errors > 0) {
1467       fprintf (stderr, "args error. Try `vgdb --help` for more information\n");
1468       exit(1);
1469    }
1470 
1471    *p_show_shared_mem = show_shared_mem;
1472    *p_show_list = show_list;
1473    *p_arg_pid = arg_pid;
1474    *p_check_trials = check_trials;
1475    *p_port = int_port;
1476    *p_last_command = last_command;
1477 }
1478 
main(int argc,char ** argv)1479 int main(int argc, char** argv)
1480 {
1481    int i;
1482    int pid;
1483 
1484    Bool show_shared_mem;
1485    Bool show_list;
1486    int arg_pid;
1487    int check_trials;
1488    int in_port;
1489    int last_command;
1490    char *commands[argc]; // we will never have more commands than args.
1491 
1492    parse_options(argc, argv,
1493                  &show_shared_mem,
1494                  &show_list,
1495                  &arg_pid,
1496                  &check_trials,
1497                  &in_port,
1498                  &last_command,
1499                  commands);
1500 
1501    /* when we are working as a relay for gdb, handle some signals by
1502       only reporting them (according to debug level). Also handle these
1503       when ptrace will be used: vgdb must clean up the ptrace effect before
1504       dying. */
1505    if (max_invoke_ms > 0 || last_command == -1)
1506       install_handlers();
1507 
1508    pid = search_arg_pid (arg_pid, check_trials, show_list);
1509 
1510    prepare_fifos_and_shared_mem(pid);
1511 
1512    if (in_port > 0)
1513       wait_for_gdb_connect(in_port);
1514 
1515    if (show_shared_mem) {
1516       fprintf(stderr,
1517               "vgdb %d "
1518               "written_by_vgdb %d "
1519               "seen_by_valgrind %d\n"
1520               "vgdb pid %d\n",
1521               VS_vgdb_pid,
1522               VS_written_by_vgdb,
1523               VS_seen_by_valgrind,
1524               VS_vgdb_pid);
1525       exit (0);
1526    }
1527 
1528    if (last_command >= 0) {
1529       standalone_send_commands(pid, last_command, commands);
1530    } else {
1531       gdb_relay(pid);
1532    }
1533 
1534 
1535    free (from_gdb_to_pid);
1536    free (to_gdb_from_pid);
1537    free (shared_mem);
1538 
1539    for (i = 0; i <= last_command; i++)
1540       free (commands[i]);
1541    return 0;
1542 }
1543