gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r15397 - gnunet/src/monkey


From: gnunet
Subject: [GNUnet-SVN] r15397 - gnunet/src/monkey
Date: Thu, 2 Jun 2011 11:27:35 +0200

Author: safey
Date: 2011-06-02 11:27:35 +0200 (Thu, 02 Jun 2011)
New Revision: 15397

Added:
   gnunet/src/monkey/bug_assertion_failure.c
Modified:
   gnunet/src/monkey/Makefile.am
   gnunet/src/monkey/action_api.c
   gnunet/src/monkey/gnunet-monkey.c
   gnunet/src/monkey/gnunet_monkey_action.h
Log:
Monkey supports Assertions, and inspects user-defined expressions

Modified: gnunet/src/monkey/Makefile.am
===================================================================
--- gnunet/src/monkey/Makefile.am       2011-06-01 18:55:25 UTC (rev 15396)
+++ gnunet/src/monkey/Makefile.am       2011-06-02 09:27:35 UTC (rev 15397)
@@ -41,7 +41,8 @@
 
 noinst_PROGRAMS = \
  bug_null_pointer_exception \
- bug_bad_memory_access
+ bug_bad_memory_access \
+ bug_assertion_failure
 
 gnunet_monkey_SOURCES = \
  gdbmi.h \
@@ -84,6 +85,9 @@
 bug_bad_memory_access:
        gcc -g -O0 -o bug_bad_memory_access bug_bad_memory_access.c     
 
+bug_assertion_failure:
+       gcc -g -O0 -o bug_assertion_failure bug_assertion_failure.c     
+       
 check_PROGRAMS = \
     test_monkey_edb
     #test_gnunet_monkey        

Modified: gnunet/src/monkey/action_api.c
===================================================================
--- gnunet/src/monkey/action_api.c      2011-06-01 18:55:25 UTC (rev 15396)
+++ gnunet/src/monkey/action_api.c      2011-06-02 09:27:35 UTC (rev 15397)
@@ -33,322 +33,513 @@
 extern void sendMail (const char *messageContents, const char *emailAddress);
 
 
-static int async_c=0;
+static int async_c = 0;
 static struct Expression *expressionListHead = NULL;
 static struct Expression *expressionListTail = NULL;
 
-struct Expression {
-       struct Expression *next;
-       struct Expression *prev;
-       const char* expressionSyntax;
-       int lineNo;
+struct Expression
+{
+  struct Expression *next;
+  struct Expression *prev;
+  const char *expressionSyntax;
+  int lineNo;
 };
 
-static void cb_console(const char *str, void *data)
+static void
+cb_console (const char *str, void *data)
 {
- printf("CONSOLE> %s\n",str);
+  printf ("CONSOLE> %s\n", str);
 }
 
 
 /* Note that unlike what's documented in gdb docs it isn't usable. */
-static void cb_target(const char *str, void *data)
+static void
+cb_target (const char *str, void *data)
 {
- printf("TARGET> %s\n",str);
+  printf ("TARGET> %s\n", str);
 }
 
 
-static void cb_log(const char *str, void *data)
+static void
+cb_log (const char *str, void *data)
 {
- printf("LOG> %s\n",str);
+  printf ("LOG> %s\n", str);
 }
 
 
-static void cb_to(const char *str, void *data)
+static void
+cb_to (const char *str, void *data)
 {
- printf(">> %s",str);
+  printf (">> %s", str);
 }
 
 
-static void cb_from(const char *str, void *data)
+static void
+cb_from (const char *str, void *data)
 {
- printf("<< %s\n",str);
+  printf ("<< %s\n", str);
 }
 
 
-static void cb_async(mi_output *o, void *data)
+static void
+cb_async (mi_output * o, void *data)
 {
- printf("ASYNC\n");
- async_c++;
+  printf ("ASYNC\n");
+  async_c++;
 }
 
 
-static int wait_for_stop(mi_h *h, struct GNUNET_MONKEY_ACTION_Context *cntxt)
+static int
+wait_for_stop (mi_h * h, struct GNUNET_MONKEY_ACTION_Context *cntxt)
 {
-       while (!mi_get_response(h))
-               usleep(1000);
-       /* The end of the async. */
-       cntxt->gdb_stop_reason=mi_res_stop(h);
-       if (cntxt->gdb_stop_reason)
-       {
-               if (cntxt->gdb_stop_reason->reason == sr_exited_normally)
-                       return GDB_STATE_EXIT_NORMALLY;
+  while (!mi_get_response (h))
+    usleep (1000);
+  /* The end of the async. */
+  cntxt->gdb_stop_reason = mi_res_stop (h);
+  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);
-               if (NULL == cntxt->gdb_frames)
-                 GNUNET_break(0);
+      cntxt->gdb_frames = gmi_stack_info_frame (h);
+      if (NULL == cntxt->gdb_frames)
+       GNUNET_break (0);
 
-               return GDB_STATE_STOPPED;
+      if (0 == cntxt->gdb_frames->line)
+       {
+         /*
+          * This happens if the program stops in a shared library (inner 
frames)
+          * We will move to outer frames until reaching the faulty line in the 
source code
+          */
+         cntxt->gdb_frames = gmi_stack_list_frames (cntxt->gdb_handle);
+         do
+           {
+             cntxt->gdb_frames = cntxt->gdb_frames->next;
+           }
+         while (0 == cntxt->gdb_frames->line);
        }
-       return GDB_STATE_ERROR;
+
+      return GDB_STATE_STOPPED;
+    }
+  return GDB_STATE_ERROR;
 }
 
 
-int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* 
cntxt, const char* dumpFileName)
+int
+GNUNET_MONKEY_ACTION_report_file (struct GNUNET_MONKEY_ACTION_Context *cntxt,
+                                 const char *dumpFileName)
 {
-       FILE* file = fopen(dumpFileName, "w");
-       GNUNET_assert(NULL != file);
-       fprintf(file,"%s", cntxt->debug_report);
-       fclose(file);
-       return GNUNET_OK;
+  FILE *file = fopen (dumpFileName, "w");
+  GNUNET_assert (NULL != file);
+  fprintf (file, "%s", cntxt->debug_report);
+  fclose (file);
+  return GNUNET_OK;
 }
 
 
-int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* 
cntxt)
+int
+GNUNET_MONKEY_ACTION_report_email (struct GNUNET_MONKEY_ACTION_Context *cntxt)
 {
-       if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY)
-               sendMail(cntxt->debug_report, cntxt->email_address);
+  if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY)
+    sendMail (cntxt->debug_report, cntxt->email_address);
 
-       return GNUNET_OK;
+  return GNUNET_OK;
 }
 
 
-static int iterateExpressions(void *cls, int numColumns, char **colValues, 
char **colNames)
+static int
+iterateExpressions (void *cls, int numColumns, char **colValues,
+                   char **colNames)
 {
-       struct Expression *expression;
+  struct Expression *expression;
 
-       if (NULL == colValues[0] || NULL == colValues[1])
-               return 1; /* Error */
+  if (NULL == colValues[0] || NULL == colValues[1])
+    return 1;                  /* Error */
 
-       expression = GNUNET_malloc(sizeof(struct Expression));
-       expression->expressionSyntax = strdup(colValues[0]);
-       expression->lineNo = atoi(colValues[1]);
+  expression = GNUNET_malloc (sizeof (struct Expression));
+  expression->expressionSyntax = strdup (colValues[0]);
+  expression->lineNo = atoi (colValues[1]);
 
+  printf ("Inserting expression:%s", expression->expressionSyntax);
+  GNUNET_CONTAINER_DLL_insert (expressionListHead, expressionListTail,
+                              expression);
 
-       GNUNET_CONTAINER_DLL_insert(expressionListHead, expressionListTail, 
expression);
-
-       return 0; /* OK */
+  return 0;                    /* OK */
 }
 
 
-static int scopeEndCallback(void *cls, int numColumns, char **colValues, char 
** colNames)
+static int
+scopeEndCallback (void *cls, int numColumns, char **colValues,
+                 char **colNames)
 {
-       int *scopeEnd = (int*) cls;
+  int *scopeEnd = (int *) cls;
 
-       *scopeEnd = atoi(colValues[0]);
-       if (*scopeEnd < 0)
-               return 1; /* Error */
-       return 0;
+  *scopeEnd = atoi (colValues[0]);
+  if (*scopeEnd < 0)
+    return 1;                  /* Error */
+  return 0;
 }
 
 
-static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt)
+static struct Expression *
+getFaultyExpression (struct GNUNET_MONKEY_ACTION_Context *cntxt)
 {
-       struct Expression *faultyExpression = NULL;
-       struct Expression *tmp;
-       int expressionLength = 0;
-       //mi_wp *watchPoint;
+  struct Expression *faultyExpression = NULL;
+  struct Expression *tmp = NULL;
+  int expressionLength = 0;
 
-       tmp = expressionListHead;
-       while (NULL != tmp) {
-               if ((tmp->lineNo == cntxt->gdb_frames->line)
-                               && (strlen(tmp->expressionSyntax) > 
expressionLength)) {
-                       expressionLength = strlen(tmp->expressionSyntax);
-                       faultyExpression = tmp;
-               }
-               tmp = tmp->next;
+  tmp = expressionListHead;
+  while (NULL != tmp)
+    {
+      if ((tmp->lineNo == cntxt->gdb_frames->line)
+         && (strlen (tmp->expressionSyntax) > expressionLength))
+       {
+         expressionLength = strlen (tmp->expressionSyntax);
+         faultyExpression = tmp;
        }
+      tmp = tmp->next;
+    }
 
-       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;
+  return faultyExpression;
+}
+
+static int
+analyzeSegmentationFault (struct GNUNET_MONKEY_ACTION_Context *cntxt)
+{
+  struct Expression *faultyExpression = NULL;
+  struct Expression *tmp;
+  int expressionLength = 0;
+
+
+  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);
+             if (NULL != eval
+                 && (strcmp (eval, "0x0") == 0
+                     || strcmp (eval, "NULL") == 0))
+               {
+                 cntxt->gdb_null_variable = tmp->expressionSyntax;
+                 return GNUNET_OK;
                }
+           }
+         tmp = tmp->next;
        }
-       /* 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;
+    }
+  /* 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;
 }
 
 
-int GNUNET_MONKEY_ACTION_inspect_expression_database(struct 
GNUNET_MONKEY_ACTION_Context *cntxt)
+
+static int
+analyzeCustomFault (struct GNUNET_MONKEY_ACTION_Context *cntxt)
 {
-       struct GNUNET_MONKEY_EDB_Context *edbCntxt;
-       int ret = GNUNET_OK;
-       int endScope;
-
-       edbCntxt = GNUNET_MONKEY_EDB_connect(cntxt->expression_database_path);
-       if (NULL == edbCntxt) {
-               GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Unable to connect to 
Expression Database file!\n");
-               return GNUNET_NO;
+  struct Expression *tmp;
+  struct Expression *faultyExpression = getFaultyExpression (cntxt);
+  struct Variable *variable;
+  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);
+           }
+         tmp = tmp->next;
        }
+    }
+  return GNUNET_OK;
+}
 
-       ret = GNUNET_MONKEY_EDB_get_expression_scope_end(edbCntxt,
-                                          cntxt->gdb_frames->file, 
cntxt->gdb_frames->line,
-                                          &scopeEndCallback, &endScope);
-       if (endScope < 0)
-               return GNUNET_NO;
 
-       ret = GNUNET_MONKEY_EDB_get_expressions (edbCntxt,
-                                          cntxt->gdb_frames->file, 
cntxt->gdb_frames->line,
-                                          endScope,
-                                          &iterateExpressions,
-                                          NULL);
+int
+GNUNET_MONKEY_ACTION_inspect_expression_database (struct
+                                                 GNUNET_MONKEY_ACTION_Context
+                                                 *cntxt)
+{
+  struct GNUNET_MONKEY_EDB_Context *edbCntxt;
+  int ret = GNUNET_OK;
+  int endScope;
+  const char *signalMeaning = cntxt->gdb_stop_reason->signal_meaning;
 
-       if (strcasecmp(cntxt->gdb_stop_reason->signal_meaning, "Segmentation 
fault") == 0)
-               ret = analyzeSegmentationFault(cntxt);
+  edbCntxt = GNUNET_MONKEY_EDB_connect (cntxt->expression_database_path);
+  if (NULL == edbCntxt)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Unable to connect to Expression Database file!\n");
+      return GNUNET_NO;
+    }
 
-       GNUNET_MONKEY_EDB_disconnect(edbCntxt);
-       mi_disconnect(cntxt->gdb_handle);
-       return ret;
+  ret = GNUNET_MONKEY_EDB_get_expression_scope_end (edbCntxt,
+                                                   cntxt->gdb_frames->file,
+                                                   cntxt->gdb_frames->line,
+                                                   &scopeEndCallback,
+                                                   &endScope);
+  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;
+      ret = analyzeSegmentationFault (cntxt);
+    }
+  else if (strcasecmp (signalMeaning, "Aborted") == 0)
+    {
+      cntxt->bug_detected = BUG_CUSTOM;
+      ret = analyzeCustomFault (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;
-       char* valgrindCommand;
-       cntxt->debug_mode = DEBUG_MODE_VALGRIND;
-       GNUNET_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");
-               GNUNET_free (valgrindCommand);
-               return GNUNET_NO;
-       }
+int
+GNUNET_MONKEY_ACTION_rerun_with_valgrind (struct GNUNET_MONKEY_ACTION_Context
+                                         *cntxt)
+{
+  FILE *valgrindPipe;
+  int size;
+  char *valgrindCommand;
+  cntxt->debug_mode = DEBUG_MODE_VALGRIND;
+  GNUNET_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");
+      GNUNET_free (valgrindCommand);
+      return GNUNET_NO;
+    }
 
-       fscanf(valgrindPipe, "%d", &size);
+  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;
-       }
-       return GNUNET_OK;
+  /* 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;
+    }
+  return GNUNET_OK;
 }
 
 
-int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* 
cntxt)
+int
+GNUNET_MONKEY_ACTION_rerun_with_gdb (struct GNUNET_MONKEY_ACTION_Context
+                                    *cntxt)
 {
-       cntxt->debug_mode = DEBUG_MODE_GDB;
+  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". */
+  if (NULL != cntxt->gdb_binary_path)
+    mi_set_gdb_exe (cntxt->gdb_binary_path);
+  int ret;
 
-       /* This is like a file-handle for fopen.
-           Here we have all the state of gdb "connection". */
-       if (NULL != cntxt->gdb_binary_path)
-               mi_set_gdb_exe(cntxt->gdb_binary_path);
-       int ret;
+  /* Connect to gdb child. */
+  cntxt->gdb_handle = mi_connect_local ();
+  if (!cntxt->gdb_handle)
+    {
+      printf ("Connect failed\n");
+      return GNUNET_NO;
+    }
+  printf ("Connected to gdb!\n");
 
-        /* Connect to gdb child. */
-       cntxt->gdb_handle = mi_connect_local();
-        if (!cntxt->gdb_handle)
-          {
-           printf("Connect failed\n");
-           return GNUNET_NO;
-          }
-        printf("Connected to gdb!\n");
+  /* Set all callbacks. */
+  mi_set_console_cb (cntxt->gdb_handle, cb_console, NULL);
+  mi_set_target_cb (cntxt->gdb_handle, cb_target, NULL);
+  mi_set_log_cb (cntxt->gdb_handle, cb_log, NULL);
+  mi_set_async_cb (cntxt->gdb_handle, cb_async, NULL);
+  mi_set_to_gdb_cb (cntxt->gdb_handle, cb_to, NULL);
+  mi_set_from_gdb_cb (cntxt->gdb_handle, cb_from, NULL);
 
-        /* Set all callbacks. */
-        mi_set_console_cb(cntxt->gdb_handle,cb_console,NULL);
-        mi_set_target_cb(cntxt->gdb_handle,cb_target,NULL);
-        mi_set_log_cb(cntxt->gdb_handle,cb_log,NULL);
-        mi_set_async_cb(cntxt->gdb_handle,cb_async,NULL);
-        mi_set_to_gdb_cb(cntxt->gdb_handle,cb_to,NULL);
-        mi_set_from_gdb_cb(cntxt->gdb_handle,cb_from,NULL);
+  /* Set the name of the child and the command line arguments. */
+  if (!gmi_set_exec (cntxt->gdb_handle, cntxt->binary_name, NULL))
+    {
+      printf ("Error setting exec y args\n");
+      mi_disconnect (cntxt->gdb_handle);
+      return GNUNET_NO;
+    }
 
-        /* Set the name of the child and the command line arguments. */
-        if (!gmi_set_exec(cntxt->gdb_handle, cntxt->binary_name, NULL))
-          {
-           printf("Error setting exec y args\n");
-           mi_disconnect(cntxt->gdb_handle);
-           return GNUNET_NO;
-          }
+  /* Tell gdb to attach the child to a terminal. */
+  if (!gmi_target_terminal (cntxt->gdb_handle, ttyname (STDIN_FILENO)))
+    {
+      printf ("Error selecting target terminal\n");
+      mi_disconnect (cntxt->gdb_handle);
+      return GNUNET_NO;
+    }
 
-        /* Tell gdb to attach the child to a terminal. */
-        if (!gmi_target_terminal(cntxt->gdb_handle, ttyname(STDIN_FILENO)))
-          {
-           printf("Error selecting target terminal\n");
-           mi_disconnect(cntxt->gdb_handle);
-           return GNUNET_NO;
-          }
+  if (NULL != cntxt->inspect_expression)
+    {
+      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;
+       }
+    }
 
-        /* Run the program. */
-        if (!gmi_exec_run(cntxt->gdb_handle))
-          {
-           printf("Error in run!\n");
-           mi_disconnect(cntxt->gdb_handle);
-           return GNUNET_NO;
-          }
-        /* Here we should be stopped when the program crashes */
-        ret = wait_for_stop(cntxt->gdb_handle, cntxt);
-        if (ret == GDB_STATE_ERROR)
-           mi_disconnect(cntxt->gdb_handle);
+  /* Run the program. */
+  if (!gmi_exec_run (cntxt->gdb_handle))
+    {
+      printf ("Error in run!\n");
+      mi_disconnect (cntxt->gdb_handle);
+      return GNUNET_NO;
+    }
+  /* Here we should be stopped when the program crashes */
+  ret = wait_for_stop (cntxt->gdb_handle, cntxt);
+  if (ret == GDB_STATE_ERROR)
+    mi_disconnect (cntxt->gdb_handle);
 
-       return ret;
+  return ret;
 }
 
+static const char *
+variableListToString (struct Variable *head)
+{
+  const char *string = GNUNET_malloc (200 * sizeof (char));
+  const char *strTmp;
+  struct Variable *tmp = head;
+  asprintf (&strTmp, "%s = %s\n", tmp->name, tmp->value);
+  strcpy (string, strTmp);
+  free (strTmp);
+  while (NULL != tmp)
+    {
+      asprintf (&strTmp, "%s = %s\n", tmp->name, tmp->value);
+      strcat (string, strTmp);
+      free (strTmp);
+      tmp = tmp->next;
+    }
+  return string;
+}
 
-int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* 
cntxt)
+
+int
+GNUNET_MONKEY_ACTION_format_report (struct GNUNET_MONKEY_ACTION_Context
+                                   *cntxt)
 {
-       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 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;
+  switch (cntxt->debug_mode)
+    {
+    case DEBUG_MODE_GDB:
+      if (cntxt->bug_detected == BUG_NULL_POINTER)
+       {
+         GNUNET_asprintf (&(cntxt->debug_report),
+                          "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);
        }
+      else if (cntxt->bug_detected == BUG_CUSTOM)
+       {
+         if (NULL == cntxt->inspect_expression)
+           {
+             /* Assertion Failure */
+             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",
+                              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));
+           }
+         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));
+           }
+       }
+      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;
+    }
 
-       cntxt->debug_mode = DEBUG_MODE_REPORT_READY;
-       return GNUNET_OK;
+  cntxt->debug_mode = DEBUG_MODE_REPORT_READY;
+  return GNUNET_OK;
 }
 
 
-int GNUNET_MONKEY_ACTION_check_bug_redundancy()
+int
+GNUNET_MONKEY_ACTION_check_bug_redundancy ()
 {
-       return GNUNET_OK;
+  return GNUNET_OK;
 }

Added: gnunet/src/monkey/bug_assertion_failure.c
===================================================================
--- gnunet/src/monkey/bug_assertion_failure.c                           (rev 0)
+++ gnunet/src/monkey/bug_assertion_failure.c   2011-06-02 09:27:35 UTC (rev 
15397)
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <assert.h>
+
+void assertionFailure()
+{
+       int x = 5;
+       printf("Assertion Failure Now!\n");
+       assert(x < 4);
+}
+
+int main(int argc, char *argv[])
+{
+       assertionFailure();
+       return 0;
+}

Modified: gnunet/src/monkey/gnunet-monkey.c
===================================================================
--- gnunet/src/monkey/gnunet-monkey.c   2011-06-01 18:55:25 UTC (rev 15396)
+++ gnunet/src/monkey/gnunet-monkey.c   2011-06-02 09:27:35 UTC (rev 15397)
@@ -30,12 +30,13 @@
 #include "gnunet_program_lib.h"
 #include "gnunet_monkey_action.h"
 
-static const char* mode;
-static const char* dumpFileName;
-static const char* binaryName;
-static const char* emailAddress;
-static const char* edbFilePath;
-static const char* gdbBinaryPath;
+static const char *mode;
+static const char *dumpFileName;
+static const char *binaryName;
+static const char *emailAddress;
+static const char *edbFilePath;
+static const char *gdbBinaryPath;
+static const char *inspectExpression;
 static int ret = 0;
 
 /**
@@ -49,113 +50,147 @@
 static void
 run (void *cls,
      char *const *args,
-     const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *c)
+     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c)
 {
-       int result;
-       struct GNUNET_MONKEY_ACTION_Context *cntxt;
+  int result;
+  struct GNUNET_MONKEY_ACTION_Context *cntxt;
 
-       if (strcasecmp(mode, "email") == 0) {
-               if (NULL == emailAddress) {
-                       GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Working in email 
mode requires an email address!\n");
-                       ret = 1;
-                       return;
-               }
-       } else if (strcasecmp(mode, "text") == 0) {
-               if (NULL == dumpFileName) {
-                       GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Working in text 
mode requires a path for the dump file!\n");
-                       ret = 1;
-                       return;
-               }
+  if (strcasecmp (mode, "email") == 0)
+    {
+      if (NULL == emailAddress)
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     "Working in email mode requires an email address!\n");
+         ret = 1;
+         return;
        }
+    }
+  else if (strcasecmp (mode, "text") == 0)
+    {
+      if (NULL == dumpFileName)
+       {
+         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                     "Working in text mode requires a path for the dump 
file!\n");
+         ret = 1;
+         return;
+       }
+    }
 
-       /* Initialize context for the Action API */
-       cntxt = GNUNET_malloc(sizeof(struct GNUNET_MONKEY_ACTION_Context));
-       cntxt->binary_name = binaryName;
-       cntxt->expression_database_path = edbFilePath;
-       cntxt->gdb_binary_path = gdbBinaryPath;
+  /* Initialize context for the Action API */
+  cntxt = GNUNET_malloc (sizeof (struct GNUNET_MONKEY_ACTION_Context));
+  cntxt->binary_name = binaryName;
+  cntxt->expression_database_path = edbFilePath;
+  cntxt->gdb_binary_path = gdbBinaryPath;
+  cntxt->inspect_expression = inspectExpression;
 
-       result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt);
-       switch (result) {
-       int retVal;
-       case GDB_STATE_ERROR:
-               break;
-       case GDB_STATE_EXIT_NORMALLY:
-               GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Debug with gdb, program 
exited normally!\n");
-               /*FIXME: Valgrind should be launched here */
-               break;
-       case GDB_STATE_STOPPED:
-               /*FIXME: Expression Database should be inspected here (before 
writing the report) */
-               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");
-                       ret = 1;
-               }
-               if (strcasecmp(mode, "email") == 0) {
-                       if (GNUNET_OK != 
GNUNET_MONKEY_ACTION_report_email(cntxt)) {
-                               GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error 
sending email!\n");
-                               ret = 1;
-                       }
-               } else {
-                       /* text mode */
-                       if (GNUNET_OK != 
GNUNET_MONKEY_ACTION_report_file(cntxt, dumpFileName)) {
-                               GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in 
saving debug file!\n");
-                               ret = 1;
-                       }
-               }
-               break;
-       default:
-               break;
+  result = GNUNET_MONKEY_ACTION_rerun_with_gdb (cntxt);
+  switch (result)
+    {
+      int retVal;
+    case GDB_STATE_ERROR:
+      break;
+    case GDB_STATE_EXIT_NORMALLY:
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+                 "Debug with gdb, program exited normally!\n");
+      /*FIXME: Valgrind should be launched here */
+      break;
+    case GDB_STATE_STOPPED:
+      /*FIXME: Expression Database should be inspected here (before writing 
the report) */
+      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");
+         ret = 1;
+       }
+      if (strcasecmp (mode, "email") == 0)
+       {
+         if (GNUNET_OK != GNUNET_MONKEY_ACTION_report_email (cntxt))
+           {
+             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error sending email!\n");
+             ret = 1;
+           }
+       }
+      else
+       {
+         /* text mode */
+         if (GNUNET_OK !=
+             GNUNET_MONKEY_ACTION_report_file (cntxt, dumpFileName))
+           {
+             GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                         "Error in saving debug file!\n");
+             ret = 1;
+           }
+       }
+      break;
+    default:
+      break;
+    }
 }
 
 
-int main(int argc, char *argv[])
+int
+main (int argc, char *argv[])
 {
- static const struct GNUNET_GETOPT_CommandLineOption options[] = {
-     {'m', "mode", NULL, gettext_noop ("monkey's mode of operation: options 
are \"text\" or \"email\""),
-      GNUNET_YES, &GNUNET_GETOPT_set_string, &mode},
-     {'b', "binary", NULL, gettext_noop ("binary for program to debug with 
monkey"),
-      GNUNET_YES, &GNUNET_GETOPT_set_string, &binaryName},
-     {'o', "output", NULL, gettext_noop ("path to file to dump monkey's output 
in case of text mode"),
-      GNUNET_YES, &GNUNET_GETOPT_set_string, &dumpFileName},
-     {'a', "address", NULL, gettext_noop ("address to send email to in case of 
email mode"),
-          GNUNET_YES, &GNUNET_GETOPT_set_string, &emailAddress},
-     {'d', "database", NULL, gettext_noop ("path to Expression Database file"),
-                    GNUNET_YES, &GNUNET_GETOPT_set_string, &edbFilePath},
-     {'g', "gdb", NULL, gettext_noop ("path to gdb binary in use; default is 
/usr/bin/gdb"),
-                    GNUNET_YES, &GNUNET_GETOPT_set_string, &gdbBinaryPath},
-      GNUNET_GETOPT_OPTION_END
-   };
- 
- if (argc < 2) {
-        printf("%s", "Monkey should take arguments: Use --help to get a list 
of options.\n");
-        return 1;
- }
- 
- if (GNUNET_OK == GNUNET_PROGRAM_run (argc,
-                       argv,
-                       "gnunet-monkey",
-                       gettext_noop
-                       ("Automatically debug a service"),
-                       options, &run, NULL))
-     {
-       return ret;
-     }
+  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
+    {'m', "mode", NULL,
+     gettext_noop
+     ("monkey's mode of operation: options are \"text\" or \"email\""),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &mode},
+    {'b', "binary", NULL,
+     gettext_noop ("binary for program to debug with monkey"),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &binaryName},
+    {'o', "output", NULL,
+     gettext_noop
+     ("path to file to dump monkey's output in case of text mode"),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &dumpFileName},
+    {'a', "address", NULL,
+     gettext_noop ("address to send email to in case of email mode"),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &emailAddress},
+    {'d', "database", NULL, gettext_noop ("path to Expression Database file"),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &edbFilePath},
+    {'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"),
+     GNUNET_YES, &GNUNET_GETOPT_set_string, &inspectExpression},
+    GNUNET_GETOPT_OPTION_END
+  };
 
-     return 1;
+  if (argc < 2)
+    {
+      printf ("%s",
+             "Monkey should take arguments: Use --help to get a list of 
options.\n");
+      return 1;
+    }
+
+  if (GNUNET_OK == GNUNET_PROGRAM_run (argc,
+                                      argv,
+                                      "gnunet-monkey",
+                                      gettext_noop
+                                      ("Automatically debug a service"),
+                                      options, &run, NULL))
+    {
+      return ret;
+    }
+
+  return 1;
 }
-

Modified: gnunet/src/monkey/gnunet_monkey_action.h
===================================================================
--- gnunet/src/monkey/gnunet_monkey_action.h    2011-06-01 18:55:25 UTC (rev 
15396)
+++ gnunet/src/monkey/gnunet_monkey_action.h    2011-06-02 09:27:35 UTC (rev 
15397)
@@ -44,39 +44,62 @@
 #define GDB_STATE_ERROR 3
 #define DEBUG_MODE_VALGRIND 4
 #define DEBUG_MODE_REPORT_READY 5
+#define BUG_NULL_POINTER 6
+#define BUG_CUSTOM 7
 
 
+struct Variable
+{
+  struct Variable *next;
+  struct Varialble *prev;
+  const char *name;
+  const char *value;
+};
+
+
 /**
  * Context for the Action API
  */
 struct GNUNET_MONKEY_ACTION_Context
 {
-       const char* binary_name;
-       const char* email_address;
-       const char* expression_database_path;
-       const char* gdb_binary_path;
-       int debug_mode;
-       char* debug_report;
+  const char *binary_name;
+  const char *email_address;
+  const char *expression_database_path;
+  const char *gdb_binary_path;
+  const char *inspect_expression;
+  int debug_mode;
+  int bug_detected;
+  char *debug_report;
 
-       /* gdb debugging attributes */
-       mi_h *gdb_handle;
-       const char* gdb_in_use;
-       mi_stop* gdb_stop_reason;
-       mi_frames* gdb_frames;
-       const char* gdb_null_variable;
+  /* gdb debugging attributes */
+  mi_h *gdb_handle;
+  const char *gdb_in_use;
+  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;
+  /* 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_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);
+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_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);
 
 
 #if 0                          /* keep Emacsens' auto-indent happy */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]