handle return value, kind-of
[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    /*
277     That's a must. If we just keep trying to read and failing things
278     become really sloooowwww. Instead we try and if it fails we wait
279     until something is available.
280     TODO: Implement something with the time out, a callback to ask the
281     application is we have to wait or not could be a good thing.
282    */
283    fd_set set;
284    struct timeval timeout;
285    int ret;
286
287    r=mi_get_response(h);
288    if (r)
289       return mi_retire_response(h);
290
291    FD_ZERO(&set);
292    FD_SET(h->from_gdb[0],&set);
293    timeout.tv_sec=h->time_out;
294    timeout.tv_usec=0;
295    ret=TEMP_FAILURE_RETRY(select(FD_SETSIZE,&set,NULL,NULL,&timeout));
296    if (!ret)
297      {
298       if (!mi_check_running(h))
299         {
300          h->died=1;
301          mi_error=MI_GDB_DIED;
302          return NULL;
303         }
304       if (h->time_out_cb)
305          ret=h->time_out_cb(h->time_out_cb_data);
306       if (!ret)
307         {
308          mi_error=MI_GDB_TIME_OUT;
309          return NULL;
310         }
311      }
312    }
313  while (!r);
314
315  return NULL;
316 }
317
318 void mi_send_commands(mi_h *h, const char *file)
319 {
320  FILE *f;
321  char b[PATH_MAX];
322
323  //printf("File: %s\n",file);
324  if (!file)
325     return;
326  f=fopen(file,"rt");
327  if (!f)
328     return;
329  while (!feof(f))
330    {
331     if (fgets(b,PATH_MAX,f))
332       {
333         //printf("Send: %s\n",b);
334         mi_send (h, "%s", b);
335         mi_res_simple_done(h);
336       }
337    }
338  fclose(f);
339 }
340
341 void mi_send_target_commands(mi_h *h)
342 {
343  mi_send_commands(h,gdb_conn);
344 }
345
346 /**[txh]********************************************************************
347
348   Description:
349   Connect to a local copy of gdb. Note that the mi_h structure is something
350 similar to a "FILE *" for stdio.
351   
352   Return: A new mi_h structure or NULL on error.
353   
354 ***************************************************************************/
355
356 mi_h *mi_connect_local()
357 {
358  mi_h *h;
359  const char *gdb=mi_get_gdb_exe();
360
361  /* Start without error. */
362  mi_error=MI_OK;
363  /* Verify we have a GDB binary. */
364  if (access(gdb,X_OK))
365    {
366     mi_error=MI_MISSING_GDB;
367     return NULL;
368    }
369  /* Alloc the handle structure. */
370  h=mi_alloc_h();
371  if (!h)
372     return h;
373  h->time_out=MI_DEFAULT_TIME_OUT;
374  /* Create the pipes to connect with the child. */
375  if (pipe(h->to_gdb) || pipe(h->from_gdb))
376    {
377     mi_error=MI_PIPE_CREATE;
378     mi_free_h(&h);
379     return NULL;
380    }
381  mi_set_nonblk(h->to_gdb[1]);
382  mi_set_nonblk(h->from_gdb[0]);
383  /* Associate streams to the file handles. */
384  h->to=fdopen(h->to_gdb[1],"w");
385  h->from=fdopen(h->from_gdb[0],"r");
386  if (!h->to || !h->from)
387    {
388     mi_error=MI_PIPE_CREATE;
389     mi_free_h(&h);
390     return NULL;
391    }
392  /* Create the child. */
393  h->pid=fork();
394  if (h->pid==0)
395    {/* We are the child. */
396     char *argv[5];
397     /* Connect stdin/out to the pipes. */
398     dup2(h->to_gdb[0],STDIN_FILENO);
399     dup2(h->from_gdb[1],STDOUT_FILENO);
400     /* Pass the control to gdb. */
401     argv[0]=(char *)gdb; /* Is that OK? */
402     argv[1]="--interpreter=mi";
403     argv[2]="--quiet";
404     argv[3]=disable_psym_search_workaround ? 0 : "--readnow";
405     argv[4]=0;
406     execvp(argv[0],argv);
407     /* We get here only if exec failed. */
408     _exit(127);
409    }
410  /* We are the parent. */
411  if (h->pid==-1)
412    {/* Fork failed. */
413     mi_error=MI_FORK;
414     mi_free_h(&h);
415     return NULL;
416    }
417  if (!mi_check_running(h))
418    {
419     mi_error=MI_DEBUGGER_RUN;
420     mi_free_h(&h);
421     return NULL;
422    }
423  /* Wait for the prompt. */
424  mi_get_response_blk(h);
425  /* Send the start-up commands */
426  mi_send_commands(h,gdb_start);
427
428  return h;
429 }
430
431 /**[txh]********************************************************************
432
433   Description:
434   Close connection. You should ask gdb to quit first gmi_gdb_exit.
435   
436 ***************************************************************************/
437
438 void mi_disconnect(mi_h *h)
439 {
440  mi_free_h(&h);
441  free(mi_error_from_gdb);
442  mi_error_from_gdb=NULL;
443 }
444
445 void mi_set_console_cb(mi_h *h, stream_cb cb, void *data)
446 {
447  h->console=cb;
448  h->console_data=data;
449 }
450
451 void mi_set_target_cb(mi_h *h, stream_cb cb, void *data)
452 {
453  h->target=cb;
454  h->target_data=data;
455 }
456
457 void mi_set_log_cb(mi_h *h, stream_cb cb, void *data)
458 {
459  h->log=cb;
460  h->log_data=data;
461 }
462
463 stream_cb mi_get_console_cb(mi_h *h, void **data)
464 {
465  if (data)
466     *data=h->console_data;
467  return h->console;
468 }
469
470 stream_cb mi_get_target_cb(mi_h *h, void **data)
471 {
472  if (data)
473     *data=h->target_data;
474  return h->target;
475 }
476
477 stream_cb mi_get_log_cb(mi_h *h, void **data)
478 {
479  if (data)
480     *data=h->log_data;
481  return h->log;
482 }
483
484 void mi_set_async_cb(mi_h *h, async_cb cb, void *data)
485 {
486  h->async=cb;
487  h->async_data=data;
488 }
489
490 async_cb mi_get_async_cb(mi_h *h, void **data)
491 {
492  if (data)
493     *data=h->async_data;
494  return h->async;
495 }
496
497 void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data)
498 {
499  h->to_gdb_echo=cb;
500  h->to_gdb_echo_data=data;
501 }
502
503 void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data)
504 {
505  h->from_gdb_echo=cb;
506  h->from_gdb_echo_data=data;
507 }
508
509 stream_cb mi_get_to_gdb_cb(mi_h *h, void **data)
510 {
511  if (data)
512     *data=h->to_gdb_echo_data;
513  return h->to_gdb_echo;
514 }
515
516 stream_cb mi_get_from_gdb_cb(mi_h *h, void **data)
517 {
518  if (data)
519     *data=h->from_gdb_echo_data;
520  return h->from_gdb_echo;
521 }
522
523 void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data)
524 {
525  h->time_out_cb=cb;
526  h->time_out_cb_data=data;
527 }
528
529 tm_cb mi_get_time_out_cb(mi_h *h, void **data)
530 {
531  if (data)
532     *data=h->time_out_cb_data;
533  return h->time_out_cb;
534 }
535
536 void mi_set_time_out(mi_h *h, int to)
537 {
538  h->time_out=to;
539 }
540
541 int mi_get_time_out(mi_h *h)
542 {
543  return h->time_out;
544 }
545
546 int mi_send(mi_h *h, const char *format, ...)
547 {
548  int ret;
549  char *str;
550  va_list argptr;
551
552  if (h->died)
553     return 0;
554
555  va_start(argptr,format);
556  ret=vasprintf(&str,format,argptr);
557  va_end(argptr);
558  if (-1 != ret)
559    {
560      fputs(str,h->to);
561      fflush(h->to);
562      if (h->to_gdb_echo)
563        h->to_gdb_echo(str,h->to_gdb_echo_data);
564      free(str);
565    }
566  else
567    {
568      abort ();
569    }
570
571  return ret;
572 }
573
574 void mi_clean_up_globals()
575 {
576  free(gdb_exe);
577  gdb_exe=NULL;
578  free(xterm_exe);
579  xterm_exe=NULL;
580  free(gdb_start);
581  gdb_start=NULL;
582  free(gdb_conn);
583  gdb_conn=NULL;
584  free(main_func);
585  main_func=NULL;
586 }
587
588 void mi_register_exit()
589 {
590  static int registered=0;
591  if (!registered)
592    {
593     registered=1;
594     atexit(mi_clean_up_globals);
595    }
596 }
597
598 void mi_set_gdb_exe(const char *name)
599 {
600  free(gdb_exe);
601  gdb_exe=name ? strdup(name) : NULL;
602  mi_register_exit();
603 }
604
605 void mi_set_gdb_start(const char *name)
606 {
607  free(gdb_start);
608  gdb_start=name ? strdup(name) : NULL;
609  mi_register_exit();
610 }
611
612 void mi_set_gdb_conn(const char *name)
613 {
614  free(gdb_conn);
615  gdb_conn=name ? strdup(name) : NULL;
616  mi_register_exit();
617 }
618
619 static
620 char *mi_search_in_path(const char *file)
621 {
622  char *path, *pt, *r;
623  char test[PATH_MAX];
624  struct stat st;
625
626  path=getenv("PATH");
627  if (!path)
628     return NULL;
629  pt=strdup(path);
630  r=strtok(pt,PATH_SEPARATOR_STR);
631  while (r)
632    {
633     strcpy(test,r);
634     strcat(test,"/");
635     strcat(test,file);
636     if (stat(test,&st)==0 && S_ISREG(st.st_mode))
637       {
638        free(pt);
639        return strdup(test);
640       }
641     r=strtok(NULL,PATH_SEPARATOR_STR);
642    }
643  free(pt);
644  return NULL;
645 }
646
647 const char *mi_get_gdb_exe()
648 {
649  if (!gdb_exe)
650    {/* Look for gdb in path */
651     gdb_exe=mi_search_in_path("gdb");
652     if (!gdb_exe)
653        return "/usr/bin/gdb";
654    }
655  return gdb_exe;
656 }
657
658 const char *mi_get_gdb_start()
659 {
660  return gdb_start;
661 }
662
663 const char *mi_get_gdb_conn()
664 {
665  return gdb_conn;
666 }
667
668 void mi_set_xterm_exe(const char *name)
669 {
670  free(xterm_exe);
671  xterm_exe=name ? strdup(name) : NULL;
672  mi_register_exit();
673 }
674
675 const char *mi_get_xterm_exe()
676 {
677  if (!xterm_exe)
678    {/* Look for xterm in path */
679     xterm_exe=mi_search_in_path("xterm");
680     if (!xterm_exe)
681        return "/usr/bin/X11/xterm";
682    }
683  return xterm_exe;
684 }
685
686 void mi_set_main_func(const char *name)
687 {
688  free(main_func);
689  main_func=name ? strdup(name) : NULL;
690  mi_register_exit();
691 }
692
693 const char *mi_get_main_func()
694 {
695  if (main_func)
696     return main_func;
697  return "main";
698 }
699
700 /**[txh]********************************************************************
701
702   Description:
703   Opens a new xterm to be used by the child process to debug.
704   
705   Return: A new mi_aux_term structure, you can use gmi_end_aux_term to
706 release it.
707   
708 ***************************************************************************/
709
710 mi_aux_term *gmi_start_xterm()
711 {
712  char nsh[14]="/tmp/shXXXXXX";
713  char ntt[14]="/tmp/ttXXXXXX";
714  const char *xterm;
715  struct stat st;
716  int hsh, htt=-1;
717  mi_aux_term *res=NULL;
718  FILE *f;
719  pid_t pid;
720  char buf[PATH_MAX];
721
722  /* Verify we have an X terminal. */
723  xterm=mi_get_xterm_exe();
724  if (access(xterm,X_OK))
725    {
726     mi_error=MI_MISSING_XTERM;
727     return NULL;
728    }
729
730  /* Create 2 temporals. */
731  hsh=mkstemp(nsh);
732  if (hsh==-1)
733    {
734     mi_error=MI_CREATE_TEMPORAL;
735     return NULL;
736    }
737  htt=mkstemp(ntt);
738  if (htt==-1)
739    {
740     close(hsh);
741     unlink(nsh);
742     mi_error=MI_CREATE_TEMPORAL;
743     return NULL;
744    }
745  close(htt);
746  /* Create the script. */
747  f=fdopen(hsh,"w");
748  if (!f)
749    {
750     close(hsh);
751     unlink(nsh);
752     unlink(ntt);
753     mi_error=MI_CREATE_TEMPORAL;
754     return NULL;
755    }
756  fprintf(f,"#!/bin/sh\n");
757  fprintf(f,"tty > %s\n",ntt);
758  fprintf(f,"rm %s\n",nsh);
759  fprintf(f,"sleep 365d\n");
760  fclose(f);
761  /* Spawn xterm. */
762  /* Create the child. */
763  pid=fork();
764  if (pid==0)
765    {/* We are the child. */
766     char *argv[5];
767     /* Pass the control to gdb. */
768     argv[0]=(char *)mi_get_xterm_exe(); /* Is that ok? */
769     argv[1]="-e";
770     argv[2]="/bin/sh";
771     argv[3]=nsh;
772     argv[4]=0;
773     execvp(argv[0],argv);
774     /* We get here only if exec failed. */
775     unlink(nsh);
776     unlink(ntt);
777     _exit(127);
778    }
779  /* We are the parent. */
780  if (pid==-1)
781    {/* Fork failed. */
782     unlink(nsh);
783     unlink(ntt);
784     mi_error=MI_FORK;
785     return NULL;
786    }
787  /* Wait until the shell is deleted. */
788  while (stat(nsh,&st)==0)
789    usleep(1000);
790  /* Try to read the tty name. */
791  f=fopen(ntt,"rt");
792  if (f)
793    {
794     if (fgets(buf,PATH_MAX,f))
795       {
796        char *s; /* Strip the \n. */
797        for (s=buf; *s && *s!='\n'; s++);
798        *s=0;
799        res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
800        if (res)
801          {
802           res->pid=pid;
803           res->tty=strdup(buf);
804          }
805       }
806     fclose(f);
807    }
808  unlink(ntt);
809  return res;
810 }
811
812 void mi_free_aux_term(mi_aux_term *t)
813 {
814  if (!t)
815     return;
816  free(t->tty);
817  free(t);
818 }
819
820 /**[txh]********************************************************************
821
822   Description:
823   Closes the auxiliar terminal and releases the allocated memory.
824   
825 ***************************************************************************/
826
827 void gmi_end_aux_term(mi_aux_term *t)
828 {
829  if (!t)
830     return;
831  if (t->pid!=-1 && mi_check_running_pid(t->pid))
832     mi_kill_child(t->pid);
833  mi_free_aux_term(t);
834 }
835
836 /**[txh]********************************************************************
837
838   Description:
839   Forces the MI version. Currently the library can't detect it so you must
840 force it manually. GDB 5.x implemented MI v1 and 6.x v2.
841   
842 ***************************************************************************/
843
844 void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
845                       unsigned vMinor)
846 {
847  h->version=MI_VERSION2U(vMajor,vMiddle,vMinor);
848 }
849
850 /**[txh]********************************************************************
851
852   Description:
853   Dis/Enables the workaround for a bug in gdb.
854
855 ***************************************************************************/
856
857 void mi_set_workaround(unsigned wa, int enable)
858 {
859  switch (wa)
860    {
861     case MI_PSYM_SEARCH:
862          disable_psym_search_workaround=enable ? 0 : 1;
863          break;
864    }
865 }
866
867 /**[txh]********************************************************************
868
869   Description:
870   Finds if the workaround for a bug in gdb is enabled.
871   
872   Return: !=0 if enabled.
873   
874 ***************************************************************************/
875
876 int mi_get_workaround(unsigned wa)
877 {
878  switch (wa)
879    {
880     case MI_PSYM_SEARCH:
881          return disable_psym_search_workaround==0;
882    }
883  return 0;
884 }
885