summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSafey A.Halim <safey.allah@gmail.com>2011-05-12 07:32:10 +0000
committerSafey A.Halim <safey.allah@gmail.com>2011-05-12 07:32:10 +0000
commit11f47e3fff7ad51a8f8076e84abb216dfe17ef19 (patch)
tree10c213cf6b90200a57d98aeec5408c79799152c1 /src
parent3117911a77e121fb729411d29c4929332934ba42 (diff)
Monkey supports bad memory access using Valgrind
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 = \
gnunet-service-monkey
noinst_PROGRAMS = \
- bug_null_pointer_exception
+ bug_null_pointer_exception \
+ bug_bad_memory_access
gnunet_monkey_SOURCES = \
gdbmi.h \
@@ -80,6 +81,9 @@ gnunet_service_monkey_LDADD = \
bug_null_pointer_exception:
gcc -g -O0 -o bug_null_pointer_exception bug_null_pointer_exception.c
+bug_bad_memory_access:
+ gcc -g -O0 -o bug_bad_memory_access bug_bad_memory_access.c
+
check_PROGRAMS = \
test_monkey_edb
#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
}
-
-int GNUNET_MONKEY_ACTION_rerun_with_valgrind()
-{
- return GNUNET_OK;
-}
-
static int iterateExpressions(void *cls, int numColumns, char **colValues, char **colNames)
{
struct Expression *expression;
@@ -159,10 +153,10 @@ static int scopeEndCallback(void *cls, int numColumns, char **colValues, char **
static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt)
{
- struct Expression *faultyExpression;
+ struct Expression *faultyExpression = NULL;
struct Expression *tmp;
int expressionLength = 0;
- mi_wp *watchPoint;
+ //mi_wp *watchPoint;
tmp = expressionListHead;
while (NULL != tmp) {
@@ -174,23 +168,40 @@ static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt)
tmp = tmp->next;
}
- /* Set watch points on the faulty-expression's subexpressions */
- tmp = expressionListHead;
- while (NULL != tmp) {
- if (tmp != faultyExpression) {
- /* Only subexpressions are interesting */
- watchPoint = gmi_break_watch(cntxt->gdb_handle, wm_write, tmp->expressionSyntax);
- if (!watchPoint)
- {
- printf("Error in setting watchpoint\n");
- return 1;
- }
- printf("Watchpoint %d for expression: %s\n", watchPoint->number, watchPoint->exp);
- mi_free_wp(watchPoint);
+ if (NULL != faultyExpression) {
+ tmp = expressionListHead;
+ while (NULL != tmp) {
+ const char* eval;
+ if (tmp != faultyExpression) {
+ eval = gmi_data_evaluate_expression(cntxt->gdb_handle, tmp->expressionSyntax);
+ if (NULL != eval && strcmp(eval, "0x0") == 0) {
+ cntxt->gdb_null_variable = tmp->expressionSyntax;
+ return GNUNET_OK;
+ }
+ }
+ tmp = tmp->next;
}
- tmp = tmp->next;
}
- return GNUNET_OK;
+ /* Set watch points on the faulty-expression's subexpressions */
+// if (NULL != faultyExpression) {
+// tmp = expressionListHead;
+// while (NULL != tmp) {
+// if (tmp != faultyExpression) {
+// /* Only subexpressions are interesting */
+// watchPoint = gmi_break_watch(cntxt->gdb_handle, wm_write, tmp->expressionSyntax);
+// if (!watchPoint)
+// {
+// printf("Error in setting watchpoint\n");
+// return 1;
+// }
+// printf("Watchpoint %d for expression: %s\n", watchPoint->number, watchPoint->exp);
+// mi_free_wp(watchPoint);
+// }
+// tmp = tmp->next;
+// }
+// return GNUNET_OK;
+// }
+ return GDB_STATE_ERROR;
}
@@ -219,13 +230,39 @@ int GNUNET_MONKEY_ACTION_inspect_expression_database(struct GNUNET_MONKEY_ACTION
NULL);
if (strcasecmp(cntxt->gdb_stop_reason->signal_meaning, "Segmentation fault") == 0)
- analyzeSegmentationFault(cntxt);
+ ret = analyzeSegmentationFault(cntxt);
GNUNET_MONKEY_EDB_disconnect(edbCntxt);
+ mi_disconnect(cntxt->gdb_handle);
return ret;
}
+int GNUNET_MONKEY_ACTION_rerun_with_valgrind(struct GNUNET_MONKEY_ACTION_Context* cntxt) {
+ FILE* valgrindPipe;
+ int size;
+ const char* valgrindCommand;
+ cntxt->debug_mode = DEBUG_MODE_VALGRIND;
+ asprintf(&valgrindCommand, "valgrind --leak-check=yes %s", cntxt->binary_name);
+ valgrindPipe = popen(valgrindCommand, "r");
+ if (NULL == valgrindPipe) {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in running Valgrind!\n");
+ return GNUNET_NO;
+ }
+
+ fscanf(valgrindPipe, "%d", &size);
+
+ /* Read Valgrind stream */
+ cntxt->valgrind_output = GNUNET_malloc(size);
+ fscanf(valgrindPipe, "%s", cntxt->valgrind_output);
+ if (0 != pclose(valgrindPipe)) {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error while closing Valgrind pipe!\n");
+ return GNUNET_NO;
+ }
+ return GNUNET_OK;
+}
+
+
int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt)
{
cntxt->debug_mode = DEBUG_MODE_GDB;
@@ -278,7 +315,7 @@ int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cnt
}
/* Here we should be stopped when the program crashes */
ret = wait_for_stop(cntxt->gdb_handle, cntxt);
- if (ret != GDB_STATE_ERROR)
+ if (ret == GDB_STATE_ERROR)
mi_disconnect(cntxt->gdb_handle);
return ret;
@@ -290,10 +327,15 @@ int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntx
switch (cntxt->debug_mode) {
case DEBUG_MODE_GDB:
GNUNET_asprintf(&(cntxt->debug_report),
- "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n",
- 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);
+ "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Expression:%s is NULL\n",
+ 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, cntxt->gdb_null_variable);
break;
case DEBUG_MODE_VALGRIND:
+ GNUNET_asprintf(&(cntxt->debug_report),
+ "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",
+ 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, cntxt->valgrind_output);
break;
default:
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 @@
+#include <stdio.h>
+#include <string.h>
+
+
+void badMemoryAccess()
+{
+ int *p = (int*) 0x4252352;
+ printf("Bad memory access now!\n");
+ *p = 5;
+}
+
+int main(int argc, char *argv[])
+{
+ badMemoryAccess();
+ return 0;
+}
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,
result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt);
switch (result) {
+ int retVal;
case GDB_STATE_ERROR:
break;
case GDB_STATE_EXIT_NORMALLY:
@@ -85,10 +86,19 @@ run (void *cls,
break;
case GDB_STATE_STOPPED:
/*FIXME: Expression Database should be inspected here (before writing the report) */
- if (GNUNET_OK != GNUNET_MONKEY_ACTION_inspect_expression_database(cntxt)) {
+ retVal = GNUNET_MONKEY_ACTION_inspect_expression_database(cntxt);
+ if (GNUNET_NO == retVal) {
GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using Expression Database!\n");
ret = 1;
break;
+ } else if (GDB_STATE_ERROR == retVal) {
+ /* GDB could not locate a NULL value expression, launch Valgrind */
+ retVal = GNUNET_MONKEY_ACTION_rerun_with_valgrind(cntxt);
+ if (GNUNET_NO == retVal) {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using Valgrind!\n");
+ ret = 1;
+ break;
+ }
}
if(GNUNET_OK != GNUNET_MONKEY_ACTION_format_report(cntxt)){
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
const char* gdb_in_use;
mi_stop* gdb_stop_reason;
mi_frames* gdb_frames;
+ const char* gdb_null_variable;
+
+ /* Valgrind memcheck attributes */
+ char* valgrind_output;
};
int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName);
int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt);
-int GNUNET_MONKEY_ACTION_rerun_with_valgrind(void);
int GNUNET_MONKEY_ACTION_inspect_expression_database(struct GNUNET_MONKEY_ACTION_Context* cntxt);
int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt);
+int GNUNET_MONKEY_ACTION_rerun_with_valgrind(struct GNUNET_MONKEY_ACTION_Context* cntxt);
int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt);
int GNUNET_MONKEY_ACTION_check_bug_redundancy(void);