From: Safey A.Halim Date: Thu, 12 May 2011 07:32:10 +0000 (+0000) Subject: Monkey supports bad memory access using Valgrind X-Git-Tag: initial-import-from-subversion-38251~18499 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=11f47e3fff7ad51a8f8076e84abb216dfe17ef19;p=oweals%2Fgnunet.git Monkey supports bad memory access using Valgrind --- 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 Binary files /dev/null and b/src/monkey/bug_bad_memory_access 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 +#include + + +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);