doxygen
[oweals/gnunet.git] / src / monkey / gdbmi_connect.c
1 /**[txh]********************************************************************
2
3   Copyright (c) 2004-2009 by Salvador E. Tropea.
4   Covered by the GPL license.
5
6   Module: Connect.
7   Comments:
8   This module handles the dialog with gdb, including starting and stopping
9 gdb.
10   @<p>
11
12 GDB Bug workaround for "file -readnow": I tried to workaround a bug using
13 it but looks like this option also have bugs!!!! so I have to use the
14 command line option --readnow.
15 It also have a bug!!!! when the binary is changed and gdb must reload it
16 this option is ignored. So it looks like we have no solution but 3 gdb bugs
17 in a row.
18
19 ***************************************************************************/
20
21 #include "platform.h"
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <sys/wait.h>
27 #include <fcntl.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <limits.h>
31 #include <errno.h>
32 #include <signal.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35
36 #include "gdbmi.h"
37 #ifndef _GNU_SOURCE
38 #define _GNU_SOURCE
39 #endif
40
41 #ifndef TEMP_FAILURE_RETRY
42  #define TEMP_FAILURE_RETRY(a) (a)
43 #endif
44
45 int mi_error=MI_OK;
46 char *mi_error_from_gdb=NULL;
47 static char *gdb_exe=NULL;
48 static char *xterm_exe=NULL;
49 static char *gdb_start=NULL;
50 static char *gdb_conn=NULL;
51 static char *main_func=NULL;
52 static char  disable_psym_search_workaround=0;
53
54 mi_h *mi_alloc_h()
55 {
56  mi_h *h=(mi_h *)calloc(1,sizeof(mi_h));
57  if (!h)
58    {
59     mi_error=MI_OUT_OF_MEMORY;
60     return NULL;
61    }
62  h->to_gdb[0]=h->to_gdb[1]=h->from_gdb[0]=h->from_gdb[1]=-1;
63  h->pid=-1;
64  return h;
65 }
66
67 int mi_check_running_pid(pid_t pid)
68 {
69  int status;
70
71  if (pid<=0)
72     return 0;
73  /* If waitpid returns the number of our child means it communicated
74     to as a termination status. */
75  if (waitpid(pid,&status,WNOHANG)==pid)
76    {
77     pid=0;
78     return 0;
79    }
80  return 1;
81 }
82
83 int mi_check_running(mi_h *h)
84 {
85  return !h->died && mi_check_running_pid(h->pid);
86 }
87
88 void mi_kill_child(pid_t pid)
89 {
90  kill(pid,SIGTERM);
91  usleep(100000);
92  if (mi_check_running_pid(pid))
93    {
94     int status;
95     kill(pid,SIGKILL);
96     waitpid(pid,&status,0);
97    }
98 }
99
100 void mi_free_h(mi_h **handle)
101 {
102  mi_h *h=*handle;
103  if (h->to_gdb[0]>=0)
104     close(h->to_gdb[0]);
105  if (h->to)
106     fclose(h->to);
107  else if (h->to_gdb[1]>=0)
108     close(h->to_gdb[1]);
109  if (h->from)
110     fclose(h->from);
111  else if (h->from_gdb[0]>=0)
112     close(h->from_gdb[0]);
113  if (h->from_gdb[1]>=0)
114     close(h->from_gdb[1]);
115  if (mi_check_running(h))
116    {/* GDB is running! */
117     mi_kill_child(h->pid);
118    }
119  if (h->line)
120     free(h->line);
121  mi_free_output(h->po);
122  free(h->catched_console);
123  free(h);
124  *handle=NULL;
125 }
126
127 void mi_set_nonblk(int h)
128 {
129  int flf;
130  flf=fcntl(h,F_GETFL,0);
131  flf=flf | O_NONBLOCK;
132  fcntl(h,F_SETFL,flf);
133 }
134
135 int mi_getline(mi_h *h)
136 {
137  char c;
138
139  while (read(h->from_gdb[0],&c,1)==1)
140    {
141     if (h->lread>=h->llen)
142       {
143        h->llen=h->lread+128;
144        h->line=(char *)realloc(h->line,h->llen);
145        if (!h->line)
146          {
147           h->llen=0;
148           h->lread=0;
149           return -1;
150          }
151       }
152     if (c=='\n')
153       {
154        int ret=h->lread;
155        h->line[ret]=0;
156        h->lread=0;
157        return ret;
158       }
159     h->line[h->lread]=c;
160     h->lread++;
161    }
162  return 0;
163 }
164
165 char *get_cstr(mi_output *o)
166 {
167  if (!o->c || o->c->type!=t_const)
168     return NULL;
169  return o->c->v.cstr;
170 }
171
172 int mi_get_response(mi_h *h)
173 {
174  int l=mi_getline(h);
175  if (!l)
176     return 0;
177
178  if (h->from_gdb_echo)
179     h->from_gdb_echo(h->line,h->from_gdb_echo_data);
180  if (strncmp(h->line,"(gdb)",5)==0)
181    {/* End of response. */
182     return 1;
183    }
184  else
185    {/* Add to the response. */
186     mi_output *o;
187     int add=1, is_exit=0;
188     o=mi_parse_gdb_output(h->line);
189
190     if (!o)
191        return 0;
192     /* Tunneled streams callbacks. */
193     if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_STREAM)
194       {
195        char *aux;
196        add=0;
197        switch (o->sstype)
198          {
199           case MI_SST_CONSOLE:
200                aux=get_cstr(o);
201                if (h->console)
202                   h->console(aux,h->console_data);
203                if (h->catch_console && aux)
204                  {
205                   h->catch_console--;
206                   if (!h->catch_console)
207                     {
208                      free(h->catched_console);
209                      h->catched_console=strdup(aux);
210                     }
211                  }
212                break;
213           case MI_SST_TARGET:
214                /* This one seems to be useless. */
215                if (h->target)
216                   h->target(get_cstr(o),h->target_data);
217                break;
218           case MI_SST_LOG:
219                if (h->log)
220                   h->log(get_cstr(o),h->log_data);
221                break;
222          }
223       }
224     else if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_ASYNC)
225       {
226        if (h->async)
227           h->async(o,h->async_data);
228       }
229     else if (o->type==MI_T_RESULT_RECORD && o->tclass==MI_CL_ERROR)
230       {/* Error from gdb, record it. */
231        mi_error=MI_FROM_GDB;
232        free(mi_error_from_gdb);
233        mi_error_from_gdb=NULL;
234        if (o->c && strcmp(o->c->var,"msg")==0 && o->c->type==t_const)
235           mi_error_from_gdb=strdup(o->c->v.cstr);
236       }
237     is_exit=(o->type==MI_T_RESULT_RECORD && o->tclass==MI_CL_EXIT);
238     /* Add to the list of responses. */
239     if (add)
240       {
241        if (h->last)
242           h->last->next=o;
243        else
244           h->po=o;
245        h->last=o;
246       }
247     else
248        mi_free_output(o);
249     /* Exit RR means gdb exited, we won't get a new prompt ;-) */
250     if (is_exit)
251        return 1;
252    }
253
254  return 0;
255 }
256
257 mi_output *mi_retire_response(mi_h *h)
258 {
259  mi_output *ret=h->po;
260  h->po=h->last=NULL;
261  return ret;
262 }
263
264 mi_output *mi_get_response_blk(mi_h *h)
265 {
266  int r;
267  /* Sometimes gdb dies. */
268  if (!mi_check_running(h))
269    {
270     h->died=1;
271     mi_error=MI_GDB_DIED;
272     return NULL;
273    }
274  do
275    {
276     if (1)
277       {
278        /*
279         That's a must. If we just keep trying to read and failing things
280         become really sloooowwww. Instead we try and if it fails we wait
281         until something is available.
282         TODO: Implement something with the time out, a callback to ask the
283         application is we have to wait or not could be a good thing.
284        */
285        fd_set set;
286        struct timeval timeout;
287        int ret;
288
289        r=mi_get_response(h);
290        if (r)
291           return mi_retire_response(h);
292
293        FD_ZERO(&set);
294        FD_SET(h->from_gdb[0],&set);
295        timeout.tv_sec=h->time_out;
296        timeout.tv_usec=0;
297        ret=TEMP_FAILURE_RETRY(select(FD_SETSIZE,&set,NULL,NULL,&timeout));
298        if (!ret)
299          {
300           if (!mi_check_running(h))
301             {
302              h->died=1;
303              mi_error=MI_GDB_DIED;
304              return NULL;
305             }
306           if (h->time_out_cb)
307              ret=h->time_out_cb(h->time_out_cb_data);
308           if (!ret)
309             {
310              mi_error=MI_GDB_TIME_OUT;
311              return NULL;
312             }
313          }
314       }
315     else
316       {
317        r=mi_get_response(h);
318        if (r)
319           return mi_retire_response(h);
320        else
321           usleep(100);
322       }
323    }
324  while (!r);
325
326  return NULL;
327 }
328
329 void mi_send_commands(mi_h *h, const char *file)
330 {
331  FILE *f;
332  char b[PATH_MAX];
333
334  //printf("File: %s\n",file);
335  if (!file)
336     return;
337  f=fopen(file,"rt");
338  if (!f)
339     return;
340  while (!feof(f))
341    {
342     if (fgets(b,PATH_MAX,f))
343       {
344        //printf("Send: %s\n",b);
345        mi_send(h,b);
346        mi_res_simple_done(h);
347       }
348    }
349  fclose(f);
350 }
351
352 void mi_send_target_commands(mi_h *h)
353 {
354  mi_send_commands(h,gdb_conn);
355 }
356
357 /**[txh]********************************************************************
358
359   Description:
360   Connect to a local copy of gdb. Note that the mi_h structure is something
361 similar to a "FILE *" for stdio.
362   
363   Return: A new mi_h structure or NULL on error.
364   
365 ***************************************************************************/
366
367 mi_h *mi_connect_local()
368 {
369  mi_h *h;
370  const char *gdb=mi_get_gdb_exe();
371
372  /* Start without error. */
373  mi_error=MI_OK;
374  /* Verify we have a GDB binary. */
375  if (access(gdb,X_OK))
376    {
377     mi_error=MI_MISSING_GDB;
378     return NULL;
379    }
380  /* Alloc the handle structure. */
381  h=mi_alloc_h();
382  if (!h)
383     return h;
384  h->time_out=MI_DEFAULT_TIME_OUT;
385  /* Create the pipes to connect with the child. */
386  if (pipe(h->to_gdb) || pipe(h->from_gdb))
387    {
388     mi_error=MI_PIPE_CREATE;
389     mi_free_h(&h);
390     return NULL;
391    }
392  mi_set_nonblk(h->to_gdb[1]);
393  mi_set_nonblk(h->from_gdb[0]);
394  /* Associate streams to the file handles. */
395  h->to=fdopen(h->to_gdb[1],"w");
396  h->from=fdopen(h->from_gdb[0],"r");
397  if (!h->to || !h->from)
398    {
399     mi_error=MI_PIPE_CREATE;
400     mi_free_h(&h);
401     return NULL;
402    }
403  /* Create the child. */
404  h->pid=fork();
405  if (h->pid==0)
406    {/* We are the child. */
407     char *argv[5];
408     /* Connect stdin/out to the pipes. */
409     dup2(h->to_gdb[0],STDIN_FILENO);
410     dup2(h->from_gdb[1],STDOUT_FILENO);
411     /* Pass the control to gdb. */
412     argv[0]=(char *)gdb; /* Is that OK? */
413     argv[1]="--interpreter=mi";
414     argv[2]="--quiet";
415     argv[3]=disable_psym_search_workaround ? 0 : "--readnow";
416     argv[4]=0;
417     execvp(argv[0],argv);
418     /* We get here only if exec failed. */
419     _exit(127);
420    }
421  /* We are the parent. */
422  if (h->pid==-1)
423    {/* Fork failed. */
424     mi_error=MI_FORK;
425     mi_free_h(&h);
426     return NULL;
427    }
428  if (!mi_check_running(h))
429    {
430     mi_error=MI_DEBUGGER_RUN;
431     mi_free_h(&h);
432     return NULL;
433    }
434  /* Wait for the prompt. */
435  mi_get_response_blk(h);
436  /* Send the start-up commands */
437  mi_send_commands(h,gdb_start);
438
439  return h;
440 }
441
442 /**[txh]********************************************************************
443
444   Description:
445   Close connection. You should ask gdb to quit first gmi_gdb_exit.
446   
447 ***************************************************************************/
448
449 void mi_disconnect(mi_h *h)
450 {
451  mi_free_h(&h);
452  free(mi_error_from_gdb);
453  mi_error_from_gdb=NULL;
454 }
455
456 void mi_set_console_cb(mi_h *h, stream_cb cb, void *data)
457 {
458  h->console=cb;
459  h->console_data=data;
460 }
461
462 void mi_set_target_cb(mi_h *h, stream_cb cb, void *data)
463 {
464  h->target=cb;
465  h->target_data=data;
466 }
467
468 void mi_set_log_cb(mi_h *h, stream_cb cb, void *data)
469 {
470  h->log=cb;
471  h->log_data=data;
472 }
473
474 stream_cb mi_get_console_cb(mi_h *h, void **data)
475 {
476  if (data)
477     *data=h->console_data;
478  return h->console;
479 }
480
481 stream_cb mi_get_target_cb(mi_h *h, void **data)
482 {
483  if (data)
484     *data=h->target_data;
485  return h->target;
486 }
487
488 stream_cb mi_get_log_cb(mi_h *h, void **data)
489 {
490  if (data)
491     *data=h->log_data;
492  return h->log;
493 }
494
495 void mi_set_async_cb(mi_h *h, async_cb cb, void *data)
496 {
497  h->async=cb;
498  h->async_data=data;
499 }
500
501 async_cb mi_get_async_cb(mi_h *h, void **data)
502 {
503  if (data)
504     *data=h->async_data;
505  return h->async;
506 }
507
508 void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data)
509 {
510  h->to_gdb_echo=cb;
511  h->to_gdb_echo_data=data;
512 }
513
514 void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data)
515 {
516  h->from_gdb_echo=cb;
517  h->from_gdb_echo_data=data;
518 }
519
520 stream_cb mi_get_to_gdb_cb(mi_h *h, void **data)
521 {
522  if (data)
523     *data=h->to_gdb_echo_data;
524  return h->to_gdb_echo;
525 }
526
527 stream_cb mi_get_from_gdb_cb(mi_h *h, void **data)
528 {
529  if (data)
530     *data=h->from_gdb_echo_data;
531  return h->from_gdb_echo;
532 }
533
534 void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data)
535 {
536  h->time_out_cb=cb;
537  h->time_out_cb_data=data;
538 }
539
540 tm_cb mi_get_time_out_cb(mi_h *h, void **data)
541 {
542  if (data)
543     *data=h->time_out_cb_data;
544  return h->time_out_cb;
545 }
546
547 void mi_set_time_out(mi_h *h, int to)
548 {
549  h->time_out=to;
550 }
551
552 int mi_get_time_out(mi_h *h)
553 {
554  return h->time_out;
555 }
556
557 int mi_send(mi_h *h, const char *format, ...)
558 {
559  int ret;
560  char *str;
561  va_list argptr;
562
563  if (h->died)
564     return 0;
565
566  va_start(argptr,format);
567  ret=vasprintf(&str,format,argptr);
568  va_end(argptr);
569  fputs(str,h->to);
570  fflush(h->to);
571  if (h->to_gdb_echo)
572     h->to_gdb_echo(str,h->to_gdb_echo_data);
573  free(str);
574
575  return ret;
576 }
577
578 void mi_clean_up_globals()
579 {
580  free(gdb_exe);
581  gdb_exe=NULL;
582  free(xterm_exe);
583  xterm_exe=NULL;
584  free(gdb_start);
585  gdb_start=NULL;
586  free(gdb_conn);
587  gdb_conn=NULL;
588  free(main_func);
589  main_func=NULL;
590 }
591
592 void mi_register_exit()
593 {
594  static int registered=0;
595  if (!registered)
596    {
597     registered=1;
598     atexit(mi_clean_up_globals);
599    }
600 }
601
602 void mi_set_gdb_exe(const char *name)
603 {
604  free(gdb_exe);
605  gdb_exe=name ? strdup(name) : NULL;
606  mi_register_exit();
607 }
608
609 void mi_set_gdb_start(const char *name)
610 {
611  free(gdb_start);
612  gdb_start=name ? strdup(name) : NULL;
613  mi_register_exit();
614 }
615
616 void mi_set_gdb_conn(const char *name)
617 {
618  free(gdb_conn);
619  gdb_conn=name ? strdup(name) : NULL;
620  mi_register_exit();
621 }
622
623 static
624 char *mi_search_in_path(const char *file)
625 {
626  char *path, *pt, *r;
627  char test[PATH_MAX];
628  struct stat st;
629
630  path=getenv("PATH");
631  if (!path)
632     return NULL;
633  pt=strdup(path);
634  r=strtok(pt,PATH_SEPARATOR_STR);
635  while (r)
636    {
637     strcpy(test,r);
638     strcat(test,"/");
639     strcat(test,file);
640     if (stat(test,&st)==0 && S_ISREG(st.st_mode))
641       {
642        free(pt);
643        return strdup(test);
644       }
645     r=strtok(NULL,PATH_SEPARATOR_STR);
646    }
647  free(pt);
648  return NULL;
649 }
650
651 const char *mi_get_gdb_exe()
652 {
653  if (!gdb_exe)
654    {/* Look for gdb in path */
655     gdb_exe=mi_search_in_path("gdb");
656     if (!gdb_exe)
657        return "/usr/bin/gdb";
658    }
659  return gdb_exe;
660 }
661
662 const char *mi_get_gdb_start()
663 {
664  return gdb_start;
665 }
666
667 const char *mi_get_gdb_conn()
668 {
669  return gdb_conn;
670 }
671
672 void mi_set_xterm_exe(const char *name)
673 {
674  free(xterm_exe);
675  xterm_exe=name ? strdup(name) : NULL;
676  mi_register_exit();
677 }
678
679 const char *mi_get_xterm_exe()
680 {
681  if (!xterm_exe)
682    {/* Look for xterm in path */
683     xterm_exe=mi_search_in_path("xterm");
684     if (!xterm_exe)
685        return "/usr/bin/X11/xterm";
686    }
687  return xterm_exe;
688 }
689
690 void mi_set_main_func(const char *name)
691 {
692  free(main_func);
693  main_func=name ? strdup(name) : NULL;
694  mi_register_exit();
695 }
696
697 const char *mi_get_main_func()
698 {
699  if (main_func)
700     return main_func;
701  return "main";
702 }
703
704 /**[txh]********************************************************************
705
706   Description:
707   Opens a new xterm to be used by the child process to debug.
708   
709   Return: A new mi_aux_term structure, you can use gmi_end_aux_term to
710 release it.
711   
712 ***************************************************************************/
713
714 mi_aux_term *gmi_start_xterm()
715 {
716  char nsh[14]="/tmp/shXXXXXX";
717  char ntt[14]="/tmp/ttXXXXXX";
718  const char *xterm;
719  struct stat st;
720  int hsh, htt=-1;
721  mi_aux_term *res=NULL;
722  FILE *f;
723  pid_t pid;
724  char buf[PATH_MAX];
725
726  /* Verify we have an X terminal. */
727  xterm=mi_get_xterm_exe();
728  if (access(xterm,X_OK))
729    {
730     mi_error=MI_MISSING_XTERM;
731     return NULL;
732    }
733
734  /* Create 2 temporals. */
735  hsh=mkstemp(nsh);
736  if (hsh==-1)
737    {
738     mi_error=MI_CREATE_TEMPORAL;
739     return NULL;
740    }
741  htt=mkstemp(ntt);
742  if (htt==-1)
743    {
744     close(hsh);
745     unlink(nsh);
746     mi_error=MI_CREATE_TEMPORAL;
747     return NULL;
748    }
749  close(htt);
750  /* Create the script. */
751  f=fdopen(hsh,"w");
752  if (!f)
753    {
754     close(hsh);
755     unlink(nsh);
756     unlink(ntt);
757     mi_error=MI_CREATE_TEMPORAL;
758     return NULL;
759    }
760  fprintf(f,"#!/bin/sh\n");
761  fprintf(f,"tty > %s\n",ntt);
762  fprintf(f,"rm %s\n",nsh);
763  fprintf(f,"sleep 365d\n");
764  fclose(f);
765  /* Spawn xterm. */
766  /* Create the child. */
767  pid=fork();
768  if (pid==0)
769    {/* We are the child. */
770     char *argv[5];
771     /* Pass the control to gdb. */
772     argv[0]=(char *)mi_get_xterm_exe(); /* Is that ok? */
773     argv[1]="-e";
774     argv[2]="/bin/sh";
775     argv[3]=nsh;
776     argv[4]=0;
777     execvp(argv[0],argv);
778     /* We get here only if exec failed. */
779     unlink(nsh);
780     unlink(ntt);
781     _exit(127);
782    }
783  /* We are the parent. */
784  if (pid==-1)
785    {/* Fork failed. */
786     unlink(nsh);
787     unlink(ntt);
788     mi_error=MI_FORK;
789     return NULL;
790    }
791  /* Wait until the shell is deleted. */
792  while (stat(nsh,&st)==0)
793    usleep(1000);
794  /* Try to read the tty name. */
795  f=fopen(ntt,"rt");
796  if (f)
797    {
798     if (fgets(buf,PATH_MAX,f))
799       {
800        char *s; /* Strip the \n. */
801        for (s=buf; *s && *s!='\n'; s++);
802        *s=0;
803        res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
804        if (res)
805          {
806           res->pid=pid;
807           res->tty=strdup(buf);
808          }
809       }
810     fclose(f);
811    }
812  unlink(ntt);
813  return res;
814 }
815
816 void mi_free_aux_term(mi_aux_term *t)
817 {
818  if (!t)
819     return;
820  free(t->tty);
821  free(t);
822 }
823
824 /**[txh]********************************************************************
825
826   Description:
827   Closes the auxiliar terminal and releases the allocated memory.
828   
829 ***************************************************************************/
830
831 void gmi_end_aux_term(mi_aux_term *t)
832 {
833  if (!t)
834     return;
835  if (t->pid!=-1 && mi_check_running_pid(t->pid))
836     mi_kill_child(t->pid);
837  mi_free_aux_term(t);
838 }
839
840 /**[txh]********************************************************************
841
842   Description:
843   Forces the MI version. Currently the library can't detect it so you must
844 force it manually. GDB 5.x implemented MI v1 and 6.x v2.
845   
846 ***************************************************************************/
847
848 void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
849                       unsigned vMinor)
850 {
851  h->version=MI_VERSION2U(vMajor,vMiddle,vMinor);
852 }
853
854 /**[txh]********************************************************************
855
856   Description:
857   Dis/Enables the workaround for a bug in gdb.
858
859 ***************************************************************************/
860
861 void mi_set_workaround(unsigned wa, int enable)
862 {
863  switch (wa)
864    {
865     case MI_PSYM_SEARCH:
866          disable_psym_search_workaround=enable ? 0 : 1;
867          break;
868    }
869 }
870
871 /**[txh]********************************************************************
872
873   Description:
874   Finds if the workaround for a bug in gdb is enabled.
875   
876   Return: !=0 if enabled.
877   
878 ***************************************************************************/
879
880 int mi_get_workaround(unsigned wa)
881 {
882  switch (wa)
883    {
884     case MI_PSYM_SEARCH:
885          return disable_psym_search_workaround==0;
886    }
887  return 0;
888 }
889