Monkey sends e-mails reporting bugs detected using gdbmi
[oweals/gnunet.git] / src / monkey / gnunet-monkey.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 <libesmtp.h>
15 #include "gdbmi.h"
16 #include "platform.h"
17 #include "gnunet_common.h"
18
19 extern void sendMail(const char *messageContents);
20
21 void cb_console(const char *str, void *data)
22 {
23  printf("CONSOLE> %s\n",str);
24 }
25
26 /* Note that unlike what's documented in gdb docs it isn't usable. */
27 void cb_target(const char *str, void *data)
28 {
29  printf("TARGET> %s\n",str);
30 }
31
32 void cb_log(const char *str, void *data)
33 {
34  printf("LOG> %s\n",str);
35 }
36
37 void cb_to(const char *str, void *data)
38 {
39  printf(">> %s",str);
40 }
41
42 void cb_from(const char *str, void *data)
43 {
44  printf("<< %s\n",str);
45 }
46
47 volatile int async_c=0;
48
49 void cb_async(mi_output *o, void *data)
50 {
51  printf("ASYNC\n");
52  async_c++;
53 }
54
55
56 void send_bug_mail(mi_stop* sr, mi_frames* f)
57 {
58         char *message;
59         asprintf(&message, "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n",
60                 f->file, f->func, f->line, mi_reason_enum_to_str(sr->reason), sr->signal_name, sr->signal_meaning);
61         sendMail(message);
62 }
63
64
65 int wait_for_stop(mi_h *h)
66 {
67  int res=1;
68  mi_stop *sr;
69  mi_frames *f;
70
71  while (!mi_get_response(h))
72     usleep(1000);
73  /* The end of the async. */
74  sr=mi_res_stop(h);
75  if (sr)
76    {
77     f = gmi_stack_info_frame(h);
78     send_bug_mail(sr, f);
79     mi_free_stop(sr);
80     res = 0;
81    }
82  else
83    {
84     printf("Error while waiting\n");
85     printf("mi_error: %d\nmi_error_from_gdb: %s\n",mi_error,mi_error_from_gdb);
86     res=0;
87    }
88  return res;
89 }
90
91 int main(int argc, char *argv[])
92 {
93  mi_aux_term *xterm_tty=NULL;
94  const char* binaryName;
95  
96  binaryName = argv[1];
97  GNUNET_assert(NULL != binaryName);
98  
99  /* This is like a file-handle for fopen.
100     Here we have all the state of gdb "connection". */
101  mi_h *h;
102
103  /* Connect to gdb child. */
104  h=mi_connect_local();
105  if (!h)
106    {
107     printf("Connect failed\n");
108     return 1;
109    }
110  printf("Connected to gdb!\n");
111
112  /* Set all callbacks. */
113  mi_set_console_cb(h,cb_console,NULL);
114  mi_set_target_cb(h,cb_target,NULL);
115  mi_set_log_cb(h,cb_log,NULL);
116  mi_set_async_cb(h,cb_async,NULL);
117  mi_set_to_gdb_cb(h,cb_to,NULL);
118  mi_set_from_gdb_cb(h,cb_from,NULL);
119
120  /* Set the name of the child and the command line aguments. */
121  if (!gmi_set_exec(h, binaryName, NULL))
122    {
123     printf("Error setting exec y args\n");
124     mi_disconnect(h);
125     return 1;
126    }
127
128  /* Tell gdb to attach the child to a terminal. */
129  if (!gmi_target_terminal(h, ttyname(STDIN_FILENO)))
130    {
131     printf("Error selecting target terminal\n");
132     mi_disconnect(h);
133     return 1;
134    }
135
136  /* Run the program. */
137  if (!gmi_exec_run(h))
138    {
139     printf("Error in run!\n");
140     mi_disconnect(h);
141     return 1;
142    }
143  /* Here we should be stopped when the program crashes */
144  if (!wait_for_stop(h))
145    {
146     mi_disconnect(h);
147     return 1;
148    }
149
150  /* Continue execution. */
151  if (!gmi_exec_continue(h))
152    {
153     printf("Error in continue!\n");
154     mi_disconnect(h);
155     return 1;
156    }
157  /* Here we should be terminated. */
158  if (!wait_for_stop(h))
159    {
160     mi_disconnect(h);
161     return 1;
162    }
163
164  /* Exit from gdb. */
165  gmi_gdb_exit(h);
166  /* Close the connection. */
167  mi_disconnect(h);
168  /* Wait 5 seconds and close the auxiliar terminal. */
169  printf("Waiting 5 seconds\n");
170  sleep(5);
171  gmi_end_aux_term(xterm_tty);
172
173  return 0;
174 }