gnunet-svn
[Top][All Lists]
Advanced

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

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


From: gnunet
Subject: [GNUnet-SVN] r14980 - gnunet/src/monkey
Date: Fri, 15 Apr 2011 12:02:28 +0200

Author: safey
Date: 2011-04-15 12:02:28 +0200 (Fri, 15 Apr 2011)
New Revision: 14980

Modified:
   gnunet/src/monkey/action_api.c
   gnunet/src/monkey/bug_null_pointer_exception.c
   gnunet/src/monkey/edb_api.c
   gnunet/src/monkey/gnunet-monkey.c
   gnunet/src/monkey/gnunet_monkey_action.h
   gnunet/src/monkey/gnunet_monkey_edb.h
Log:
Action API detects segmentation fault

Modified: gnunet/src/monkey/action_api.c
===================================================================
--- gnunet/src/monkey/action_api.c      2011-04-15 10:01:39 UTC (rev 14979)
+++ gnunet/src/monkey/action_api.c      2011-04-15 10:02:28 UTC (rev 14980)
@@ -26,13 +26,23 @@
 #include "platform.h"
 #include "gnunet_common.h"
 #include "gnunet_monkey_action.h"
+#include "gnunet_monkey_edb.h"
+#include "gnunet_container_lib.h"
 #include <libesmtp.h>
 
 extern void sendMail (const char *messageContents, const char *emailAddress);
 
 
 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;
+};
 
 static void cb_console(const char *str, void *data)
 {
@@ -118,20 +128,117 @@
        return GNUNET_OK;
 }
 
+static int iterateExpressions(void *cls, int numColumns, char **colValues, 
char **colNames)
+{
+       struct Expression *expression;
 
+       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]);
+
+
+       GNUNET_CONTAINER_DLL_insert(expressionListHead, expressionListTail, 
expression);
+
+       return 0; /* OK */
+}
+
+
+static int scopeEndCallback(void *cls, int numColumns, char **colValues, char 
** colNames)
+{
+       int *scopeEnd = (int*) cls;
+
+       *scopeEnd = atoi(colValues[0]);
+       if (*scopeEnd < 0)
+               return 1; /* Error */
+       return 0;
+}
+
+
+static int analyzeSegmentationFault(struct GNUNET_MONKEY_ACTION_Context *cntxt)
+{
+       struct Expression *faultyExpression;
+       struct Expression *tmp;
+       int expressionLength = 0;
+       mi_wp *watchPoint;
+
+       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;
+       }
+
+       /* 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);
+               }
+               tmp = tmp->next;
+       }
+       return GNUNET_OK;
+}
+
+
+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;
+
+       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;
+       }
+
+       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(cntxt->gdb_stop_reason->signal_meaning, "Segmentation 
fault") == 0)
+               analyzeSegmentationFault(cntxt);
+
+       GNUNET_MONKEY_EDB_disconnect(edbCntxt);
+       return ret;
+}
+
+
 int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* 
cntxt)
 {
        cntxt->debug_mode = DEBUG_MODE_GDB;
 
        /* This is like a file-handle for fopen.
            Here we have all the state of gdb "connection". */
-       mi_set_gdb_exe("/tmp/gdb/bin/gdb");
-       mi_h *h;
+       if (NULL != cntxt->gdb_binary_path)
+               mi_set_gdb_exe(cntxt->gdb_binary_path);
        int ret;
 
         /* Connect to gdb child. */
-        h = mi_connect_local();
-        if (!h)
+       cntxt->gdb_handle = mi_connect_local();
+        if (!cntxt->gdb_handle)
           {
            printf("Connect failed\n");
            return GNUNET_NO;
@@ -139,40 +246,40 @@
         printf("Connected to gdb!\n");
 
         /* Set all callbacks. */
-        mi_set_console_cb(h,cb_console,NULL);
-        mi_set_target_cb(h,cb_target,NULL);
-        mi_set_log_cb(h,cb_log,NULL);
-        mi_set_async_cb(h,cb_async,NULL);
-        mi_set_to_gdb_cb(h,cb_to,NULL);
-        mi_set_from_gdb_cb(h,cb_from,NULL);
+        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 aguments. */
-        if (!gmi_set_exec(h, cntxt->binary_name, 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(h);
+           mi_disconnect(cntxt->gdb_handle);
            return GNUNET_NO;
           }
 
         /* Tell gdb to attach the child to a terminal. */
-        if (!gmi_target_terminal(h, ttyname(STDIN_FILENO)))
+        if (!gmi_target_terminal(cntxt->gdb_handle, ttyname(STDIN_FILENO)))
           {
            printf("Error selecting target terminal\n");
-           mi_disconnect(h);
+           mi_disconnect(cntxt->gdb_handle);
            return GNUNET_NO;
           }
 
         /* Run the program. */
-        if (!gmi_exec_run(h))
+        if (!gmi_exec_run(cntxt->gdb_handle))
           {
            printf("Error in run!\n");
-           mi_disconnect(h);
+           mi_disconnect(cntxt->gdb_handle);
            return GNUNET_NO;
           }
         /* Here we should be stopped when the program crashes */
-        ret = wait_for_stop(h, cntxt);
+        ret = wait_for_stop(cntxt->gdb_handle, cntxt);
         if (ret != GDB_STATE_ERROR)
-           mi_disconnect(h);
+           mi_disconnect(cntxt->gdb_handle);
 
        return ret;
 }

Modified: gnunet/src/monkey/bug_null_pointer_exception.c
===================================================================
--- gnunet/src/monkey/bug_null_pointer_exception.c      2011-04-15 10:01:39 UTC 
(rev 14979)
+++ gnunet/src/monkey/bug_null_pointer_exception.c      2011-04-15 10:02:28 UTC 
(rev 14980)
@@ -1,13 +1,17 @@
 #include <stdio.h>
 #include <string.h>
 
+
+struct CrashStruct {
+       const char *crashValue;
+};
+
 void crashFunction() 
 {
-       char *nullString = NULL;
+       struct CrashStruct *crashStruct;
+       crashStruct = NULL;
        printf("Now the program will crash!\n");
-       if (strcmp(nullString, "A string to compare with") == 0) {
-               printf("How come?! It had to crash!\n");
-       }
+       crashStruct->crashValue = "hello!";
 }
 
 int main(int argc, char *argv[]) 

Modified: gnunet/src/monkey/edb_api.c
===================================================================
--- gnunet/src/monkey/edb_api.c 2011-04-15 10:01:39 UTC (rev 14979)
+++ gnunet/src/monkey/edb_api.c 2011-04-15 10:02:28 UTC (rev 14980)
@@ -82,10 +82,46 @@
 
 
 /**
+ * Return the line number of the end-of-scope for the expression indicated by 
start_line_no
+ *
+ * @param cntxt context containing the Expression Database handle
+ * @param file_name path to the file in which the expression in question exists
+ * @param start_line_no expression's line
+ * @param iter callback function, iterator for values returned from the 
Database
+ * @param iter_cls closure for the expression iterator, will contain the 
scope-end line number
+ * @return GNUNET_OK on success, GNUNET_NO on failure
+ */
+int
+GNUNET_MONKEY_EDB_get_expression_scope_end(struct GNUNET_MONKEY_EDB_Context 
*cntxt,
+                                 const char *file_name, int start_line_no,
+                                 GNUNET_MONKEY_ExpressionIterator iter,
+                                 void *iter_cls)
+{
+       int err;
+       char *errMsg;
+       char *query;
+
+       if (asprintf(&query, "select end_lineno from Expression where file_name 
LIKE \'\%/%s\' and start_lineno = %d", file_name, start_line_no) == -1) {
+               GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Memory allocation problem 
occurred during creating database query!\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;
+}
+
+
+/**
  * Run an SQLite query to retrieve those expressions that are previous to
  * given expression and are in the same scope of the given expression
  * 
- * @param cntxt context containing the Expression Database handle.
+ * @param cntxt context containing the Expression Database handle
  * @param file_name path to the file in which the expression in question exists
  * @param start_line_no expression beginning line
  * @param end_line_no line number for the expression's scope end
@@ -105,11 +141,11 @@
   char *query;
   if (asprintf
       (&query,
-       "select expr_syntax, start_lineno from Expression where file_name = 
\'%s\' and start_lineno < %d and end_lineno = %d",
+       "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.");
+                 "Memory allocation problem occurred!\n");
       return GNUNET_NO;
     }
 

Modified: gnunet/src/monkey/gnunet-monkey.c
===================================================================
--- gnunet/src/monkey/gnunet-monkey.c   2011-04-15 10:01:39 UTC (rev 14979)
+++ gnunet/src/monkey/gnunet-monkey.c   2011-04-15 10:02:28 UTC (rev 14980)
@@ -34,6 +34,8 @@
 static const char* dumpFileName;
 static const char* binaryName;
 static const char* emailAddress;
+static const char* edbFilePath;
+static const char* gdbBinaryPath;
 static int ret = 0;
 
 /**
@@ -51,7 +53,7 @@
      const struct GNUNET_CONFIGURATION_Handle *c)
 {
        int result;
-       struct GNUNET_MONKEY_ACTION_Context* cntxt;
+       struct GNUNET_MONKEY_ACTION_Context *cntxt;
 
        if (strcasecmp(mode, "email") == 0) {
                if (NULL == emailAddress) {
@@ -67,8 +69,12 @@
                }
        }
 
+       /* 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;
+
        result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt);
        switch (result) {
        case GDB_STATE_ERROR:
@@ -79,6 +85,11 @@
                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)) {
+                       GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error using 
Expression Database!\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;
@@ -113,6 +124,10 @@
       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
    };
  
@@ -133,3 +148,4 @@
 
      return 1;
 }
+

Modified: gnunet/src/monkey/gnunet_monkey_action.h
===================================================================
--- gnunet/src/monkey/gnunet_monkey_action.h    2011-04-15 10:01:39 UTC (rev 
14979)
+++ gnunet/src/monkey/gnunet_monkey_action.h    2011-04-15 10:02:28 UTC (rev 
14980)
@@ -53,17 +53,23 @@
 {
        const char* binary_name;
        const char* email_address;
+       const char* expression_database_path;
+       const char* gdb_binary_path;
        int debug_mode;
        char* debug_report;
 
        /* gdb debugging attributes */
+       mi_h *gdb_handle;
+       const char* gdb_in_use;
        mi_stop* gdb_stop_reason;
        mi_frames* gdb_frames;
 };
 
+
 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_format_report(struct GNUNET_MONKEY_ACTION_Context* 
cntxt);
 int GNUNET_MONKEY_ACTION_check_bug_redundancy(void);

Modified: gnunet/src/monkey/gnunet_monkey_edb.h
===================================================================
--- gnunet/src/monkey/gnunet_monkey_edb.h       2011-04-15 10:01:39 UTC (rev 
14979)
+++ gnunet/src/monkey/gnunet_monkey_edb.h       2011-04-15 10:02:28 UTC (rev 
14980)
@@ -60,7 +60,25 @@
                                                 char **);
 
 
+
 /**
+ * Return the line number of the end-of-scope for the expression indicated by 
start_line_no
+ *
+ * @param cntxt context containing the Expression Database handle
+ * @param file_name path to the file in which the expression in question exists
+ * @param start_line_no expression's line
+ * @param iter callback function, iterator for values returned from the 
Database
+ * @param iter_cls closure for the expression iterator, will contain the 
scope-end line number
+ * @return GNUNET_OK on success, GNUNET_NO on failure
+ */
+int
+GNUNET_MONKEY_EDB_get_expression_scope_end(struct GNUNET_MONKEY_EDB_Context 
*cntxt,
+                                 const char *file_name, int start_line_no,
+                                 GNUNET_MONKEY_ExpressionIterator iter,
+                                 void *iter_cls);
+
+
+/**
  * Run an SQLite query to retrieve those expressions that are previous to
  * given expression and are in the same scope of the given expression
  * For example, consider the following code snippet:




reply via email to

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