diff options
Diffstat (limited to 'src/monkey/action_api.c')
-rw-r--r-- | src/monkey/action_api.c | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/src/monkey/action_api.c b/src/monkey/action_api.c index 0412c7630..99809f82f 100644 --- a/src/monkey/action_api.c +++ b/src/monkey/action_api.c | |||
@@ -122,12 +122,6 @@ int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt | |||
122 | } | 122 | } |
123 | 123 | ||
124 | 124 | ||
125 | |||
126 | int GNUNET_MONKEY_ACTION_rerun_with_valgrind() | ||
127 | { | ||
128 | return GNUNET_OK; | ||
129 | } | ||
130 | |||
131 | static int iterateExpressions(void *cls, int numColumns, char **colValues, char **colNames) | 125 | static int iterateExpressions(void *cls, int numColumns, char **colValues, char **colNames) |
132 | { | 126 | { |
133 | struct Expression *expression; | 127 | struct Expression *expression; |
@@ -159,10 +153,10 @@ static int scopeEndCallback(void *cls, int numColumns, char **colValues, char ** | |||
159 | 153 | ||
160 | static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt) | 154 | static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt) |
161 | { | 155 | { |
162 | struct Expression *faultyExpression; | 156 | struct Expression *faultyExpression = NULL; |
163 | struct Expression *tmp; | 157 | struct Expression *tmp; |
164 | int expressionLength = 0; | 158 | int expressionLength = 0; |
165 | mi_wp *watchPoint; | 159 | //mi_wp *watchPoint; |
166 | 160 | ||
167 | tmp = expressionListHead; | 161 | tmp = expressionListHead; |
168 | while (NULL != tmp) { | 162 | while (NULL != tmp) { |
@@ -174,23 +168,40 @@ static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt) | |||
174 | tmp = tmp->next; | 168 | tmp = tmp->next; |
175 | } | 169 | } |
176 | 170 | ||
177 | /* Set watch points on the faulty-expression's subexpressions */ | 171 | if (NULL != faultyExpression) { |
178 | tmp = expressionListHead; | 172 | tmp = expressionListHead; |
179 | while (NULL != tmp) { | 173 | while (NULL != tmp) { |
180 | if (tmp != faultyExpression) { | 174 | const char* eval; |
181 | /* Only subexpressions are interesting */ | 175 | if (tmp != faultyExpression) { |
182 | watchPoint = gmi_break_watch(cntxt->gdb_handle, wm_write, tmp->expressionSyntax); | 176 | eval = gmi_data_evaluate_expression(cntxt->gdb_handle, tmp->expressionSyntax); |
183 | if (!watchPoint) | 177 | if (NULL != eval && strcmp(eval, "0x0") == 0) { |
184 | { | 178 | cntxt->gdb_null_variable = tmp->expressionSyntax; |
185 | printf("Error in setting watchpoint\n"); | 179 | return GNUNET_OK; |
186 | return 1; | 180 | } |
187 | } | 181 | } |
188 | printf("Watchpoint %d for expression: %s\n", watchPoint->number, watchPoint->exp); | 182 | tmp = tmp->next; |
189 | mi_free_wp(watchPoint); | ||
190 | } | 183 | } |
191 | tmp = tmp->next; | ||
192 | } | 184 | } |
193 | return GNUNET_OK; | 185 | /* Set watch points on the faulty-expression's subexpressions */ |
186 | // if (NULL != faultyExpression) { | ||
187 | // tmp = expressionListHead; | ||
188 | // while (NULL != tmp) { | ||
189 | // if (tmp != faultyExpression) { | ||
190 | // /* Only subexpressions are interesting */ | ||
191 | // watchPoint = gmi_break_watch(cntxt->gdb_handle, wm_write, tmp->expressionSyntax); | ||
192 | // if (!watchPoint) | ||
193 | // { | ||
194 | // printf("Error in setting watchpoint\n"); | ||
195 | // return 1; | ||
196 | // } | ||
197 | // printf("Watchpoint %d for expression: %s\n", watchPoint->number, watchPoint->exp); | ||
198 | // mi_free_wp(watchPoint); | ||
199 | // } | ||
200 | // tmp = tmp->next; | ||
201 | // } | ||
202 | // return GNUNET_OK; | ||
203 | // } | ||
204 | return GDB_STATE_ERROR; | ||
194 | } | 205 | } |
195 | 206 | ||
196 | 207 | ||
@@ -219,13 +230,39 @@ int GNUNET_MONKEY_ACTION_inspect_expression_database(struct GNUNET_MONKEY_ACTION | |||
219 | NULL); | 230 | NULL); |
220 | 231 | ||
221 | if (strcasecmp(cntxt->gdb_stop_reason->signal_meaning, "Segmentation fault") == 0) | 232 | if (strcasecmp(cntxt->gdb_stop_reason->signal_meaning, "Segmentation fault") == 0) |
222 | analyzeSegmentationFault(cntxt); | 233 | ret = analyzeSegmentationFault(cntxt); |
223 | 234 | ||
224 | GNUNET_MONKEY_EDB_disconnect(edbCntxt); | 235 | GNUNET_MONKEY_EDB_disconnect(edbCntxt); |
236 | mi_disconnect(cntxt->gdb_handle); | ||
225 | return ret; | 237 | return ret; |
226 | } | 238 | } |
227 | 239 | ||
228 | 240 | ||
241 | int GNUNET_MONKEY_ACTION_rerun_with_valgrind(struct GNUNET_MONKEY_ACTION_Context* cntxt) { | ||
242 | FILE* valgrindPipe; | ||
243 | int size; | ||
244 | const char* valgrindCommand; | ||
245 | cntxt->debug_mode = DEBUG_MODE_VALGRIND; | ||
246 | asprintf(&valgrindCommand, "valgrind --leak-check=yes %s", cntxt->binary_name); | ||
247 | valgrindPipe = popen(valgrindCommand, "r"); | ||
248 | if (NULL == valgrindPipe) { | ||
249 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in running Valgrind!\n"); | ||
250 | return GNUNET_NO; | ||
251 | } | ||
252 | |||
253 | fscanf(valgrindPipe, "%d", &size); | ||
254 | |||
255 | /* Read Valgrind stream */ | ||
256 | cntxt->valgrind_output = GNUNET_malloc(size); | ||
257 | fscanf(valgrindPipe, "%s", cntxt->valgrind_output); | ||
258 | if (0 != pclose(valgrindPipe)) { | ||
259 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error while closing Valgrind pipe!\n"); | ||
260 | return GNUNET_NO; | ||
261 | } | ||
262 | return GNUNET_OK; | ||
263 | } | ||
264 | |||
265 | |||
229 | int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt) | 266 | int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt) |
230 | { | 267 | { |
231 | cntxt->debug_mode = DEBUG_MODE_GDB; | 268 | cntxt->debug_mode = DEBUG_MODE_GDB; |
@@ -278,7 +315,7 @@ int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cnt | |||
278 | } | 315 | } |
279 | /* Here we should be stopped when the program crashes */ | 316 | /* Here we should be stopped when the program crashes */ |
280 | ret = wait_for_stop(cntxt->gdb_handle, cntxt); | 317 | ret = wait_for_stop(cntxt->gdb_handle, cntxt); |
281 | if (ret != GDB_STATE_ERROR) | 318 | if (ret == GDB_STATE_ERROR) |
282 | mi_disconnect(cntxt->gdb_handle); | 319 | mi_disconnect(cntxt->gdb_handle); |
283 | 320 | ||
284 | return ret; | 321 | return ret; |
@@ -290,10 +327,15 @@ int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntx | |||
290 | switch (cntxt->debug_mode) { | 327 | switch (cntxt->debug_mode) { |
291 | case DEBUG_MODE_GDB: | 328 | case DEBUG_MODE_GDB: |
292 | GNUNET_asprintf(&(cntxt->debug_report), | 329 | GNUNET_asprintf(&(cntxt->debug_report), |
293 | "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n", | 330 | "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Expression:%s is NULL\n", |
294 | 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); | 331 | cntxt->gdb_frames->file, cntxt->gdb_frames->func, cntxt->gdb_frames->line, mi_reason_enum_to_str(cntxt->gdb_stop_reason->reason), |
332 | cntxt->gdb_stop_reason->signal_name, cntxt->gdb_stop_reason->signal_meaning, cntxt->gdb_null_variable); | ||
295 | break; | 333 | break; |
296 | case DEBUG_MODE_VALGRIND: | 334 | case DEBUG_MODE_VALGRIND: |
335 | GNUNET_asprintf(&(cntxt->debug_report), | ||
336 | "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Memory Check from Valgrind:%s\n", | ||
337 | cntxt->gdb_frames->file, cntxt->gdb_frames->func, cntxt->gdb_frames->line, mi_reason_enum_to_str(cntxt->gdb_stop_reason->reason), | ||
338 | cntxt->gdb_stop_reason->signal_name, cntxt->gdb_stop_reason->signal_meaning, cntxt->valgrind_output); | ||
297 | break; | 339 | break; |
298 | default: | 340 | default: |
299 | break; | 341 | break; |