aboutsummaryrefslogtreecommitdiff
path: root/src/monkey/action_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/monkey/action_api.c')
-rw-r--r--src/monkey/action_api.c187
1 files changed, 184 insertions, 3 deletions
diff --git a/src/monkey/action_api.c b/src/monkey/action_api.c
index c1f39e788..6c7441ad7 100644
--- a/src/monkey/action_api.c
+++ b/src/monkey/action_api.c
@@ -26,16 +26,101 @@
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_common.h" 27#include "gnunet_common.h"
28#include "gnunet_monkey_action.h" 28#include "gnunet_monkey_action.h"
29#include <libesmtp.h>
29 30
30 31
31int GNUNET_MONKEY_ACTION_report_file() 32#define DEBUG_MODE_GDB 0
33#define DEBUG_MODE_VALGRIND 1
34#define DEBUG_MODE_REPORT_READY 2
35
36extern void sendMail (const char *messageContents);
37
38
39static int async_c=0;
40
41
42static void cb_console(const char *str, void *data)
43{
44 printf("CONSOLE> %s\n",str);
45}
46
47
48/* Note that unlike what's documented in gdb docs it isn't usable. */
49static void cb_target(const char *str, void *data)
50{
51 printf("TARGET> %s\n",str);
52}
53
54
55static void cb_log(const char *str, void *data)
56{
57 printf("LOG> %s\n",str);
58}
59
60
61static void cb_to(const char *str, void *data)
62{
63 printf(">> %s",str);
64}
65
66
67static void cb_from(const char *str, void *data)
68{
69 printf("<< %s\n",str);
70}
71
72
73static void cb_async(mi_output *o, void *data)
74{
75 printf("ASYNC\n");
76 async_c++;
77}
78
79
80static int wait_for_stop(mi_h *h)
81{
82 int res=1;
83 mi_stop *sr;
84 mi_frames *f;
85
86 while (!mi_get_response(h))
87 usleep(1000);
88 /* The end of the async. */
89 sr=mi_res_stop(h);
90 if (sr)
91 {
92 f = gmi_stack_info_frame(h);
93 if (NULL == f)
94 printf("f is NULL!\n");
95 if (NULL == f)
96 GNUNET_break(0);
97
98 mi_free_stop(sr);
99 res = 0;
100 }
101 else
102 {
103 res=0;
104 }
105 return res;
106}
107
108
109int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName)
32{ 110{
111 FILE* file = fopen(dumpFileName, "w");
112 GNUNET_assert(NULL != file);
113 fprintf(file,"%s", cntxt->debug_report);
114 fclose(file);
33 return GNUNET_OK; 115 return GNUNET_OK;
34} 116}
35 117
36 118
37int GNUNET_MONKEY_ACTION_report_email() 119int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt)
38{ 120{
121 if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY)
122 sendMail(cntxt->debug_report);
123
39 return GNUNET_OK; 124 return GNUNET_OK;
40} 125}
41 126
@@ -47,8 +132,104 @@ int GNUNET_MONKEY_ACTION_rerun_with_valgrind()
47} 132}
48 133
49 134
50int GNUNET_MONKEY_ACTION_rerun_with_gdb() 135int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt)
136{
137 cntxt->debug_mode = DEBUG_MODE_GDB;
138 mi_aux_term *xterm_tty=NULL;
139
140 /* This is like a file-handle for fopen.
141 Here we have all the state of gdb "connection". */
142 mi_h *h;
143
144 /* Connect to gdb child. */
145 h = mi_connect_local();
146 if (!h)
147 {
148 printf("Connect failed\n");
149 return GNUNET_NO;
150 }
151 printf("Connected to gdb!\n");
152
153 /* Set all callbacks. */
154 mi_set_console_cb(h,cb_console,NULL);
155 mi_set_target_cb(h,cb_target,NULL);
156 mi_set_log_cb(h,cb_log,NULL);
157 mi_set_async_cb(h,cb_async,NULL);
158 mi_set_to_gdb_cb(h,cb_to,NULL);
159 mi_set_from_gdb_cb(h,cb_from,NULL);
160
161 /* Set the name of the child and the command line aguments. */
162 if (!gmi_set_exec(h, cntxt->binary_name, NULL))
163 {
164 printf("Error setting exec y args\n");
165 mi_disconnect(h);
166 return GNUNET_NO;
167 }
168
169 /* Tell gdb to attach the child to a terminal. */
170 if (!gmi_target_terminal(h, ttyname(STDIN_FILENO)))
171 {
172 printf("Error selecting target terminal\n");
173 mi_disconnect(h);
174 return GNUNET_NO;
175 }
176
177 /* Run the program. */
178 if (!gmi_exec_run(h))
179 {
180 printf("Error in run!\n");
181 mi_disconnect(h);
182 return GNUNET_NO;
183 }
184 /* Here we should be stopped when the program crashes */
185 if (!wait_for_stop(h))
186 {
187 mi_disconnect(h);
188 return GNUNET_NO;
189 }
190
191 /* Continue execution. */
192 if (!gmi_exec_continue(h))
193 {
194 printf("Error in continue!\n");
195 mi_disconnect(h);
196 return GNUNET_NO;
197 }
198 /* Here we should be terminated. */
199 if (!wait_for_stop(h))
200 {
201 mi_disconnect(h);
202 return GNUNET_NO;
203 }
204
205 /* Exit from gdb. */
206 gmi_gdb_exit(h);
207 /* Close the connection. */
208 mi_disconnect(h);
209 /* Wait 5 seconds and close the auxiliar terminal. */
210 printf("Waiting 5 seconds\n");
211 sleep(5);
212 gmi_end_aux_term(xterm_tty);
213
214 return GNUNET_OK;
215}
216
217
218int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt)
51{ 219{
220 switch (cntxt->debug_mode) {
221 case DEBUG_MODE_GDB:
222 GNUNET_asprintf(&cntxt->debug_report,
223 "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n",
224 cntxt->gdb_frames->file, cntxt->gdb_frames->func, cntxt->gdb_frames->line, mi_reason_enum_to_str(cntxt->gdb_stop_reason->reason), cntxt->gdb_stop_reason->signal_name, cntxt->gdb_stop_reason->signal_meaning);
225 break;
226 case DEBUG_MODE_VALGRIND:
227 break;
228 default:
229 break;
230 }
231
232 cntxt->debug_mode = DEBUG_MODE_REPORT_READY;
52 return GNUNET_OK; 233 return GNUNET_OK;
53} 234}
54 235