cvs -z3 -d:pserver:anonymous@libmigdb.cvs.sourceforge.net:/cvsroot/libmigdb co -P...
[gdbmicli.git] / libmigdb / examples / x11_fr_test.c
1 /**[txh]********************************************************************
2
3   Copyright (c) 2004 by Salvador E. Tropea.
4   Covered by the GPL license.
5
6   Comment:
7   X11 example/test of the libmigdb.
8   Run it from an X11 terminal (xterm, Eterm, etc.).
9   
10 ***************************************************************************/
11
12 #include <stdio.h>
13 #include <unistd.h> //usleep
14 #include "mi_gdb.h"
15
16 void cb_console(const char *str, void *data)
17 {
18  printf("CONSOLE> %s\n",str);
19 }
20
21 /* Note that unlike what's documented in gdb docs it isn't usable. */
22 void cb_target(const char *str, void *data)
23 {
24  printf("TARGET> %s\n",str);
25 }
26
27 void cb_log(const char *str, void *data)
28 {
29  printf("LOG> %s\n",str);
30 }
31
32 void cb_to(const char *str, void *data)
33 {
34  printf(">> %s",str);
35 }
36
37 void cb_from(const char *str, void *data)
38 {
39  printf("<< %s\n",str);
40 }
41
42 volatile int async_c=0;
43
44 void cb_async(mi_output *o, void *data)
45 {
46  printf("ASYNC\n");
47  async_c++;
48 }
49
50 void print_frames(mi_frames *f, int free_f)
51 {
52  mi_frames *ff=f;
53
54  if (!f)
55    {
56     printf("Error! empty frames info\n");
57     return;
58    }
59  while (f)
60    {
61     printf("Level %d, addr %p, func %s, where: %s:%d args? %c\n",f->level,f->addr,
62            f->func,f->file,f->line,f->args ? 'y' : 'n');
63     f=f->next;
64    }
65  if (free_f)
66     mi_free_frames(ff);
67 }
68
69 int wait_for_stop(mi_h *h)
70 {
71  int res=1;
72  mi_stop *sr;
73
74  while (!mi_get_response(h))
75     usleep(1000);
76  /* The end of the async. */
77  sr=mi_res_stop(h);
78  if (sr)
79    {
80     printf("Stopped, reason: %s\n",mi_reason_enum_to_str(sr->reason));
81     print_frames(sr->frame,0);
82     mi_free_stop(sr);
83    }
84  else
85    {
86     printf("Error while waiting\n");
87     res=0;
88    }
89  return res;
90 }
91
92 void print_gvar(mi_gvar *v)
93 {
94  if (!v)
95    {
96     printf("Error! failed to define variable\n");
97     return;
98    }
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');
102 }
103
104 void print_update(mi_gvar_chg *changed)
105 {
106  printf("List of changed variables:\n");
107  while (changed)
108    {
109     printf("Name: %s\nIn scope: %c\n",changed->name,changed->in_scope ? 'y' : 'n');
110     if (changed->in_scope && changed->new_type)
111       {
112        printf("New type: %s\nNew num children: %d\n",changed->new_type,changed->new_num_children);
113       }
114     changed=changed->next;
115     printf("\n");
116    }
117 }
118
119 void print_children(mi_gvar *ch)
120 {
121  int i;
122  mi_gvar *s;
123
124  if (!ch->child)
125    {
126     printf("Error! getting children list\n");
127     return;
128    }
129  printf("\nChildren List (%d):\n",ch->numchild);
130  for (i=0, s=ch->child; i<ch->numchild; s++, i++)
131     {
132      printf("Name: %s Exp: %s Children: %d",s->name,s->exp,s->numchild);
133      if (s->type)
134         printf(" Type: %s",s->type);
135      if (s->value)
136         printf(" Value: %s",s->value);
137      printf("\n");
138     }
139  printf("\n");
140 }
141
142
143 int main(int argc, char *argv[])
144 {
145  mi_aux_term *xterm_tty=NULL;
146  mi_bkpt *bk;
147  mi_frames *fr;
148  /* This is like a file-handle for fopen.
149     Here we have all the state of gdb "connection". */
150  mi_h *h;
151  mi_gvar *gv, *gv2;
152  mi_gvar_chg *changed;
153  char *value;
154  int r_assign;
155
156  /* You can use any gdb you want: */
157  /*mi_set_gdb_exe("/usr/src/gdb-6.1.1/gdb/gdb");*/
158  /* You can use a terminal different than xterm: */
159  /*mi_set_xterm_exe("/usr/bin/Eterm");*/
160
161  /* Connect to gdb child. */
162  h=mi_connect_local();
163  if (!h)
164    {
165     printf("Connect failed\n");
166     return 1;
167    }
168  printf("Connected to gdb!\n");
169
170  /* Set all callbacks. */
171  mi_set_console_cb(h,cb_console,NULL);
172  mi_set_target_cb(h,cb_target,NULL);
173  mi_set_log_cb(h,cb_log,NULL);
174  mi_set_async_cb(h,cb_async,NULL);
175  mi_set_to_gdb_cb(h,cb_to,NULL);
176  mi_set_from_gdb_cb(h,cb_from,NULL);
177
178  /* Set the name of the child and the command line aguments. */
179  if (!gmi_set_exec(h,"./target_frames",""))
180    {
181     printf("Error setting exec y args\n");
182     mi_disconnect(h);
183     return 1;
184    }
185
186  /* Open an xterm to be used as terminal for the debuggy. */
187  xterm_tty=gmi_start_xterm();
188  if (!xterm_tty)
189     printf("Error opening auxiliar terminal, we'll use current one.\n");
190  else
191     printf("XTerm opened @ %s\n",xterm_tty->tty);
192
193  /* Tell gdb to attach the child to a terminal. */
194  if (!gmi_target_terminal(h,xterm_tty ? xterm_tty->tty : ttyname(STDIN_FILENO)))
195    {
196     printf("Error selecting target terminal\n");
197     mi_disconnect(h);
198     return 1;
199    }
200
201  /* Set a breakpoint. */
202  bk=gmi_break_insert(h,"target_frames.cc",7);
203  if (!bk)
204    {
205     printf("Error setting breakpoint\n");
206     mi_disconnect(h);
207     return 1;
208    }
209  printf("Breakpoint %d @ function: %s\n",bk->number,bk->func);
210
211  /* If we no longer need this data we can release it. */
212  mi_free_bkpt(bk);
213
214  /* Run the program. */
215  if (!gmi_exec_run(h))
216    {
217     printf("Error in run!\n");
218     mi_disconnect(h);
219     return 1;
220    }
221  /* Here we should be stopped at the breakpoint. */
222  if (!wait_for_stop(h))
223    {
224     mi_disconnect(h);
225     return 1;
226    }
227
228  /* Get information about the calling stack. */
229  fr=gmi_stack_list_frames(h);
230  printf("\nCalling stack:\n\n");
231  print_frames(fr,1);
232  printf("\n");
233  fr=gmi_stack_info_frame(h);
234  printf("\nCurrent frame:\n\n");
235  print_frames(fr,1);
236  printf("\n");
237  printf("Stack depth: %d\n",gmi_stack_info_depth_get(h));
238  gmi_stack_select_frame(h,1);
239  fr=gmi_stack_info_frame(h);
240  printf("\nFrame 1:\n\n");
241  print_frames(fr,1);
242  printf("\n");
243
244  if (0)
245    {
246     gv=gmi_var_create(h,-1,"v");
247     print_gvar(gv);
248     gmi_var_show_format(h,gv);
249     print_gvar(gv);
250     gmi_var_info_num_children(h,gv);
251     print_gvar(gv);
252     gmi_var_info_type(h,gv);
253     print_gvar(gv);
254     gmi_var_info_expression(h,gv);
255     print_gvar(gv);
256     gmi_var_show_attributes(h,gv);
257     print_gvar(gv);
258    }
259  else
260    {
261     gv=gmi_full_var_create(h,-1,"v");
262     print_gvar(gv);
263    }
264  gv2=gmi_full_var_create(h,-1,"sup");
265  print_gvar(gv2);
266  gmi_var_set_format(h,gv,fm_hexadecimal);
267  print_gvar(gv);
268
269  /* Continue execution. */
270  if (!gmi_exec_until(h,"target_frames.cc",21))
271    {
272     printf("Error in exec until!\n");
273     mi_disconnect(h);
274     return 1;
275    }
276  if (!wait_for_stop(h))
277    {
278     mi_disconnect(h);
279     return 1;
280    }
281
282  gmi_var_update(h,NULL,&changed);
283  print_update(changed);
284  mi_free_gvar_chg(changed);
285
286  r_assign=gmi_var_assign(h,gv,"i+5");
287  if (r_assign && gv->value)
288     printf("\nAssigned v=%s\n\n",gv->value);
289
290  gmi_var_list_children(h,gv2);
291  print_children(gv2);
292
293  gmi_var_evaluate_expression(h,gv2);
294  printf("\n%s = %s\n\n",gv2->exp,gv2->value);
295
296  value=gmi_data_evaluate_expression(h,gv2->exp);
297  printf("\n%s = %s\n\n",gv2->exp,value);
298  free(value);
299
300  gmi_var_delete(h,gv);
301  mi_free_gvar(gv);
302  gmi_var_delete(h,gv2);
303  mi_free_gvar(gv2);
304
305  /* Continue execution. */
306  if (!gmi_exec_continue(h))
307    {
308     printf("Error in continue!\n");
309     mi_disconnect(h);
310     return 1;
311    }
312  /* Here we should be terminated. */
313  if (!wait_for_stop(h))
314    {
315     mi_disconnect(h);
316     return 1;
317    }
318
319  /* Exit from gdb. */
320  gmi_gdb_exit(h);
321  /* Close the connection. */
322  mi_disconnect(h);
323  /* Wait 5 seconds and close the auxiliar terminal. */
324  printf("Waiting 5 seconds\n");
325  sleep(5);
326  gmi_end_aux_term(xterm_tty);
327
328  return 0;
329 }