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