aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/monkey/Makefile.am6
-rw-r--r--src/monkey/action_api.c96
-rwxr-xr-xsrc/monkey/bug_bad_memory_accessbin0 -> 9226 bytes
-rw-r--r--src/monkey/bug_bad_memory_access.c16
-rw-r--r--src/monkey/gnunet-monkey.c12
-rw-r--r--src/monkey/gnunet_monkey_action.h6
6 files changed, 106 insertions, 30 deletions
diff --git a/src/monkey/Makefile.am b/src/monkey/Makefile.am
index 44042dfdd..effa37bd4 100644
--- a/src/monkey/Makefile.am
+++ b/src/monkey/Makefile.am
@@ -40,7 +40,8 @@ bin_PROGRAMS = \
40 gnunet-service-monkey 40 gnunet-service-monkey
41 41
42noinst_PROGRAMS = \ 42noinst_PROGRAMS = \
43 bug_null_pointer_exception 43 bug_null_pointer_exception \
44 bug_bad_memory_access
44 45
45gnunet_monkey_SOURCES = \ 46gnunet_monkey_SOURCES = \
46 gdbmi.h \ 47 gdbmi.h \
@@ -80,6 +81,9 @@ gnunet_service_monkey_LDADD = \
80bug_null_pointer_exception: 81bug_null_pointer_exception:
81 gcc -g -O0 -o bug_null_pointer_exception bug_null_pointer_exception.c 82 gcc -g -O0 -o bug_null_pointer_exception bug_null_pointer_exception.c
82 83
84bug_bad_memory_access:
85 gcc -g -O0 -o bug_bad_memory_access bug_bad_memory_access.c
86
83check_PROGRAMS = \ 87check_PROGRAMS = \
84 test_monkey_edb 88 test_monkey_edb
85 #test_gnunet_monkey 89 #test_gnunet_monkey
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
126int GNUNET_MONKEY_ACTION_rerun_with_valgrind()
127{
128 return GNUNET_OK;
129}
130
131static int iterateExpressions(void *cls, int numColumns, char **colValues, char **colNames) 125static 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
160static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt) 154static 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
241int 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
229int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt) 266int 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;
diff --git a/src/monkey/bug_bad_memory_access b/src/monkey/bug_bad_memory_access
new file mode 100755
index 000000000..ddd87c243
--- /dev/null
+++ b/src/monkey/bug_bad_memory_access
Binary files differ
diff --git a/src/monkey/bug_bad_memory_access.c b/src/monkey/bug_bad_memory_access.c
new file mode 100644
index 000000000..54e50ade0
--- /dev/null
+++ b/src/monkey/bug_bad_memory_access.c
@@ -0,0 +1,16 @@
1#include <stdio.h>
2#include <string.h>
3
4
5void badMemoryAccess()
6{
7 int *p = (int*) 0x4252352;
8 printf("Bad memory access now!\n");
9 *p = 5;
10}
11
12int main(int argc, char *argv[])
13{
14 badMemoryAccess();
15 return 0;
16}
diff --git a/src/monkey/gnunet-monkey.c b/src/monkey/gnunet-monkey.c
index 7821936bf..030eb0774 100644
--- a/src/monkey/gnunet-monkey.c
+++ b/src/monkey/gnunet-monkey.c
@@ -77,6 +77,7 @@ run (void *cls,
77 77
78 result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt); 78 result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt);
79 switch (result) { 79 switch (result) {
80 int retVal;
80 case GDB_STATE_ERROR: 81 case GDB_STATE_ERROR:
81 break; 82 break;
82 case GDB_STATE_EXIT_NORMALLY: 83 case GDB_STATE_EXIT_NORMALLY:
@@ -85,10 +86,19 @@ run (void *cls,
85 break; 86 break;
86 case GDB_STATE_STOPPED: 87 case GDB_STATE_STOPPED:
87 /*FIXME: Expression Database should be inspected here (before writing the report) */ 88 /*FIXME: Expression Database should be inspected here (before writing the report) */
88 if (GNUNET_OK != GNUNET_MONKEY_ACTION_inspect_expression_database(cntxt)) { 89 retVal = GNUNET_MONKEY_ACTION_inspect_expression_database(cntxt);
90 if (GNUNET_NO == retVal) {
89 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using Expression Database!\n"); 91 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using Expression Database!\n");
90 ret = 1; 92 ret = 1;
91 break; 93 break;
94 } else if (GDB_STATE_ERROR == retVal) {
95 /* GDB could not locate a NULL value expression, launch Valgrind */
96 retVal = GNUNET_MONKEY_ACTION_rerun_with_valgrind(cntxt);
97 if (GNUNET_NO == retVal) {
98 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using Valgrind!\n");
99 ret = 1;
100 break;
101 }
92 } 102 }
93 if(GNUNET_OK != GNUNET_MONKEY_ACTION_format_report(cntxt)){ 103 if(GNUNET_OK != GNUNET_MONKEY_ACTION_format_report(cntxt)){
94 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in generating debug report!\n"); 104 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in generating debug report!\n");
diff --git a/src/monkey/gnunet_monkey_action.h b/src/monkey/gnunet_monkey_action.h
index dd96a03a5..d8af8d712 100644
--- a/src/monkey/gnunet_monkey_action.h
+++ b/src/monkey/gnunet_monkey_action.h
@@ -63,14 +63,18 @@ struct GNUNET_MONKEY_ACTION_Context
63 const char* gdb_in_use; 63 const char* gdb_in_use;
64 mi_stop* gdb_stop_reason; 64 mi_stop* gdb_stop_reason;
65 mi_frames* gdb_frames; 65 mi_frames* gdb_frames;
66 const char* gdb_null_variable;
67
68 /* Valgrind memcheck attributes */
69 char* valgrind_output;
66}; 70};
67 71
68 72
69int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName); 73int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName);
70int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt); 74int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt);
71int GNUNET_MONKEY_ACTION_rerun_with_valgrind(void);
72int GNUNET_MONKEY_ACTION_inspect_expression_database(struct GNUNET_MONKEY_ACTION_Context* cntxt); 75int GNUNET_MONKEY_ACTION_inspect_expression_database(struct GNUNET_MONKEY_ACTION_Context* cntxt);
73int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt); 76int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt);
77int GNUNET_MONKEY_ACTION_rerun_with_valgrind(struct GNUNET_MONKEY_ACTION_Context* cntxt);
74int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt); 78int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt);
75int GNUNET_MONKEY_ACTION_check_bug_redundancy(void); 79int GNUNET_MONKEY_ACTION_check_bug_redundancy(void);
76 80