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)
{
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)
{
}
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;
}
expression->expressionSyntax = strdup (colValues[0]);
expression->lineNo = atoi (colValues[1]);
- printf ("Inserting expression:%s", expression->expressionSyntax);
GNUNET_CONTAINER_DLL_insert (expressionListHead, expressionListTail,
expression);
static int
analyzeSegmentationFault (struct GNUNET_MONKEY_ACTION_Context *cntxt)
{
- struct Expression *faultyExpression = NULL;
struct Expression *tmp;
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;
}
}
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);
}
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)
{
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;
}
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". */
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. */
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;
}
+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)
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;
}
+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 ()
{
--- /dev/null
+/*
+ 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 */