1 /**[txh]********************************************************************
3 Copyright (c) 2004 by Salvador E. Tropea.
4 Covered by the GPL license.
7 X11 example/test of the libmigdb.
8 Run it from an X11 terminal (xterm, Eterm, etc.).
10 ***************************************************************************/
13 #include <unistd.h> //usleep
16 void cb_console(const char *str, void *data)
18 printf("CONSOLE> %s\n",str);
21 /* Note that unlike what's documented in gdb docs it isn't usable. */
22 void cb_target(const char *str, void *data)
24 printf("TARGET> %s\n",str);
27 void cb_log(const char *str, void *data)
29 printf("LOG> %s\n",str);
32 void cb_to(const char *str, void *data)
37 void cb_from(const char *str, void *data)
39 printf("<< %s\n",str);
42 volatile int async_c=0;
44 void cb_async(mi_output *o, void *data)
50 void print_frames(mi_frames *f)
54 printf("Error! empty frames info\n");
59 printf("Level %d, addr %p, func %s, where: %s:%d args? %c\n",f->level,f->addr,
60 f->func,f->file,f->line,f->args ? 'y' : 'n');
66 int wait_for_stop(mi_h *h)
71 while (!mi_get_response(h))
73 /* The end of the async. */
77 printf("Stopped, reason: %s\n",mi_reason_enum_to_str(sr->reason));
78 print_frames(sr->frame);
83 printf("Error while waiting\n");
84 printf("mi_error: %s (%d)\nmi_error_from_gdb: %s\n",mi_get_error_str(),
85 mi_error,mi_error_from_gdb);
92 void print_gvar(mi_gvar *v)
96 printf("Error! failed to define variable\n");
99 printf("Variable name: '%s', type: '%s', number of children: %d format: %s expression: %s lang: %s editable: %c\n",
100 v->name,v->type,v->numchild,mi_format_enum_to_str(v->format),
101 v->exp,mi_lang_enum_to_str(v->lang),v->attr & MI_ATTR_EDITABLE ? 'y' : 'n');
104 void print_update(mi_gvar_chg *changed)
106 printf("List of changed variables:\n");
109 printf("Name: %s\nIn scope: %c\n",changed->name,changed->in_scope ? 'y' : 'n');
110 if (changed->in_scope && changed->new_type)
112 printf("New type: %s\nNew num children: %d\n",changed->new_type,changed->new_num_children);
114 changed=changed->next;
119 void print_children(mi_gvar *ch)
126 printf("Error! getting children list\n");
129 printf("\nChildren List (%d):\n",ch->numchild);
130 for (i=0, s=ch->child; i<ch->numchild; s++, i++)
132 printf("Name: %s Exp: %s Children: %d",s->name,s->exp,s->numchild);
134 printf(" Type: %s",s->type);
136 printf(" Value: %s",s->value);
142 enum cont_mode { cm_run, cm_continue, cm_finish, cm_step };
144 void do_continue(mi_h *h, enum cont_mode mode)
153 res=gmi_exec_continue(h);
156 res=gmi_exec_finish(h);
159 res=gmi_exec_step(h);
162 /* Continue the program. */
165 printf("Error in run!\n");
169 /* Here we should be stopped at the breakpoint. */
170 if (!wait_for_stop(h))
178 int main(int argc, char *argv[])
180 mi_aux_term *xterm_tty=NULL;
181 /* This is like a file-handle for fopen.
182 Here we have all the state of gdb "connection". */
187 /* You can use any gdb you want: */
188 /*mi_set_gdb_exe("/usr/src/gdb-6.1.1/gdb/gdb");*/
189 /* You can use a terminal different than xterm: */
190 /*mi_set_xterm_exe("/usr/bin/Eterm");*/
192 /* Connect to gdb child. */
193 h=mi_connect_local();
196 printf("Connect failed\n");
199 printf("Connected to gdb!\n");
201 /* Set all callbacks. */
202 mi_set_console_cb(h,cb_console,NULL);
203 mi_set_target_cb(h,cb_target,NULL);
204 mi_set_log_cb(h,cb_log,NULL);
205 mi_set_async_cb(h,cb_async,NULL);
206 mi_set_to_gdb_cb(h,cb_to,NULL);
207 mi_set_from_gdb_cb(h,cb_from,NULL);
209 /* Open an xterm to be used as terminal for the debuggy. */
210 xterm_tty=gmi_start_xterm();
212 printf("Error opening auxiliar terminal, we'll use current one.\n");
214 printf("XTerm opened @ %s\n",xterm_tty->tty);
216 /* Tell gdb to attach the child to a terminal. */
217 if (!gmi_target_terminal(h,xterm_tty ? xterm_tty->tty : ttyname(STDIN_FILENO)))
219 printf("Error selecting target terminal\n");
224 /* Set the name of the child and the command line aguments. */
225 if (!gmi_set_exec(h,"./target_frames",""))
227 printf("Error setting exec y args\n");
232 /* Break on FuncLev1. */
233 bk=gmi_break_insert_full(h,1,0,NULL,-1,-1,"FuncLev1");
236 printf("Error setting breakpoint\n");
240 printf("Breakpoint %d @ function: %s\n",bk->number,bk->func);
243 /* Set a watchpoint, that's a data breakpoint. */
244 wp=gmi_break_watch(h,wm_write,"v");
247 printf("Error al setting watchpoint\n");
251 printf("Watchpoint %d for expression: %s\n",wp->number,wp->exp);
254 /* Run the program. */
255 do_continue(h,cm_run);
257 wp2=gmi_break_watch(h,wm_write,"i");
262 do_continue(h,cm_finish);
263 do_continue(h,cm_finish);
264 do_continue(h,cm_finish);
265 do_continue(h,cm_continue);
266 do_continue(h,cm_continue);
267 do_continue(h,cm_step);
268 do_continue(h,cm_step);
269 do_continue(h,cm_step);
270 do_continue(h,cm_step);
271 do_continue(h,cm_step);
272 do_continue(h,cm_step);
273 do_continue(h,cm_step);
277 do_continue(h,cm_step);
278 do_continue(h,cm_step);
279 do_continue(h,cm_step);
284 /* Close the connection. */
286 /* Wait 5 seconds and close the auxiliar terminal. */
287 printf("Waiting 5 seconds\n");
289 gmi_end_aux_term(xterm_tty);