[Top][All Lists]
[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:
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r14980 - gnunet/src/monkey,
gnunet <=