diff options
Diffstat (limited to 'src/monkey/action_api.c')
-rw-r--r-- | src/monkey/action_api.c | 187 |
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 | ||
31 | int 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 | |||
36 | extern void sendMail (const char *messageContents); | ||
37 | |||
38 | |||
39 | static int async_c=0; | ||
40 | |||
41 | |||
42 | static 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. */ | ||
49 | static void cb_target(const char *str, void *data) | ||
50 | { | ||
51 | printf("TARGET> %s\n",str); | ||
52 | } | ||
53 | |||
54 | |||
55 | static void cb_log(const char *str, void *data) | ||
56 | { | ||
57 | printf("LOG> %s\n",str); | ||
58 | } | ||
59 | |||
60 | |||
61 | static void cb_to(const char *str, void *data) | ||
62 | { | ||
63 | printf(">> %s",str); | ||
64 | } | ||
65 | |||
66 | |||
67 | static void cb_from(const char *str, void *data) | ||
68 | { | ||
69 | printf("<< %s\n",str); | ||
70 | } | ||
71 | |||
72 | |||
73 | static void cb_async(mi_output *o, void *data) | ||
74 | { | ||
75 | printf("ASYNC\n"); | ||
76 | async_c++; | ||
77 | } | ||
78 | |||
79 | |||
80 | static 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 | |||
109 | int 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 | ||
37 | int GNUNET_MONKEY_ACTION_report_email() | 119 | int 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 | ||
50 | int GNUNET_MONKEY_ACTION_rerun_with_gdb() | 135 | int 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 | |||
218 | int 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 | ||