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