From: Safey A.Halim Date: Tue, 14 Jun 2011 21:49:52 +0000 (+0000) Subject: Memory leak problem fixed when running Monkey with Valgrind. X-Git-Tag: initial-import-from-subversion-38251~18208 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=05e166a26ab3c6aef34478e006b04324222b3446;p=oweals%2Fgnunet.git Memory leak problem fixed when running Monkey with Valgrind. "assert" debugging supported. Watch a user defined expression supported (crypto_crc performance analysis test is not working properly) --- diff --git a/src/monkey/Makefile.am b/src/monkey/Makefile.am index 1f048070e..ab265daa0 100644 --- a/src/monkey/Makefile.am +++ b/src/monkey/Makefile.am @@ -42,7 +42,8 @@ bin_PROGRAMS = \ noinst_PROGRAMS = \ bug_null_pointer_exception \ bug_bad_memory_access \ - bug_assertion_failure + bug_assertion_failure \ + bug_crypto_crc gnunet_monkey_SOURCES = \ gdbmi.h \ @@ -88,6 +89,9 @@ bug_bad_memory_access: bug_assertion_failure: gcc -g -O0 -o bug_assertion_failure bug_assertion_failure.c +bug_crypto_crc: + gcc -g -O0 -o bug_crypto_crc bug_crypto_crc.c + check_PROGRAMS = \ test_monkey_edb #test_gnunet_monkey diff --git a/src/monkey/action_api.c b/src/monkey/action_api.c index be160af5f..045f4109f 100644 --- a/src/monkey/action_api.c +++ b/src/monkey/action_api.c @@ -36,15 +36,28 @@ extern void sendMail (const char *messageContents, const char *emailAddress); static int async_c = 0; static struct Expression *expressionListHead = NULL; static struct Expression *expressionListTail = NULL; +static struct WatchInfo *watchInfoListHead = NULL; +static struct WatchInfo *watchInfoListTail = NULL; +static struct Expression *faultyExpression = NULL; struct Expression { struct Expression *next; struct Expression *prev; const char *expressionSyntax; + const char *expressionValue; int lineNo; }; +struct WatchInfo +{ + struct WatchInfo *next; + struct WatchInfo *prev; + int hitNumber; + const char *value; +}; + + static void cb_console (const char *str, void *data) { @@ -90,20 +103,48 @@ cb_async (mi_output * o, void *data) static int -wait_for_stop (mi_h * h, struct GNUNET_MONKEY_ACTION_Context *cntxt) +wait_for_stop (struct GNUNET_MONKEY_ACTION_Context *cntxt) { - while (!mi_get_response (h)) + while (!mi_get_response (cntxt->gdb_handle)) usleep (1000); /* The end of the async. */ - cntxt->gdb_stop_reason = mi_res_stop (h); + cntxt->gdb_stop_reason = mi_res_stop (cntxt->gdb_handle); if (cntxt->gdb_stop_reason) { if (cntxt->gdb_stop_reason->reason == sr_exited_normally) - return GDB_STATE_EXIT_NORMALLY; - - cntxt->gdb_frames = gmi_stack_info_frame (h); + return GDB_STATE_EXIT_NORMALLY; + else if (cntxt->gdb_stop_reason->reason == sr_bkpt_hit) { + /* We want to inspect an expression */ + /* Set hardware watch at the expression to inspect */ + mi_wp *wp = gmi_break_watch(cntxt->gdb_handle, wm_write, cntxt->inspect_expression); + if (NULL == wp) + { + printf("Error in setting a watchpoint at expression:%s\n", cntxt->inspect_expression); + return GDB_STATE_ERROR; + } + mi_free_wp(wp); + /* continue execution */ + gmi_exec_continue(cntxt->gdb_handle); + return wait_for_stop (cntxt); + } + else if (cntxt->gdb_stop_reason->reason == sr_wp_trigger) { + static int watchPointHitNumber = 0; + struct WatchInfo *watchInfo = GNUNET_malloc(sizeof(struct WatchInfo)); + watchInfo->hitNumber = ++watchPointHitNumber; + watchInfo->value = cntxt->gdb_stop_reason->wp_val; + GNUNET_CONTAINER_DLL_insert(watchInfoListHead, watchInfoListTail, watchInfo); + if (watchPointHitNumber == 1023) + printf("HEY! 1023! WE ARE GETTING OUT OF THE LOOP!\n"); + gmi_exec_continue(cntxt->gdb_handle); + return wait_for_stop (cntxt); + } + else if (cntxt->gdb_stop_reason->reason == sr_wp_scope) { + gmi_exec_continue(cntxt->gdb_handle); + return wait_for_stop (cntxt); + } + cntxt->gdb_frames = gmi_stack_info_frame (cntxt->gdb_handle); if (NULL == cntxt->gdb_frames) - GNUNET_break (0); + GNUNET_break (0); if (0 == cntxt->gdb_frames->line) { @@ -118,6 +159,8 @@ wait_for_stop (mi_h * h, struct GNUNET_MONKEY_ACTION_Context *cntxt) } while (0 == cntxt->gdb_frames->line); } + /* Change current GDB frame to the one containing source code */ + gmi_stack_select_frame(cntxt->gdb_handle, cntxt->gdb_frames->level); return GDB_STATE_STOPPED; } @@ -160,7 +203,6 @@ iterateExpressions (void *cls, int numColumns, char **colValues, expression->expressionSyntax = strdup (colValues[0]); expression->lineNo = atoi (colValues[1]); - printf ("Inserting expression:%s", expression->expressionSyntax); GNUNET_CONTAINER_DLL_insert (expressionListHead, expressionListTail, expression); @@ -206,7 +248,6 @@ getFaultyExpression (struct GNUNET_MONKEY_ACTION_Context *cntxt) static int analyzeSegmentationFault (struct GNUNET_MONKEY_ACTION_Context *cntxt) { - struct Expression *faultyExpression = NULL; struct Expression *tmp; @@ -262,26 +303,21 @@ static int analyzeCustomFault (struct GNUNET_MONKEY_ACTION_Context *cntxt) { struct Expression *tmp; - struct Expression *faultyExpression = getFaultyExpression (cntxt); - struct Variable *variable; + faultyExpression = getFaultyExpression (cntxt); + + if (NULL != faultyExpression) { tmp = expressionListHead; while (NULL != tmp) { const char *eval; - if (tmp != faultyExpression) - { eval = gmi_data_evaluate_expression (cntxt->gdb_handle, tmp->expressionSyntax); - variable = GNUNET_malloc (sizeof (struct Variable)); - variable->name = tmp->expressionSyntax; - variable->value = eval; - GNUNET_CONTAINER_DLL_insert (cntxt->variable_list_head, - cntxt->variable_list_tail, - variable); - } + if (NULL != eval) { + tmp->expressionValue = eval; + } tmp = tmp->next; } } @@ -315,19 +351,23 @@ GNUNET_MONKEY_ACTION_inspect_expression_database (struct if (endScope < 0) return GNUNET_NO; - ret = GNUNET_MONKEY_EDB_get_expressions (edbCntxt, - cntxt->gdb_frames->file, - cntxt->gdb_frames->line, endScope, - &iterateExpressions, NULL); if (strcasecmp (signalMeaning, "Segmentation fault") == 0) { cntxt->bug_detected = BUG_NULL_POINTER; + GNUNET_MONKEY_EDB_get_expressions (edbCntxt, + cntxt->gdb_frames->file, + cntxt->gdb_frames->line, endScope, + &iterateExpressions, NULL); ret = analyzeSegmentationFault (cntxt); } else if (strcasecmp (signalMeaning, "Aborted") == 0) { cntxt->bug_detected = BUG_CUSTOM; + GNUNET_MONKEY_EDB_get_sub_expressions (edbCntxt, + cntxt->gdb_frames->file, + cntxt->gdb_frames->line, endScope, + &iterateExpressions, NULL); ret = analyzeCustomFault (cntxt); } @@ -341,12 +381,13 @@ int GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct GNUNET_MONKEY_ACTION_Context *cntxt) { - FILE *valgrindPipe; - int size; char *valgrindCommand; + FILE *valgrindPipe; + + GNUNET_asprintf(&cntxt->valgrind_output_tmp_file_name, "%d", rand()); cntxt->debug_mode = DEBUG_MODE_VALGRIND; - GNUNET_asprintf (&valgrindCommand, "valgrind --leak-check=yes %s", - cntxt->binary_name); + GNUNET_asprintf (&valgrindCommand, "valgrind --leak-check=yes --log-file=%s %s", + cntxt->valgrind_output_tmp_file_name, cntxt->binary_name); valgrindPipe = popen (valgrindCommand, "r"); if (NULL == valgrindPipe) { @@ -355,18 +396,8 @@ GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct GNUNET_MONKEY_ACTION_Context return GNUNET_NO; } - fscanf (valgrindPipe, "%d", &size); - - /* Read Valgrind stream */ - cntxt->valgrind_output = GNUNET_malloc (size); - fscanf (valgrindPipe, "%s", cntxt->valgrind_output); - GNUNET_free (valgrindCommand); - if (0 != pclose (valgrindPipe)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error while closing Valgrind pipe!\n"); - return GNUNET_NO; - } + pclose(valgrindPipe); + GNUNET_free(valgrindCommand); return GNUNET_OK; } @@ -375,7 +406,6 @@ int GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context *cntxt) { - mi_wp *watchPoint; cntxt->debug_mode = DEBUG_MODE_GDB; /* This is like a file-handle for fopen. Here we have all the state of gdb "connection". */ @@ -416,17 +446,17 @@ GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context return GNUNET_NO; } - if (NULL != cntxt->inspect_expression) + if ((NULL != cntxt->inspect_expression) && (NULL != cntxt->inspect_function)) { - watchPoint = - gmi_break_watch (cntxt->gdb_handle, wm_write, - cntxt->inspect_expression); - if (NULL == watchPoint) - { - printf ("Error in setting watch point\n"); - mi_disconnect (cntxt->gdb_handle); - return GNUNET_NO; - } + /* Setting a breakpoint at the function containing the expression to inspect */ + mi_bkpt *bp = gmi_break_insert_full(cntxt->gdb_handle, 0, 0, NULL, -1, -1, cntxt->inspect_function); + if (NULL == bp) + { + printf("Error setting breakpoint at function:%s\n", cntxt->inspect_function); + mi_disconnect(cntxt->gdb_handle); + return GNUNET_NO; + } + mi_free_bkpt(bp); } /* Run the program. */ @@ -437,26 +467,45 @@ GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context return GNUNET_NO; } /* Here we should be stopped when the program crashes */ - ret = wait_for_stop (cntxt->gdb_handle, cntxt); + ret = wait_for_stop (cntxt); if (ret == GDB_STATE_ERROR) mi_disconnect (cntxt->gdb_handle); return ret; } + +static int +getExpressionListSize(struct Expression *head) +{ + int size, count = 0; + struct Expression *tmp = head; + + while (NULL != tmp) { + count++; + tmp = tmp->next; + } + /* Since the faulty expression is the longest in the expression list */ + size = count * strlen(faultyExpression->expressionSyntax) * sizeof(char); + return size; +} + + static const char * -variableListToString (struct Variable *head) +expressionListToString (struct Expression *head) { - char *string = GNUNET_malloc (200 * sizeof (char)); + char *string = GNUNET_malloc (getExpressionListSize(head)); char *strTmp; - struct Variable *tmp = head; + struct Expression *tmp = head; - GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->name, tmp->value); + GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->expressionSyntax, NULL == tmp->expressionValue ? "Not evaluated" : tmp->expressionValue); strcpy (string, strTmp); GNUNET_free (strTmp); + tmp = tmp->next; + while (NULL != tmp) { - GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->name, tmp->value); + GNUNET_asprintf (&strTmp, "%s = %s\n", tmp->expressionSyntax, NULL == tmp->expressionValue ? "Not evaluated" : tmp->expressionValue); strcat (string, strTmp); GNUNET_free (strTmp); tmp = tmp->next; @@ -465,6 +514,61 @@ variableListToString (struct Variable *head) } +static int +getWatchInfoListSize(struct WatchInfo *head) +{ + int count = 0; + int largestStr = 0; + struct WatchInfo *tmp = head; + + while (NULL != tmp) { + if (largestStr < strlen(tmp->value)) + largestStr = strlen(tmp->value); + tmp = tmp->next; + count++; + } + + return count * largestStr; +} + +static const char* +watchInfoListToString(struct WatchInfo *head) +{ + char *string = GNUNET_malloc(getWatchInfoListSize(head)); + char *strTmp; + struct WatchInfo *tmp = head; + + GNUNET_asprintf (&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value); + strcpy (string, strTmp); + GNUNET_free (strTmp); + tmp = tmp->next; + + while (NULL != tmp) { + GNUNET_asprintf (&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value); + strcat (string, strTmp); + GNUNET_free(strTmp); + tmp = tmp->next; + } + + return string; +} + +static const char* getValgrindOutput(struct GNUNET_MONKEY_ACTION_Context *cntxt) +{ + char* valgrindOutput; + int size; + FILE *valgrindFile = fopen(cntxt->valgrind_output_tmp_file_name, "r"); + fseek(valgrindFile, 0L, SEEK_END); + size = ftell(valgrindFile); + fseek(valgrindFile, 0L, SEEK_SET); + + valgrindOutput = GNUNET_malloc(size); + fread(valgrindOutput, size, 1, valgrindFile); + fclose(valgrindFile); + return valgrindOutput; +} + + int GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context *cntxt) @@ -489,45 +593,35 @@ GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context if (NULL == cntxt->inspect_expression) { /* Assertion Failure */ + const char *expToString = expressionListToString(expressionListHead); GNUNET_asprintf (&(cntxt->debug_report), - "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Assertion Failure\n Expression evaluation:\n", + "Bug detected in file:%s\nfunction:%s\nline:%d\nreceived signal:%s\n%s\nDetails:\nAssertion Failure\nExpression evaluation:\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, - variableListToString (cntxt-> - variable_list_head)); + expToString); } else { - /* Failure in a user-defined expression */ - GNUNET_asprintf (&(cntxt->debug_report), - "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n Details:\n Failure in user-defined expression:%s\n Expression evaluation:\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->inspect_expression, - variableListToString (cntxt-> - variable_list_head)); + /* Inspection of user-defined expression */ + /* + GNUNET_asprintf(&(cntxt->debug_report), + "Inspection of expression: %s in function: %s, file:%s\nHit Number: \t \tValue:\n%s", + cntxt->inspect_expression, cntxt->inspect_function, cntxt->binary_name, watchInfoListToString(watchInfoListHead)); + */ } } 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", + "Bug detected in file:%s\nfunction:%s\nline:%d\nreceived signal:%s\n%s\n Details:\n Memory Check from Valgrind:\n%s", 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); + getValgrindOutput(cntxt)); break; default: break; @@ -538,6 +632,21 @@ GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context } +int +GNUNET_MONKEY_ACTION_delete_context(struct GNUNET_MONKEY_ACTION_Context *cntxt) +{ + if (NULL != cntxt->debug_report) + GNUNET_free(cntxt->debug_report); + if (NULL != cntxt->valgrind_output_tmp_file_name) { + remove(cntxt->valgrind_output_tmp_file_name); + GNUNET_free(cntxt->valgrind_output_tmp_file_name); + } + + GNUNET_free(cntxt); + return GNUNET_OK; +} + + int GNUNET_MONKEY_ACTION_check_bug_redundancy () { diff --git a/src/monkey/bug_crypto_crc.c b/src/monkey/bug_crypto_crc.c new file mode 100644 index 000000000..efe9d7ec4 --- /dev/null +++ b/src/monkey/bug_crypto_crc.c @@ -0,0 +1,120 @@ +/* + This file is part of GNUnet. + (C) 2001, 2002, 2003, 2004, 2006 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + For the actual CRC code: + Copyright abandoned; this code is in the public domain. + Provided to GNUnet by peter@horizon.com +*/ + +/** + * @file monkey/bug_crypto_crc.c + * @brief implementation of CRC32 (this code has been copied from GNUnet util source directory, and modified to be Seaspider friendly) + * @author Christian Grothoff, Safey A.Halim + */ + +#include "assert.h" +#include "stdlib.h" +#include "stdio.h" + +#define Z_NULL 0 + + +#define POLYNOMIAL (unsigned long)0xedb88320 +static unsigned long crc_table[256]; + +/* + * This routine writes each crc_table entry exactly once, + * with the ccorrect final value. Thus, it is safe to call + * even on a table that someone else is using concurrently. + */ +static void +crc_init () +{ + static int once; + unsigned int i, j; + unsigned long h = 1; + + if (once) + return; + once = 1; + crc_table[0] = 0; + for (i = 128; i; i >>= 1) + { + h = (h >> 1) ^ ((h & 1) ? POLYNOMIAL : 0); + /* h is now crc_table[i] */ + for (j = 0; j < 256; j += 2 * i) + crc_table[i + j] = crc_table[j] ^ h; + } +} + +/* + * This computes the standard preset and inverted CRC, as used + * by most networking standards. Start by passing in an initial + * chaining value of 0, and then pass in the return value from the + * previous crc32() call. The final return value is the CRC. + * Note that this is a little-endian CRC, which is best used with + * data transmitted lsbit-first, and it should, itself, be appended + * to data in little-endian byte and bit order to preserve the + * property of detecting all burst errors of length 32 bits or less. + */ +static unsigned long +crc_go (unsigned long crc, const char *buf, size_t len) +{ + crc_init (); + assert (crc_table[255] != 0); + crc ^= 0xffffffff; + while (len--) + crc = (crc >> 8) ^ crc_table[(crc ^ *buf++) & 0xff]; + return crc ^ 0xffffffff; +} + + +/** + * Compute the CRC32 checksum for the first len bytes of the buffer. + * + * @param buf the data over which we're taking the CRC + * @param len the length of the buffer + * @return the resulting CRC32 checksum + */ +int32_t +GNUNET_CRYPTO_crc32_n (const void *buf, size_t len) +{ + unsigned long crc; + crc = crc_go (0L, Z_NULL, 0); + crc = crc_go (crc, (char *) buf, len); + return crc; +} + + +int main () +{ + char buf[1024]; + int i; + for (i = 0; i < 1024; i++) + { + buf[i] = (char) i; + } + for (i = 0; i < 1024; i++) + { + printf("%d\n", GNUNET_CRYPTO_crc32_n (&buf[i], 1024 - i)); + } + return 0; +} + +/* end of bug_crypto_crc.c */ diff --git a/src/monkey/edb_api.c b/src/monkey/edb_api.c index 65b16a4a6..296d7c838 100644 --- a/src/monkey/edb_api.c +++ b/src/monkey/edb_api.c @@ -159,3 +159,36 @@ GNUNET_MONKEY_EDB_get_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt, } return GNUNET_OK; } + + +int +GNUNET_MONKEY_EDB_get_sub_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt, + const char *file_name, int start_line_no, + int end_line_no, + GNUNET_MONKEY_ExpressionIterator iter, + void *iter_cls) +{ + int err; + char *errMsg; + char *query; + if (asprintf + (&query, + "select expr_syntax, start_lineno from Expression where file_name LIKE \'%%/%s\' and start_lineno = %d and end_lineno = %d", + file_name, start_line_no, end_line_no) == -1) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Memory allocation problem occurred!\n"); + return GNUNET_NO; + } + + err = sqlite3_exec (cntxt->db_handle, query, iter, iter_cls, &errMsg); + if (err) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error occurred while executing Database query. `%s'", + errMsg); + return GNUNET_NO; + } + return GNUNET_OK; +} + diff --git a/src/monkey/gnunet-monkey.c b/src/monkey/gnunet-monkey.c index 1019a87a0..18d9abf32 100644 --- a/src/monkey/gnunet-monkey.c +++ b/src/monkey/gnunet-monkey.c @@ -37,6 +37,7 @@ static const char *emailAddress; static const char *edbFilePath; static const char *gdbBinaryPath; static const char *inspectExpression; +static const char *inspectFunction; static int ret = 0; /** @@ -82,6 +83,7 @@ run (void *cls, cntxt->expression_database_path = edbFilePath; cntxt->gdb_binary_path = gdbBinaryPath; cntxt->inspect_expression = inspectExpression; + cntxt->inspect_function = inspectFunction; result = GNUNET_MONKEY_ACTION_rerun_with_gdb (cntxt); switch (result) @@ -144,6 +146,7 @@ run (void *cls, default: break; } + GNUNET_MONKEY_ACTION_delete_context(cntxt); } @@ -170,7 +173,9 @@ main (int argc, char *argv[]) {'g', "gdb", NULL, gettext_noop ("path to gdb binary in use; default is /usr/bin/gdb"), GNUNET_YES, &GNUNET_GETOPT_set_string, &gdbBinaryPath}, - {'i', "inspect", NULL, gettext_noop ("A custom expression to inspect"), + {'f', "function", NULL, gettext_noop ("Monkey will set a breakpoint on this function"), + GNUNET_YES, &GNUNET_GETOPT_set_string, &inspectFunction}, + {'i', "inspect", NULL, gettext_noop ("An expression to inspect in the function specified after the argument f"), GNUNET_YES, &GNUNET_GETOPT_set_string, &inspectExpression}, GNUNET_GETOPT_OPTION_END }; diff --git a/src/monkey/gnunet_monkey_action.h b/src/monkey/gnunet_monkey_action.h index d46a22a2f..7c49525a4 100644 --- a/src/monkey/gnunet_monkey_action.h +++ b/src/monkey/gnunet_monkey_action.h @@ -48,15 +48,6 @@ extern "C" #define BUG_CUSTOM 7 -struct Variable -{ - struct Variable *next; - struct Variable *prev; - const char *name; - const char *value; -}; - - /** * Context for the Action API */ @@ -67,6 +58,7 @@ struct GNUNET_MONKEY_ACTION_Context const char *expression_database_path; const char *gdb_binary_path; const char *inspect_expression; + const char *inspect_function; int debug_mode; int bug_detected; char *debug_report; @@ -77,11 +69,9 @@ struct GNUNET_MONKEY_ACTION_Context mi_stop *gdb_stop_reason; mi_frames *gdb_frames; const char *gdb_null_variable; - struct Variable *variable_list_head; - struct Variable *variable_list_tail; /* Valgrind memcheck attributes */ - char *valgrind_output; + char* valgrind_output_tmp_file_name; }; @@ -99,6 +89,8 @@ int GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct *cntxt); int GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context *cntxt); +int GNUNET_MONKEY_ACTION_delete_context(struct GNUNET_MONKEY_ACTION_Context *cntxt); + int GNUNET_MONKEY_ACTION_check_bug_redundancy (void); diff --git a/src/monkey/gnunet_monkey_edb.h b/src/monkey/gnunet_monkey_edb.h index 27f2f8283..d3d82f183 100644 --- a/src/monkey/gnunet_monkey_edb.h +++ b/src/monkey/gnunet_monkey_edb.h @@ -110,6 +110,14 @@ GNUNET_MONKEY_EDB_get_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt, void *iter_cls); +int +GNUNET_MONKEY_EDB_get_sub_expressions (struct GNUNET_MONKEY_EDB_Context *cntxt, + const char *file_name, int start_line_no, + int end_line_no, + GNUNET_MONKEY_ExpressionIterator iter, + void *iter_cls); + + #if 0 /* keep Emacsens' auto-indent happy */ { diff --git a/src/monkey/tmp b/src/monkey/tmp new file mode 100644 index 000000000..b3a613732 --- /dev/null +++ b/src/monkey/tmp @@ -0,0 +1,30 @@ +==1277== Memcheck, a memory error detector +==1277== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al. +==1277== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info +==1277== Command: ./bug_bad_memory_access +==1277== Parent PID: 1666 +==1277== +==1277== Invalid write of size 4 +==1277== at 0x400512: badMemoryAccess (bug_bad_memory_access.c:9) +==1277== by 0x400532: main (bug_bad_memory_access.c:14) +==1277== Address 0x4252352 is not stack'd, malloc'd or (recently) free'd +==1277== +==1277== +==1277== Process terminating with default action of signal 11 (SIGSEGV) +==1277== Access not within mapped region at address 0x4252352 +==1277== at 0x400512: badMemoryAccess (bug_bad_memory_access.c:9) +==1277== by 0x400532: main (bug_bad_memory_access.c:14) +==1277== If you believe this happened as a result of a stack +==1277== overflow in your program's main thread (unlikely but +==1277== possible), you can try to increase the size of the +==1277== main thread stack using the --main-stacksize= flag. +==1277== The main thread stack size used in this run was 8388608. +==1277== +==1277== HEAP SUMMARY: +==1277== in use at exit: 0 bytes in 0 blocks +==1277== total heap usage: 0 allocs, 0 frees, 0 bytes allocated +==1277== +==1277== All heap blocks were freed -- no leaks are possible +==1277== +==1277== For counts of detected and suppressed errors, rerun with: -v +==1277== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)