1 /**[txh]********************************************************************
3 Copyright (c) 2004-2009 by Salvador E. Tropea.
4 Covered by the GPL license.
8 This module handles the dialog with gdb, including starting and stopping
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
18 ***************************************************************************/
21 #include <sys/types.h>
37 #ifndef TEMP_FAILURE_RETRY
38 #define TEMP_FAILURE_RETRY(a) (a)
42 char *mi_error_from_gdb=NULL;
43 static char *gdb_exe=NULL;
44 static char *xterm_exe=NULL;
45 static char *gdb_start=NULL;
46 static char *gdb_conn=NULL;
47 static char *main_func=NULL;
48 static char disable_psym_search_workaround=0;
52 mi_h *h=(mi_h *)calloc(1,sizeof(mi_h));
55 mi_error=MI_OUT_OF_MEMORY;
58 h->to_gdb[0]=h->to_gdb[1]=h->from_gdb[0]=h->from_gdb[1]=-1;
63 int mi_check_running_pid(pid_t pid)
69 /* If waitpid returns the number of our child means it communicated
70 to as a termination status. */
71 if (waitpid(pid,&status,WNOHANG)==pid)
79 int mi_check_running(mi_h *h)
81 return !h->died && mi_check_running_pid(h->pid);
84 void mi_kill_child(pid_t pid)
88 if (mi_check_running_pid(pid))
92 waitpid(pid,&status,0);
96 void mi_free_h(mi_h **handle)
103 else if (h->to_gdb[1]>=0)
107 else if (h->from_gdb[0]>=0)
108 close(h->from_gdb[0]);
109 if (h->from_gdb[1]>=0)
110 close(h->from_gdb[1]);
111 if (mi_check_running(h))
112 {/* GDB is running! */
113 mi_kill_child(h->pid);
117 mi_free_output(h->po);
118 free(h->catched_console);
123 void mi_set_nonblk(int h)
126 flf=fcntl(h,F_GETFL,0);
127 flf=flf | O_NONBLOCK;
128 // fcntl(h,F_SETFL,flf);
131 int mi_getline(mi_h *h)
135 while (read(h->from_gdb[0],&c,1)==1)
137 if (h->lread>=h->llen)
139 h->llen=h->lread+128;
140 h->line=(char *)realloc(h->line,h->llen);
164 char *get_cstr(mi_output *o)
166 if (!o->c || o->c->type!=t_const)
171 int mi_get_response(mi_h *h)
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. */
184 {/* Add to the response. */
186 int add=1, is_exit=0;
187 o=mi_parse_gdb_output(h->line);
191 /* Tunneled streams callbacks. */
192 if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_STREAM)
201 h->console(aux,h->console_data);
202 if (h->catch_console && aux)
205 if (!h->catch_console)
207 free(h->catched_console);
208 h->catched_console=strdup(aux);
213 /* This one seems to be useless. */
215 h->target(get_cstr(o),h->target_data);
219 h->log(get_cstr(o),h->log_data);
223 else if (o->type==MI_T_OUT_OF_BAND && o->stype==MI_ST_ASYNC)
226 h->async(o,h->async_data);
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);
236 is_exit=(o->type==MI_T_RESULT_RECORD && o->tclass==MI_CL_EXIT);
237 /* Add to the list of responses. */
248 /* Exit RR means gdb exited, we won't get a new prompt ;-) */
256 mi_output *mi_retire_response(mi_h *h)
258 mi_output *ret=h->po;
263 mi_output *mi_get_response_blk(mi_h *h)
266 /* Sometimes gdb dies. */
267 if (!mi_check_running(h))
270 mi_error=MI_GDB_DIED;
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.
285 struct timeval timeout;
288 r=mi_get_response(h);
290 return mi_retire_response(h);
293 FD_SET(h->from_gdb[0],&set);
294 timeout.tv_sec=h->time_out;
296 ret=TEMP_FAILURE_RETRY(select(FD_SETSIZE,&set,NULL,NULL,&timeout));
299 if (!mi_check_running(h))
302 mi_error=MI_GDB_DIED;
306 ret=h->time_out_cb(h->time_out_cb_data);
309 mi_error=MI_GDB_TIME_OUT;
316 r=mi_get_response(h);
318 return mi_retire_response(h);
328 void mi_send_commands(mi_h *h, const char *file)
333 //printf("File: %s\n",file);
341 if (fgets(b,PATH_MAX,f))
343 //printf("Send: %s\n",b);
345 mi_res_simple_done(h);
351 void mi_send_target_commands(mi_h *h)
353 mi_send_commands(h,gdb_conn);
356 /**[txh]********************************************************************
359 Connect to a local copy of gdb. Note that the mi_h structure is something
360 similar to a "FILE *" for stdio.
362 Return: A new mi_h structure or NULL on error.
364 ***************************************************************************/
367 void (*mi_gdb_start_hook) (mi_h *h);
369 mi_h *mi_connect_local()
372 const char *gdb=mi_get_gdb_exe();
374 /* Start without error. */
376 /* Verify we have a GDB binary. */
377 if (access(gdb,X_OK))
379 mi_error=MI_MISSING_GDB;
382 /* Alloc the handle structure. */
386 h->time_out=MI_DEFAULT_TIME_OUT;
387 /* Create the pipes to connect with the child. */
388 if (pipe(h->to_gdb) || pipe(h->from_gdb))
390 mi_error=MI_PIPE_CREATE;
394 mi_set_nonblk(h->to_gdb[1]);
395 mi_set_nonblk(h->from_gdb[0]);
396 /* Associate streams to the file handles. */
397 h->to=fdopen(h->to_gdb[1],"w");
398 h->from=fdopen(h->from_gdb[0],"r");
399 if (!h->to || !h->from)
401 mi_error=MI_PIPE_CREATE;
405 /* Create the child. */
408 {/* We are the child. */
410 /* Connect stdin/out to the pipes. */
411 dup2(h->to_gdb[0],STDIN_FILENO);
412 dup2(h->from_gdb[1],STDOUT_FILENO);
413 /* Pass the control to gdb. */
414 argv[0]=(char *)gdb; /* Is that OK? */
415 argv[1]="--interpreter=mi";
417 argv[3]=disable_psym_search_workaround ? 0 : "--readnow";
419 execvp(argv[0],mi_gdb_argv ? mi_gdb_argv : argv);
420 /* We get here only if exec failed. */
423 /* We are the parent. */
430 if (!mi_check_running(h))
432 mi_error=MI_DEBUGGER_RUN;
436 if (mi_gdb_start_hook)
438 mi_gdb_start_hook (h);
439 assert (gdb_start == NULL);
443 /* Wait for the prompt. */
444 mi_get_response_blk(h);
445 /* Send the start-up commands */
446 mi_send_commands(h,gdb_start);
452 /**[txh]********************************************************************
455 Close connection. You should ask gdb to quit first @x{gmi_gdb_exit}.
457 ***************************************************************************/
459 void mi_disconnect(mi_h *h)
462 free(mi_error_from_gdb);
463 mi_error_from_gdb=NULL;
466 void mi_set_console_cb(mi_h *h, stream_cb cb, void *data)
469 h->console_data=data;
472 void mi_set_target_cb(mi_h *h, stream_cb cb, void *data)
478 void mi_set_log_cb(mi_h *h, stream_cb cb, void *data)
484 stream_cb mi_get_console_cb(mi_h *h, void **data)
487 *data=h->console_data;
491 stream_cb mi_get_target_cb(mi_h *h, void **data)
494 *data=h->target_data;
498 stream_cb mi_get_log_cb(mi_h *h, void **data)
505 void mi_set_async_cb(mi_h *h, async_cb cb, void *data)
511 async_cb mi_get_async_cb(mi_h *h, void **data)
518 void mi_set_to_gdb_cb(mi_h *h, stream_cb cb, void *data)
521 h->to_gdb_echo_data=data;
524 void mi_set_from_gdb_cb(mi_h *h, stream_cb cb, void *data)
527 h->from_gdb_echo_data=data;
530 stream_cb mi_get_to_gdb_cb(mi_h *h, void **data)
533 *data=h->to_gdb_echo_data;
534 return h->to_gdb_echo;
537 stream_cb mi_get_from_gdb_cb(mi_h *h, void **data)
540 *data=h->from_gdb_echo_data;
541 return h->from_gdb_echo;
544 void mi_set_time_out_cb(mi_h *h, tm_cb cb, void *data)
547 h->time_out_cb_data=data;
550 tm_cb mi_get_time_out_cb(mi_h *h, void **data)
553 *data=h->time_out_cb_data;
554 return h->time_out_cb;
557 void mi_set_time_out(mi_h *h, int to)
562 int mi_get_time_out(mi_h *h)
567 int mi_send(mi_h *h, const char *format, ...)
576 va_start(argptr,format);
577 ret=vasprintf(&str,format,argptr);
582 h->to_gdb_echo(str,h->to_gdb_echo_data);
588 void mi_clean_up_globals()
602 void mi_register_exit()
604 static int registered=0;
608 atexit(mi_clean_up_globals);
612 void mi_set_gdb_exe(const char *name)
615 gdb_exe=name ? strdup(name) : NULL;
619 void mi_set_gdb_start(const char *name)
622 gdb_start=name ? strdup(name) : NULL;
626 void mi_set_gdb_conn(const char *name)
629 gdb_conn=name ? strdup(name) : NULL;
634 char *mi_search_in_path(const char *file)
650 if (stat(test,&st)==0 && S_ISREG(st.st_mode))
661 const char *mi_get_gdb_exe()
664 {/* Look for gdb in path */
665 gdb_exe=mi_search_in_path("gdb");
667 return "/usr/bin/gdb";
672 const char *mi_get_gdb_start()
677 const char *mi_get_gdb_conn()
682 void mi_set_xterm_exe(const char *name)
685 xterm_exe=name ? strdup(name) : NULL;
689 const char *mi_get_xterm_exe()
692 {/* Look for xterm in path */
693 xterm_exe=mi_search_in_path("xterm");
695 return "/usr/bin/X11/xterm";
700 void mi_set_main_func(const char *name)
703 main_func=name ? strdup(name) : NULL;
707 const char *mi_get_main_func()
714 /**[txh]********************************************************************
717 Opens a new xterm to be used by the child process to debug.
719 Return: A new mi_aux_term structure, you can use @x{gmi_end_aux_term} to
722 ***************************************************************************/
724 mi_aux_term *gmi_start_xterm()
726 char nsh[14]="/tmp/shXXXXXX";
727 char ntt[14]="/tmp/ttXXXXXX";
731 mi_aux_term *res=NULL;
736 /* Verify we have an X terminal. */
737 xterm=mi_get_xterm_exe();
738 if (access(xterm,X_OK))
740 mi_error=MI_MISSING_XTERM;
744 /* Create 2 temporals. */
748 mi_error=MI_CREATE_TEMPORAL;
756 mi_error=MI_CREATE_TEMPORAL;
760 /* Create the script. */
767 mi_error=MI_CREATE_TEMPORAL;
770 fprintf(f,"#!/bin/sh\n");
771 fprintf(f,"tty > %s\n",ntt);
772 fprintf(f,"rm %s\n",nsh);
773 fprintf(f,"sleep 365d\n");
776 /* Create the child. */
779 {/* We are the child. */
781 /* Pass the control to gdb. */
782 argv[0]=(char *)mi_get_xterm_exe(); /* Is that ok? */
787 execvp(argv[0],argv);
788 /* We get here only if exec failed. */
793 /* We are the parent. */
801 /* Wait until the shell is deleted. */
802 while (stat(nsh,&st)==0)
804 /* Try to read the tty name. */
808 if (fgets(buf,PATH_MAX,f))
810 char *s; /* Strip the \n. */
811 for (s=buf; *s && *s!='\n'; s++);
813 res=(mi_aux_term *)malloc(sizeof(mi_aux_term));
817 res->tty=strdup(buf);
826 void mi_free_aux_term(mi_aux_term *t)
834 /**[txh]********************************************************************
837 Closes the auxiliar terminal and releases the allocated memory.
839 ***************************************************************************/
841 void gmi_end_aux_term(mi_aux_term *t)
845 if (t->pid!=-1 && mi_check_running_pid(t->pid))
846 mi_kill_child(t->pid);
850 /**[txh]********************************************************************
853 Forces the MI version. Currently the library can't detect it so you must
854 force it manually. GDB 5.x implemented MI v1 and 6.x v2.
856 ***************************************************************************/
858 void mi_force_version(mi_h *h, unsigned vMajor, unsigned vMiddle,
861 h->version=MI_VERSION2U(vMajor,vMiddle,vMinor);
864 /**[txh]********************************************************************
867 Dis/Enables the @var{wa} workaround for a bug in gdb.
869 ***************************************************************************/
871 void mi_set_workaround(unsigned wa, int enable)
876 disable_psym_search_workaround=enable ? 0 : 1;
881 /**[txh]********************************************************************
884 Finds if the @var{wa} workaround for a bug in gdb is enabled.
886 Return: !=0 if enabled.
888 ***************************************************************************/
890 int mi_get_workaround(unsigned wa)
895 return disable_psym_search_workaround==0;