gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r26063 - monkey/trunk/pathologist/src/pathologist


From: gnunet
Subject: [GNUnet-SVN] r26063 - monkey/trunk/pathologist/src/pathologist
Date: Mon, 11 Feb 2013 10:49:40 +0100

Author: teichm
Date: 2013-02-11 10:49:40 +0100 (Mon, 11 Feb 2013)
New Revision: 26063

Added:
   monkey/trunk/pathologist/src/pathologist/action.c
   monkey/trunk/pathologist/src/pathologist/action.h
Removed:
   monkey/trunk/pathologist/src/pathologist/action_api.c
   monkey/trunk/pathologist/src/pathologist/pathologist_action.h
Modified:
   monkey/trunk/pathologist/src/pathologist/Makefile.am
   monkey/trunk/pathologist/src/pathologist/pathologist.c
Log:
refactored: no more librarys, merged them to one binary to rule them all

Modified: monkey/trunk/pathologist/src/pathologist/Makefile.am
===================================================================
--- monkey/trunk/pathologist/src/pathologist/Makefile.am        2013-02-11 
08:49:40 UTC (rev 26062)
+++ monkey/trunk/pathologist/src/pathologist/Makefile.am        2013-02-11 
09:49:40 UTC (rev 26063)
@@ -1,12 +1,12 @@
 INCLUDES = -I$(top_srcdir)/src/include
 
 if MINGW
- WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols 
+       WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols 
 endif
 
 if USE_COVERAGE
-  AM_CFLAGS = --coverage -O0
-  XLIB = -lgcov
+       AM_CFLAGS = --coverage -O0
+       XLIB = -lgcov
 endif
 
 
@@ -14,57 +14,26 @@
 if HAVE_ESMTP
 if HAVE_OPENSSL
 
-
-lib_LTLIBRARIES = libpathologistedb.la \
-                                 libpathologistaction.la \
-                                 libpathologistxml.la
-
-libpathologistedb_la_SOURCES = \
-  edb_api.c \
-  pathologist_edb.h
-
-libpathologistedb_la_LIBADD = \
-  $(top_builddir)/src/util/libpathologistutil.la \
-  -lsqlite3 \
-  $(XLIB)  
-
-libpathologistaction_la_SOURCES = \
-  action_api.c \
-  pathologist_action.h
-
-libpathologistaction_la_LIBADD = \
-  $(top_builddir)/src/mi/libmi.la \
-  $(top_builddir)/src/pathologist/libpathologistedb.la \
-  $(top_builddir)/src/util/libpathologistutil.la \
-  $(XLIB)
-
-libpathologistxml_la_SOURCES = \
-  xml_writer.c \
-  pathologist_xml_writer.h
-
-libpathologistxml_la_LIBADD = \
-  $(top_builddir)/src/util/libpathologistutil.la \
-  $(XLIB)
-
 bin_PROGRAMS = \
- pathologist
+       pathologist
 
 pathologist_SOURCES = \
- pathologist.c \
- getopt.c \
- getopt_helpers.c \
- mail_sender.c
+       pathologist.c \
+       getopt.c \
+       getopt_helpers.c \
+       mail_sender.c \
+       action.c \
+       xml_writer.c \
+       edb_api.c
 
 pathologist_LDADD = \
-  $(top_builddir)/src/mi/libmi.la \
-  $(top_builddir)/src/util/libpathologistutil.la \
-  $(top_builddir)/src/pathologist/libpathologistedb.la \
-  $(top_builddir)/src/pathologist/libpathologistaction.la \
-  $(top_builddir)/src/pathologist/libpathologistxml.la \
-  -lesmtp \
-  $(GN_LIBINTL)
+       $(top_builddir)/src/mi/libmi.la \
+       $(top_builddir)/src/util/libpathologistutil.la \
+       -lesmtp \
+       -lsqlite3 \
+       $(XLIB) \
+       $(GN_LIBINTL)
 
-
 if ENABLE_TEST_RUN
 if SEASPIDER
 TESTS = $(check_PROGRAMS)
@@ -72,15 +41,16 @@
 endif
 
 check_PROGRAMS = \
-    test_pathologist   
+       test_pathologist        
 
 test_pathologist_SOURCES = \
- test_pathologist.c
+       test_pathologist.c
+
 test_pathologist_LDADD = \
-  $(top_builddir)/src/minixml/libminixml.la
+       $(top_builddir)/src/minixml/libminixml.la
 
 EXTRA_DIST = \
-  ../../refs  
+       ../../refs  
 
 
 endif

Added: monkey/trunk/pathologist/src/pathologist/action.c
===================================================================
--- monkey/trunk/pathologist/src/pathologist/action.c                           
(rev 0)
+++ monkey/trunk/pathologist/src/pathologist/action.c   2013-02-11 09:49:40 UTC 
(rev 26063)
@@ -0,0 +1,1115 @@
+
+#include "monkey_common.h"
+#include "action.h"
+#include "pathologist_edb.h"
+#include "pathologist_xml_writer.h"
+#include <libesmtp.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+extern void sendMail(const char *messageContents, const char *reportFileName,
+                    const char *emailAddress);
+
+static int crashExpressionFoundInEDB = MONKEY_YES;
+static int async_c = 0;
+static int stoppedInSharedLib = MONKEY_NO;
+static int failureFunctionStartLine = 0;       // start line number of the 
function in which the failure occurs
+static struct WatchInfo *watchInfoListHead = NULL;
+static struct WatchInfo *watchInfoListTail = NULL;
+static struct FileName *fileNameListHead = NULL;
+static struct FileName *fileNameListTail = NULL;
+static struct ScopeEnd *scopeEndListHead = NULL;
+static struct ScopeEnd *scopeEndListTail = NULL;
+
+
+struct ScopeEnd {
+    struct ScopeEnd *next;
+    struct ScopeEnd *prev;
+
+    int lineNo;
+};
+
+
+struct FileName {
+    struct FileName *next;
+    struct FileName *prev;
+
+    const char *name;
+};
+
+
+struct Expression {
+    struct Expression *next;
+    struct Expression *prev;
+    const char *expressionSyntax;
+    const char *expressionValue;
+    int isCall;
+};
+
+
+struct Function {
+    struct Function *next;
+    struct Function *prev;
+    const char *name;
+    const char *file;
+    int line;
+    int depth;
+    struct Expression *expressionListHead;
+    struct Expression *expressionListTail;
+};
+
+struct Trace {
+    struct Trace *next;
+    struct Trace *prev;
+    struct Function *functionListHead;
+    struct Function *functionListTail;
+       struct Expression *globalsListHead;
+       struct Expression *globalsListTail;
+};
+
+
+struct Epoch {
+    struct Trace *traceListHead;
+    struct Trace *traceListTail;
+} *epoch;
+
+struct WatchInfo {
+    struct WatchInfo *next;
+    struct WatchInfo *prev;
+    int hitNumber;
+    const char *value;
+};
+
+
+static void cb_console(const char *str, void *data)
+{
+    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)
+{
+    printf("TARGET> %s\n", str);
+}
+
+
+static void cb_log(const char *str, void *data)
+{
+    printf("LOG> %s\n", str);
+}
+
+
+static void cb_to(const char *str, void *data)
+{
+    printf(">> %s", str);
+}
+
+
+static void cb_from(const char *str, void *data)
+{
+    printf("<< %s\n", str);
+}
+
+
+static void cb_async(mi_output * o, void *data)
+{
+    printf("ASYNC\n");
+    async_c++;
+}
+
+static int isInCodeBase(const char *name)
+{
+       struct FileName *fileName = fileNameListHead;
+       while (fileName) {
+               if (strcmp(fileName->name, name) == 0)
+                       return MONKEY_YES;
+               fileName = fileName->next;
+       }
+       return MONKEY_NO;
+}
+
+
+static int wait_for_stop(struct MONKEY_ACTION_Context *cntxt)
+{
+    static int safetyCount = 0;
+
+    while (!mi_get_response(cntxt->gdb_handle))
+               usleep(GDB_MI_ASYNC_WAIT);
+    /* The end of the async. */
+
+    cntxt->gdb_stop_reason = mi_res_stop(cntxt->gdb_handle);
+
+    if (cntxt->gdb_stop_reason) {
+               safetyCount = 0;        // reset the Safety Count whenever you 
stop for a meaningful reason
+
+               switch (cntxt->gdb_stop_reason->reason) {
+               case sr_exited_normally:
+                       return GDB_STATE_EXIT_NORMALLY;
+               case sr_signal_received:
+                       //gmi_set_unwind_on_signal_on(cntxt->gdb_handle);       
// Program crashed. From now on preserve stack on any further received signals
+                       break;
+               case sr_bkpt_hit:
+                       {
+                       /* continue execution */
+                       gmi_exec_continue(cntxt->gdb_handle);
+                       return wait_for_stop(cntxt);
+                       }
+               case sr_wp_trigger:
+                       {
+                       /* Execution stopped because of hitting a watch point */
+                       static int watchPointHitNumber = 0;
+                       struct WatchInfo *watchInfo =
+                               MONKEY_malloc(sizeof(struct WatchInfo));
+                       watchInfo->hitNumber = ++watchPointHitNumber;
+                       watchInfo->value = cntxt->gdb_stop_reason->wp_val;
+                       MONKEY_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);
+                       }
+               case sr_wp_scope:
+                       gmi_exec_continue(cntxt->gdb_handle);
+                       return wait_for_stop(cntxt);
+               default:
+                       break;
+               }
+
+               /* Reaching this line means that the program has stopped 
abnormally OR we are in backtracking mode, and it's a step backward */
+               cntxt->gdb_frames = gmi_stack_list_frames(cntxt->gdb_handle);
+               while ((NULL != cntxt->gdb_frames) && (NULL == 
cntxt->gdb_frames->file)) {
+                       cntxt->gdb_frames = cntxt->gdb_frames->next;
+               }
+
+               if ((NULL != cntxt->gdb_frames) && (MONKEY_YES != 
isInCodeBase(cntxt->gdb_frames->file))) {
+                       do {
+                               cntxt->gdb_frames = cntxt->gdb_frames->next;
+                       } while ((NULL != cntxt->gdb_frames) && (MONKEY_YES != 
isInCodeBase(cntxt->gdb_frames->file)));
+
+                       if ((NULL != cntxt->gdb_frames) && (MONKEY_YES == 
cntxt->run_reverse)) {
+                               /* We are in backtracking mode, we need to move 
GDB from the shared library to our source code */
+                               stoppedInSharedLib = MONKEY_YES;
+                               gmi_break_insert(cntxt->gdb_handle, 
cntxt->gdb_frames->file,
+                                                cntxt->gdb_frames->line);
+                               gmi_exec_continue_reverse(cntxt->gdb_handle);
+                               while (!mi_get_response(cntxt->gdb_handle))
+                                       usleep(GDB_MI_ASYNC_WAIT);
+                               cntxt->gdb_frames = 
gmi_stack_list_frames(cntxt->gdb_handle);
+                       }
+               }
+
+               if (NULL == cntxt->gdb_frames) {
+                       fprintf(stderr, "Cannot get stack frames from gdb. You 
might be debugging the wrong program.\n"); // Something really bad happened. 
Abort!
+                       return GDB_STATE_ERROR;
+               }
+
+               /* 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;
+    }
+    else if ((MONKEY_YES == cntxt->run_reverse) && (safetyCount < 
GDB_SAFETY_COUNT)) { // GDB_SAFETY_COUNT prevents infinite analysis
+       /* If the stop reason is NULL, don't bail out immediately, wait for 
stop again.
+        * It happens when a breakpoint is placed (for backtracking) that the 
program stops for an unknown reason,
+        * resulting in a NULL stop reason which causes Monkey to bail out 
before finishing its analysis. This else if
+        * clause prevents premature bail out
+        */
+       safetyCount++;
+       return wait_for_stop(cntxt);
+    }
+
+    return GDB_STATE_ERROR;
+}
+
+
+int
+MONKEY_ACTION_report_file(struct MONKEY_ACTION_Context *cntxt,
+                         const char *dumpFileName, int isXML)
+{
+       FILE *f;
+       f = MONKEY_XML_WRITER_create_document(dumpFileName);
+       if (NULL == f) {
+               fprintf(stderr, "Error: pathologist was not able to create 
report file.\n");
+               return MONKEY_NO;
+       }
+       MONKEY_XML_WRITER_write_document(f, cntxt->xml_report_node);
+       if (0 != fclose(f)) {
+               fprintf(stderr, "Error: pathologist could not close report 
file.\n");
+               return MONKEY_NO;
+       }
+    return MONKEY_OK;
+}
+
+
+int MONKEY_ACTION_report_email(struct MONKEY_ACTION_Context *cntxt, const char 
* dumpFileName)
+{
+       FILE *f;
+       MONKEY_ACTION_format_report_xml(cntxt);
+       f = MONKEY_XML_WRITER_create_document(dumpFileName);
+       MONKEY_XML_WRITER_write_document(f, cntxt->xml_report_node);
+       fclose(f);
+       sendMail(NULL, dumpFileName, cntxt->email_address);
+    return MONKEY_OK;
+}
+
+
+static int
+iterateFileNames(void *cls, int numColumns, char **colValues,
+                char **colNames)
+{
+    struct FileName *fileName;
+    char *token;
+
+    if (NULL == colValues[0])
+       return 1;               /* Error */
+
+    // This is done to extract the only the file name from the full path 
coming from the Database
+    token = strrchr(colValues[0], '/');
+    if (NULL == token) {
+       token = colValues[0];
+    } else {
+       token++;
+    }
+    fileName = MONKEY_malloc(sizeof(struct FileName));
+    fileName->prev = NULL;
+    fileName->next = NULL;
+    fileName->name = MONKEY_strdup(token);
+    MONKEY_CONTAINER_DLL_insert(fileNameListHead, fileNameListTail, fileName);
+    return 0; /* OK */
+}
+
+
+static int
+outerScopesCallback(void *cls, int numColumns, char **colValues,
+                   char **colNames)
+{
+    if (NULL == colValues[0])
+       return 1;               /* Error */
+
+    struct ScopeEnd *scopeEnd = MONKEY_malloc(sizeof(struct ScopeEnd));
+    scopeEnd->lineNo = atoi(colValues[0]);
+    MONKEY_CONTAINER_DLL_insert(scopeEndListHead, scopeEndListTail,
+                               scopeEnd);
+    return 0;                  /* OK */
+}
+
+
+static int
+iterateExpressions(void *cls, int numColumns, char **colValues,
+                  char **colNames)
+{
+    struct Expression *expression;
+    struct Function *function = (struct Function *) cls;
+
+    if (NULL == colValues[0] || NULL == colValues[1])
+               return 1;               /* Error */
+
+    expression = MONKEY_malloc(sizeof(struct Expression));
+    expression->expressionSyntax = MONKEY_strdup(colValues[0]);
+    expression->isCall = atoi(colValues[1]);
+    expression->expressionValue = NULL;
+    expression->next = NULL;
+    expression->prev = NULL;
+
+    MONKEY_CONTAINER_DLL_insert(function->expressionListHead,
+                               function->expressionListTail, expression);
+
+    return 0;                  /* OK */
+}
+
+
+static int
+iterateGlobals(void *cls, int numColumns, char **colValues,
+                  char **colNames)
+{
+    struct Expression *expression;
+    struct Trace *trace = (struct Trace *) cls;
+
+    if (NULL == colValues[0] || NULL == colValues[1])
+               return 1;               /* Error */
+
+    expression = MONKEY_malloc(sizeof(struct Expression));
+    expression->expressionSyntax = MONKEY_strdup(colValues[0]);
+    expression->isCall = atoi(colValues[1]);
+    expression->expressionValue = NULL;
+    expression->next = NULL;
+    expression->prev = NULL;
+
+    MONKEY_CONTAINER_DLL_insert(trace->globalsListHead,
+                               trace->globalsListTail, 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 isAssignment(const char *expressionSyntax)
+{
+    return (NULL != strstr(expressionSyntax, "=")) ? MONKEY_YES : MONKEY_NO;
+}
+
+
+static struct Expression*
+analyzeExpressionValue(        struct MONKEY_ACTION_Context *cntxt,
+                                       struct Expression *expr,
+                                       struct Expression **expressionListHead,
+                                       struct Expression **expressionListTail)
+{
+       MONKEY_assert(expr);
+       struct Expression *next = expr->next;
+       struct Expression *removedExpression = expr;
+
+       // We will not evaluate function calls (because GDB will evaluate by 
calling the function)
+       if( expr->isCall )
+               goto remove;
+
+       // We should NOT evaluate assignments, otherwise subsequent expression 
evaluations will be spoiled
+       else if( isAssignment(expr->expressionSyntax) )
+               goto remove;
+
+       // NULL Pointer are also ignored (cause theire NULL)
+       if (strcmp(expr->expressionSyntax, "NULL") == 0 ||
+               strcmp(expr->expressionSyntax, "0x0") == 0 ||
+               strcmp(expr->expressionSyntax, "((void*)0)") == 0)
+               goto remove;
+
+       expr->expressionValue =
+       gmi_data_evaluate_expression(   cntxt->gdb_handle,
+                                                                       
expr->expressionSyntax);
+
+       // ignore trivial report entries (constants for that matter)
+       if (expr->expressionValue && strcmp(expr->expressionSyntax, 
expr->expressionValue) == 0)
+               goto remove;
+
+       // ignore functionpointers with their default names
+       size_t value_len; //= strlen(expr->expressionValue);
+       size_t syntax_len; //= strlen(expr->expressionSyntax);
+       if (expr->expressionValue &&
+               (value_len = strlen(expr->expressionValue)) > (syntax_len = 
strlen(expr->expressionSyntax)) + 2 &&
+               !strncmp(expr->expressionValue + value_len - 1, ">", 1) &&
+               !strncmp(expr->expressionValue + value_len - syntax_len - 2, 
"<", 1) &&
+               !strncmp(expr->expressionValue + value_len - syntax_len - 1, 
expr->expressionSyntax, syntax_len))
+               goto remove;
+       
+       if (NULL != expr->expressionValue
+       && (strcmp(expr->expressionValue, "0x0") == 0
+               || strcmp(expr->expressionValue, "NULL") == 0))
+       {
+               expr->expressionValue = "NULL";
+               cntxt->gdb_null_variable = expr->expressionSyntax;
+               cntxt->has_null = MONKEY_YES;
+       }
+
+       return next;
+
+remove:
+       MONKEY_CONTAINER_DLL_remove(*expressionListHead,
+                                                               
*expressionListTail,
+                                                               
removedExpression);
+       return next;
+}
+
+
+static int
+analyzeExpressionValues(struct Function *function,
+                        struct MONKEY_ACTION_Context *cntxt)
+{
+    struct Expression *tmp;
+
+       tmp = function->expressionListHead;
+       while (NULL != tmp) {
+               tmp = analyzeExpressionValue(cntxt, tmp, 
&(function->expressionListHead), &(function->expressionListTail));
+       }
+
+    return MONKEY_OK;
+}
+
+
+static int
+analyzeGlobalsValues(struct Trace *trace,
+                        struct MONKEY_ACTION_Context *cntxt)
+{
+    struct Expression *tmp;
+
+       tmp = trace->globalsListHead;
+       while (NULL != tmp) {
+               tmp = analyzeExpressionValue(cntxt, tmp, 
&(trace->globalsListHead), &(trace->globalsListTail));
+       }
+
+    return MONKEY_OK;
+}
+
+
+static int flushTrace(struct Trace *trace)
+{
+    struct Function *functionPtr = NULL;
+    struct Expression *expressionPtr = NULL;
+
+    while (NULL != trace->functionListHead) {
+       functionPtr = trace->functionListHead;
+       trace->functionListHead = trace->functionListHead->next;
+
+       while (NULL != functionPtr->expressionListHead) {
+           expressionPtr = functionPtr->expressionListHead;
+           functionPtr->expressionListHead =
+               functionPtr->expressionListHead->next;
+
+           MONKEY_free((char *) expressionPtr->expressionSyntax);
+           MONKEY_free(expressionPtr);
+       }
+       MONKEY_free(functionPtr);
+    }
+    return MONKEY_OK;
+}
+
+static void printTrace()
+{
+    int i = 0;
+    struct Function *functionPtr;
+    struct Expression *expressionPtr;
+    struct Trace *tracePtr = epoch->traceListHead;
+    while (NULL != tracePtr) {
+       printf("Program Stack Trace: Epoch Step %d\n", i++);
+       functionPtr = tracePtr->functionListHead;
+       while (NULL != functionPtr) {
+           printf("Function: %s, file: %s, line: %d\n", functionPtr->name,
+                  functionPtr->file, functionPtr->line);
+           printf
+               
("--------------------------------------------------------------------------------------------------\n");
+           printf("Expressions:\n");
+
+           expressionPtr = functionPtr->expressionListHead;
+           while (NULL != expressionPtr) {
+               printf("%s = %s\n",
+                      expressionPtr->expressionSyntax,
+                      (NULL ==
+                       expressionPtr->
+                       expressionValue) ? "No Value" : expressionPtr->
+                      expressionValue);
+               expressionPtr = expressionPtr->next;
+           }
+
+           functionPtr = functionPtr->next;
+       }
+       printf
+           ("############################## End Stack Trace 
######################################################\n\n");
+       tracePtr = tracePtr->next;
+    }
+}
+
+static void flushScopeEndList()
+{
+       struct ScopeEnd* scopeEndPtr;
+       while (NULL != scopeEndListHead) {
+               scopeEndPtr = scopeEndListHead;
+               scopeEndListHead = scopeEndPtr->next;
+               MONKEY_free(scopeEndPtr);
+       }
+
+       scopeEndListHead = NULL;
+       scopeEndListTail = NULL;
+}
+
+int MONKEY_ACTION_inspect_expression_database(struct MONKEY_ACTION_Context 
*cntxt)
+{
+    int ret = MONKEY_OK;
+    int stackDepth = 0;
+       char* file_names = NULL;
+    struct Function *function = NULL;
+    struct Trace *trace = NULL;
+
+    /* Variables used across recursive calls */
+    static struct MONKEY_EDB_Context *edbCntxt;
+
+    if (NULL == epoch) {
+               epoch = MONKEY_malloc(sizeof(struct Epoch));
+               epoch->traceListHead = NULL;
+               epoch->traceListTail = NULL;
+    }
+
+       // Initialize the trace structure for this particular epoch step
+       trace = MONKEY_malloc(sizeof(struct Trace));
+       trace->globalsListHead = NULL;
+       trace->globalsListTail = NULL;
+       MONKEY_CONTAINER_DLL_insert_tail(epoch->traceListHead,
+                                        epoch->traceListTail, trace);
+
+
+       // Create a connection to the Expression Database
+       edbCntxt = MONKEY_EDB_connect(cntxt->expression_database_path);
+       if (NULL == edbCntxt) {
+               fprintf(stderr, "Unable to connect to Expression Database 
file!\n");
+               ret = MONKEY_NO;
+               goto cleanup;
+       }
+
+       while( cntxt->gdb_frames && stackDepth <= cntxt->scope_depth) {
+               gmi_stack_select_frame(cntxt->gdb_handle, 
cntxt->gdb_frames->level);
+       gmi_stack_info_frame(cntxt->gdb_handle);
+
+               // build the function struct
+               function = MONKEY_malloc(sizeof(struct Function));
+               function->depth = stackDepth++;
+               function->line = cntxt->gdb_frames->line;
+               function->name = cntxt->gdb_frames->func;
+               function->file = cntxt->gdb_frames->file;
+               function->expressionListHead = NULL;
+               function->expressionListTail = NULL;
+               function->next = NULL;
+               function->prev = NULL;
+               MONKEY_CONTAINER_DLL_insert_tail(trace->functionListHead,
+                                                trace->functionListTail, 
function);
+
+               // Retrieve scope expressions from the database
+               MONKEY_EDB_get_expressions(edbCntxt,
+                                                                  
cntxt->gdb_frames->file,
+                                                                  
cntxt->gdb_frames->line,
+                                                                  
&iterateExpressions, function);
+
+               // Do value analysis for relevant expressions
+               analyzeExpressionValues(function, cntxt);
+
+               // add current filename to the list
+               char* tmp = file_names;
+               MONKEY_asprintf(&file_names,
+                                               "%s OR file_name LIKE \'%%%s\'",
+                                               file_names,
+                                               cntxt->gdb_frames->file);
+               MONKEY_free_non_null(tmp);
+
+               /* Now, dive deeper into the stack trace */
+               cntxt->gdb_frames = cntxt->gdb_frames->next;
+       }
+
+
+       // Retrieve globals from the database
+       file_names += 10;  // cut the first 10 chars "(null) OR "
+       MONKEY_EDB_get_globals( edbCntxt,
+                                                       file_names,
+                                                       &iterateGlobals, trace);
+       file_names -= 10;
+
+       // Do value analysis for globals
+       analyzeGlobalsValues(trace, cntxt);
+       
+cleanup:
+       MONKEY_EDB_disconnect(edbCntxt);
+       MONKEY_free_non_null(file_names);
+    return ret;
+}
+
+
+int MONKEY_ACTION_start_reverse_execution(struct MONKEY_ACTION_Context
+                                         *cntxt)
+{
+    const char *failureFile = epoch->traceListHead->functionListHead->file;
+    const char *failureFunction =
+       epoch->traceListHead->functionListHead->name;
+    struct Trace *tracePtr = epoch->traceListHead;
+    int oldLine;
+
+    /*
+     * We execute one step back operation before starting analysis. We do that 
to go to the expression before the one where the crash occurred.
+     * Because we already have the expression where the crash happened in our 
stack structure from the previous epoch step (the initial epoch)
+     */
+    if (MONKEY_NO == stoppedInSharedLib) {
+               if (MONKEY_NO != gmi_exec_next_reverse(cntxt->gdb_handle)) {
+                       while (!mi_get_response(cntxt->gdb_handle))
+                               usleep(GDB_MI_ASYNC_WAIT);
+               } else {
+                       fprintf(stderr, "Error: Reverse Execution has failed! 
Backtracking might not be supported for the current architecture.\n");
+                       if (MONKEY_YES == cntxt->gdb_connected) {
+                               mi_disconnect(cntxt->gdb_handle);       // No 
need for gdb mi at this point!
+                               cntxt->gdb_connected = MONKEY_NO;
+                       }
+                       return MONKEY_NO;
+               }
+    }
+
+    /* Do reverse execution for all expressions in the function in which the 
failure occurred */
+    do {
+       oldLine = tracePtr->functionListHead->line;
+               if (MONKEY_NO != gmi_exec_next_reverse(cntxt->gdb_handle)) {
+                       if (GDB_STATE_ERROR == wait_for_stop(cntxt)) {
+                               fprintf(stderr, "Error: Analysis during Reverse 
Execution has failed!\n");
+                               return MONKEY_NO;
+                       }
+                       if (oldLine == cntxt->gdb_frames->line)
+                               break;// We reached the end of record history 
TODO: DIRTY SOLUTION! WILL FAIL IF TWO EXPRESSIONS ON THE SAME LINE
+                       MONKEY_ACTION_inspect_expression_database(cntxt);
+               } else {
+                       fprintf(stderr, "Error: Reverse Execution has 
failed!\n");
+                       return MONKEY_NO;
+               }
+
+       tracePtr = tracePtr->next; // tracePtr will have the new trace added 
after examining the expression database for this reverse execution step
+    } while ((NULL != tracePtr)
+            && (strcmp(failureFile, tracePtr->functionListHead->file) ==
+                0)
+            && (strcmp(failureFunction, tracePtr->functionListHead->name)
+                == 0));
+
+    // stop recording and return
+    gmi_exec_record_stop(cntxt->gdb_handle);
+    return MONKEY_OK;
+}
+
+int MONKEY_ACTION_rerun_with_valgrind(struct MONKEY_ACTION_Context
+                                     *cntxt)
+{
+    char *valgrindCommand;
+    FILE *valgrindPipe;
+    const char *valgrindPath = cntxt->valgrind_binary_path;
+    struct stat buf;
+
+    if (NULL == valgrindPath)
+       valgrindPath = "/usr/bin/valgrind";     /* Assumption for valgrind 
installation */
+
+    /* Check if Valgrind is installed */
+    if (stat(valgrindPath, &buf) != 0 && errno == ENOENT ) {
+       fprintf(stderr,
+               "Warning: Valgrind is not installed. Memory check aborted!\n");
+       return MONKEY_NO;
+    }
+
+    MONKEY_asprintf(&cntxt->valgrind_output_tmp_file_name, "%d", rand());
+    cntxt->debug_mode = DEBUG_MODE_VALGRIND;
+    MONKEY_asprintf(&valgrindCommand,
+                   "%s --leak-check=yes --log-file=%s %s", valgrindPath,
+                   cntxt->valgrind_output_tmp_file_name,
+                   cntxt->binary_name);
+    valgrindPipe = popen(valgrindCommand, "r");
+    if (NULL == valgrindPipe) {
+       fprintf(stderr, "Error in running Valgrind! Memory check aborted!\n");
+       MONKEY_free(valgrindCommand);
+       return MONKEY_NO;
+    }
+
+    pclose(valgrindPipe);
+    MONKEY_free(valgrindCommand);
+    return MONKEY_OK;
+}
+
+
+int MONKEY_ACTION_rerun_with_gdb(struct MONKEY_ACTION_Context
+                                *cntxt)
+{
+    struct MONKEY_EDB_Context *edbCntxt;
+    struct stat buf;
+
+    /* Check if gdb is installed */
+    if (NULL == cntxt->gdb_binary_path) {
+       cntxt->gdb_binary_path = "/usr/bin/gdb"; /* Assumption for gdb default 
installation */
+    }
+       if (stat(cntxt->gdb_binary_path, &buf) != 0 && errno == ENOENT ) {
+               fprintf(stderr,
+                       "Error: gdb is not installed!\n");
+               return MONKEY_NO;
+       }
+
+    epoch = NULL;              /* Initializing epoch Data Structure */
+    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;
+
+    /* Connect to gdb child. */
+    cntxt->gdb_handle = mi_connect_local();
+    if (!cntxt->gdb_handle) {
+       fprintf(stderr, "Error: failed to connect to gdb!\n");
+       return MONKEY_NO;
+    }
+    fprintf(stderr, "Info: Connected to gdb!\n");
+    cntxt->gdb_connected = MONKEY_YES;
+
+    /* 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, 
cntxt->binaryArgs)) {
+               fprintf(stderr, "Error: could not set gdb exec y args\n");
+               goto fail;
+    }
+
+    /* Tell gdb to attach the child to a terminal. */
+    if (!gmi_target_terminal(cntxt->gdb_handle, ttyname(STDIN_FILENO))) {
+               fprintf(stderr, "Error: could not select gdb target 
terminal\n");
+               goto fail;
+    }
+
+
+    if (MONKEY_YES == cntxt->run_reverse) {
+               /* If Backtracking is enabled, we must set a breakpoint at the 
main function, starting the program, then starting recording */
+               mi_bkpt *bp = gmi_break_insert_full(cntxt->gdb_handle, 0, 0, 
NULL, -1, -1, "main");
+               if (NULL == bp) {
+                       fprintf(stderr, "Error: gdb could not set a breakpoint 
at function:%s\n",
+                          cntxt->inspect_function);
+                       goto fail;
+               }
+               mi_free_bkpt(bp);
+    }
+
+
+    if ((NULL != cntxt->inspect_expression) && (NULL != 
cntxt->inspect_function)) {
+               /* 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) {
+                       fprintf(stderr, "Error: gdb could not set a breakpoint 
at function:%s\n", cntxt->inspect_function);
+                       goto fail;
+               }
+               mi_free_bkpt(bp);
+    }
+
+    /* Prepare a list of the file names for the source files we are analyzing 
*/
+    edbCntxt = MONKEY_EDB_connect(cntxt->expression_database_path);
+    if (NULL == edbCntxt) {
+               fprintf(stderr,
+                       "Unable to connect to Expression Database file!\n");
+               goto fail;
+    }
+
+    if (MONKEY_OK != MONKEY_EDB_get_file_names(edbCntxt, &iterateFileNames, 
NULL)) {
+       fprintf(stderr, "Error: Pathologist could not retrieve source file 
names from expression database!\n");
+               goto fail;
+    }
+    MONKEY_EDB_disconnect(edbCntxt);
+
+
+    /* Run the program. */
+    if (!gmi_exec_run(cntxt->gdb_handle)) {
+               fprintf(stderr, "Error: gdb could not run the target 
program!\n");
+               goto fail;
+    }
+
+    /* Backtracking is issued after running the program */
+    if (MONKEY_YES == cntxt->run_reverse) {
+               gmi_exec_record_process(cntxt->gdb_handle);
+    }
+
+    /* Here we should be stopped when the program crashes */
+    ret = wait_for_stop(cntxt);
+    if (ret == GDB_STATE_ERROR || ret == GDB_STATE_EXIT_NORMALLY) {
+               if (MONKEY_YES == cntxt->gdb_connected) {
+                       mi_disconnect(cntxt->gdb_handle);
+                       cntxt->gdb_connected = MONKEY_NO;
+               }
+    }
+
+    return ret;
+
+       // cleanup and abort
+fail:
+       if (MONKEY_YES == cntxt->gdb_connected) {
+               mi_disconnect(cntxt->gdb_handle);
+               cntxt->gdb_connected = MONKEY_NO;
+       }
+       return MONKEY_NO;
+}
+
+
+static const char *expressionListToString(struct Expression *head)
+{
+    char *string = MONKEY_strdup("");
+    char *strTmp;
+    struct Expression *tmp;
+
+    for (tmp = head; NULL != tmp; tmp = tmp->next) {
+       MONKEY_asprintf(&strTmp,
+                       "%s%s => %s\n",
+                       string,
+                       tmp->expressionSyntax,
+                       NULL ==
+                       tmp->
+                       expressionValue ? "Not evaluated" :
+                       tmp->expressionValue);
+       MONKEY_free(string);
+       string = strTmp;
+    }
+    return string;
+}
+
+#if 0
+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 = MONKEY_malloc(getWatchInfoListSize(head));
+    char *strTmp;
+    struct WatchInfo *tmp = head;
+
+    MONKEY_asprintf(&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value);
+    strcpy(string, strTmp);
+    MONKEY_free(strTmp);
+    tmp = tmp->next;
+
+    while (NULL != tmp) {
+       MONKEY_asprintf(&strTmp, "%s\t \t%s\n", tmp->hitNumber,
+                       tmp->value);
+       strcat(string, strTmp);
+       MONKEY_free(strTmp);
+       tmp = tmp->next;
+    }
+
+    return string;
+}
+#endif
+
+static const char *getValgrindOutput(struct 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 = MONKEY_malloc(size);
+    fread(valgrindOutput, size - 1, 1, valgrindFile);
+    fclose(valgrindFile);
+    return valgrindOutput;
+}
+
+
+static struct MONKEY_XML_Node *createXmlSimpleNode(const char *nodeName,
+                                                  const char
+                                                  *nodeInnerText)
+{
+    struct MONKEY_XML_Node *node =
+       MONKEY_XML_WRITER_new_node(nodeName, nodeInnerText);
+    return node;
+}
+
+
+static struct MONKEY_XML_Node *createXmlCrashNode(const char *category,
+                                                 const char *function,
+                                                 int line,
+                                                 const char *file)
+{
+    struct MONKEY_XML_Node *node;
+    char *lineStr;
+
+    MONKEY_asprintf(&lineStr, "%d", line);
+    node = MONKEY_XML_WRITER_new_node("crash", NULL);
+    MONKEY_XML_WRITER_add_attribute(node, "category", category);
+    MONKEY_XML_WRITER_add_attribute(node, "function", function);
+    MONKEY_XML_WRITER_add_attribute(node, "line", lineStr);
+    MONKEY_XML_WRITER_add_attribute(node, "file", file);
+    return node;
+}
+
+
+static struct MONKEY_XML_Node *createXmlEpochStep(int step)
+{
+    struct MONKEY_XML_Node *node;
+    char *stepStr;
+    MONKEY_asprintf(&stepStr, "%d", step);
+    node = MONKEY_XML_WRITER_new_node("epoch", NULL);
+    MONKEY_XML_WRITER_add_attribute(node, "step", stepStr);
+    return node;
+}
+
+
+static struct MONKEY_XML_Node *createXmlFunctionNode(const char *name,
+                                                    int line,
+                                                    const char *file,
+                                                    int depth)
+{
+    struct MONKEY_XML_Node *node;
+    char *lineStr;
+    char *depthStr;
+
+    MONKEY_asprintf(&lineStr, "%d", line);
+    MONKEY_asprintf(&depthStr, "%d", depth);
+    node = MONKEY_XML_WRITER_new_node("function", NULL);
+    MONKEY_XML_WRITER_add_attribute(node, "name", name);
+    MONKEY_XML_WRITER_add_attribute(node, "line", lineStr);
+    MONKEY_XML_WRITER_add_attribute(node, "file", file);
+    MONKEY_XML_WRITER_add_attribute(node, "depth", depthStr);
+    return node;
+}
+
+
+static struct MONKEY_XML_Node *createXmlExpressionNode(const char *name,
+                                                      const char *value)
+{
+    struct MONKEY_XML_Node *node;
+
+    node = MONKEY_XML_WRITER_new_node("expression", value);
+    MONKEY_XML_WRITER_add_attribute(node, "name", name);
+    return node;
+}
+
+
+static struct MONKEY_XML_Node *createXmlGlobalExpressionNode(const char *name,
+                                                       const char *value)
+{
+    struct MONKEY_XML_Node *node;
+
+    node = MONKEY_XML_WRITER_new_node("expression", value);
+    MONKEY_XML_WRITER_add_attribute(node, "name", name);
+    return node;
+}
+
+
+int MONKEY_ACTION_is_Nullpointer(struct MONKEY_ACTION_Context* cntxt)
+{
+       mi_asm_insns* disassembled_code = 
gmi_data_disassemble_se(cntxt->gdb_handle, "$pc", "$pc+1", 0);
+       char* reg;
+       while(reg = strstr(disassembled_code->ins->inst, "(%")) {
+               //printf("%s\n", reg);
+               reg++;
+               size_t len = strcspn(reg, "),");
+               reg[0]='$';
+               reg[len]='\0';
+               char* val = gmi_data_evaluate_expression(cntxt->gdb_handle, 
reg);
+               //printf("%s\n", val);
+               if( !strcmp(val, "0") ) return 1;
+       }
+       return 0;
+}
+
+
+int MONKEY_ACTION_format_report_xml(struct MONKEY_ACTION_Context
+                                   *cntxt)
+{
+    int i = 0;
+    struct MONKEY_XML_Node *node;
+    struct MONKEY_XML_Node *historyNode;
+    struct MONKEY_XML_Node *traceNode;
+    struct MONKEY_XML_Node *globalsNode;
+    struct Trace *tracePtr = epoch->traceListHead;
+    struct Function *functionPtr = tracePtr->functionListHead;
+    struct Expression *expressionPtr;
+
+
+    switch (cntxt->bug_detected) {
+       case BUG_NULL_POINTER:
+               cntxt->xml_report_node = createXmlCrashNode("npe", 
functionPtr->name, functionPtr->line, functionPtr->file);
+               break;
+    case BUG_BAD_MEM_ACCESS:
+               cntxt->xml_report_node = createXmlCrashNode("Bad memory 
access", functionPtr->name, functionPtr->line, functionPtr->file);
+               node = MONKEY_XML_WRITER_add_child(cntxt->xml_report_node, 
createXmlSimpleNode("valgrind", getValgrindOutput(cntxt)));
+               break;
+    case BUG_ABORT:
+               cntxt->xml_report_node = createXmlCrashNode("Assertion 
Failure", functionPtr->name, functionPtr->line, functionPtr->file);
+               break;
+    case BUG_ARITHMETIC:
+               cntxt->xml_report_node = createXmlCrashNode("Division By Zero", 
functionPtr->name, functionPtr->line, functionPtr->file);
+               break;
+    case BUG_SIG_BUS:
+       cntxt->xml_report_node = createXmlCrashNode("Bus Error", 
functionPtr->name, functionPtr->line, functionPtr->file);
+               break;
+    default:
+       cntxt->xml_report_node = createXmlCrashNode("Unknown", 
functionPtr->name, functionPtr->line, functionPtr->file);
+       break;
+    }
+
+    historyNode = MONKEY_XML_WRITER_add_child(cntxt->xml_report_node, 
createXmlSimpleNode("history", NULL));
+
+    /* Adding Stack Trace Nodes to XML Report */
+    while (NULL != tracePtr) {
+               node = MONKEY_XML_WRITER_add_child(historyNode, 
createXmlEpochStep(i));
+               traceNode = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("trace", NULL));
+               globalsNode = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("globals", NULL));
+
+               functionPtr = tracePtr->functionListHead;
+               while (NULL != functionPtr) {
+                       node = MONKEY_XML_WRITER_add_child(traceNode, 
createXmlFunctionNode(functionPtr->name,
+                                                                               
                                                                                
functionPtr->line,
+                                                                               
                                                                                
functionPtr->file,
+                                                                               
                                                                                
functionPtr->depth));
+                       node = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("expressions", NULL));
+
+                       expressionPtr = functionPtr->expressionListHead;
+                       while (NULL != expressionPtr) {
+                               // ignore non helpful expressions
+                               if( expressionPtr->expressionValue )
+                                       MONKEY_XML_WRITER_add_child(node, 
createXmlExpressionNode(expressionPtr->expressionSyntax, 
expressionPtr->expressionValue));
+                               expressionPtr = expressionPtr->next;
+                       }
+
+                       functionPtr = functionPtr->next;
+               }
+
+               expressionPtr = tracePtr->globalsListHead;
+               while( expressionPtr ) {
+                       if( expressionPtr->expressionValue )
+                               MONKEY_XML_WRITER_add_child(globalsNode, 
createXmlGlobalExpressionNode(expressionPtr->expressionSyntax, 
expressionPtr->expressionValue));
+                       expressionPtr = expressionPtr->next;
+               }
+               
+
+               tracePtr = tracePtr->next;
+               i++;
+    }
+    return MONKEY_OK;
+}
+
+
+
+
+int MONKEY_ACTION_delete_context(struct MONKEY_ACTION_Context
+                                *cntxt)
+{
+       if (MONKEY_YES == cntxt->gdb_connected) {
+               mi_disconnect(cntxt->gdb_handle);
+               cntxt->gdb_connected = MONKEY_NO;
+       }
+    if (NULL != cntxt->debug_report)
+       MONKEY_free(cntxt->debug_report);
+    if (NULL != cntxt->valgrind_output_tmp_file_name) {
+       remove(cntxt->valgrind_output_tmp_file_name);
+       MONKEY_free(cntxt->valgrind_output_tmp_file_name);
+    }
+    if (NULL != cntxt->xml_report_node)
+       MONKEY_XML_WRITER_delete_tree(cntxt->xml_report_node);
+    if (NULL != cntxt->binaryArgs)
+       MONKEY_free(cntxt->binaryArgs);
+
+    MONKEY_free(cntxt);
+    return MONKEY_OK;
+}
+
+
+int MONKEY_ACTION_check_bug_redundancy()
+{
+    return MONKEY_OK;
+}

Added: monkey/trunk/pathologist/src/pathologist/action.h
===================================================================
--- monkey/trunk/pathologist/src/pathologist/action.h                           
(rev 0)
+++ monkey/trunk/pathologist/src/pathologist/action.h   2013-02-11 09:49:40 UTC 
(rev 26063)
@@ -0,0 +1,100 @@
+/**
+ * @file monkey/MONKEY_action.h
+ * @brief Monkey API for actions taken by Monkey while debugging
+ */
+
+#ifndef MONKEY_ACTION_H
+#define MONKEY_ACTION_H
+
+#include "gdbmi.h"
+#include "pathologist_xml_writer.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0                          /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+
+/* Debug constants */
+#define DEBUG_MODE_GDB 0
+#define GDB_STATE_STOPPED 1
+#define GDB_STATE_EXIT_NORMALLY 2
+#define GDB_STATE_ERROR 3
+#define GDB_SAFETY_COUNT 2
+#define DEBUG_MODE_VALGRIND 4
+#define DEBUG_MODE_REPORT_READY 5
+#define NO_BUG_DETECTED -1
+#define BUG_NULL_POINTER 6
+#define BUG_ABORT 7
+#define BUG_ARITHMETIC 8
+#define BUG_BAD_MEM_ACCESS 9
+#define BUG_SIG_BUS 10
+#define GDB_MI_ASYNC_WAIT 5
+
+/**
+ * Context for the Action API
+ */
+struct MONKEY_ACTION_Context
+{
+  const char *binary_name;
+  char *binaryArgs;
+  const char *email_address;
+  const char *expression_database_path;
+  const char *gdb_binary_path;
+  const char *valgrind_binary_path;
+  const char *inspect_expression;
+  const char *inspect_function;
+  int debug_mode;
+  int bug_detected;
+  int has_null;
+  char *debug_report;
+  struct MONKEY_XML_Node *xml_report_node;
+
+  /* gdb debugging attributes */
+  int run_reverse;
+  int scope_depth;
+  mi_h *gdb_handle;
+  int gdb_connected;
+  const char *gdb_in_use;
+  mi_stop *gdb_stop_reason;
+  mi_frames *gdb_frames;
+  const char *gdb_null_variable;
+
+  /* Valgrind memcheck attributes */
+  char* valgrind_output_tmp_file_name;
+};
+
+
+int MONKEY_ACTION_report_file (struct MONKEY_ACTION_Context
+                                     *cntxt, const char *dumpFileName, int 
isXML);
+int MONKEY_ACTION_report_email (struct MONKEY_ACTION_Context
+                                      *cntxt, const char *dumpFileName);
+int MONKEY_ACTION_inspect_expression_database (struct
+                                                     MONKEY_ACTION_Context
+                                                     *cntxt);
+int MONKEY_ACTION_rerun_with_gdb (struct MONKEY_ACTION_Context
+                                        *cntxt);
+int MONKEY_ACTION_start_reverse_execution(struct MONKEY_ACTION_Context * 
cntxt);
+int MONKEY_ACTION_rerun_with_valgrind (struct
+                                             MONKEY_ACTION_Context
+                                             *cntxt);
+int MONKEY_ACTION_format_report (struct MONKEY_ACTION_Context
+                                       *cntxt);
+int
+MONKEY_ACTION_format_report_xml (struct MONKEY_ACTION_Context
+                                       *cntxt);
+int MONKEY_ACTION_delete_context(struct MONKEY_ACTION_Context *cntxt);
+
+int MONKEY_ACTION_check_bug_redundancy (void);
+
+
+#if 0                          /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif

Deleted: monkey/trunk/pathologist/src/pathologist/action_api.c
===================================================================
--- monkey/trunk/pathologist/src/pathologist/action_api.c       2013-02-11 
08:49:40 UTC (rev 26062)
+++ monkey/trunk/pathologist/src/pathologist/action_api.c       2013-02-11 
09:49:40 UTC (rev 26063)
@@ -1,1119 +0,0 @@
-/**
- * @file monkey/action_api.c
- * @brief Monkey API for actions taken by Monkey while debugging
- */
-
-#include "monkey_common.h"
-#include "pathologist_action.h"
-#include "pathologist_edb.h"
-#include "pathologist_xml_writer.h"
-#include <libesmtp.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-extern void sendMail(const char *messageContents, const char *reportFileName,
-                    const char *emailAddress);
-
-static int crashExpressionFoundInEDB = MONKEY_YES;
-static int async_c = 0;
-static int stoppedInSharedLib = MONKEY_NO;
-static int failureFunctionStartLine = 0;       // start line number of the 
function in which the failure occurs
-static struct WatchInfo *watchInfoListHead = NULL;
-static struct WatchInfo *watchInfoListTail = NULL;
-static struct FileName *fileNameListHead = NULL;
-static struct FileName *fileNameListTail = NULL;
-static struct ScopeEnd *scopeEndListHead = NULL;
-static struct ScopeEnd *scopeEndListTail = NULL;
-
-
-struct ScopeEnd {
-    struct ScopeEnd *next;
-    struct ScopeEnd *prev;
-
-    int lineNo;
-};
-
-
-struct FileName {
-    struct FileName *next;
-    struct FileName *prev;
-
-    const char *name;
-};
-
-
-struct Expression {
-    struct Expression *next;
-    struct Expression *prev;
-    const char *expressionSyntax;
-    const char *expressionValue;
-    int isCall;
-};
-
-
-struct Function {
-    struct Function *next;
-    struct Function *prev;
-    const char *name;
-    const char *file;
-    int line;
-    int depth;
-    struct Expression *expressionListHead;
-    struct Expression *expressionListTail;
-};
-
-struct Trace {
-    struct Trace *next;
-    struct Trace *prev;
-    struct Function *functionListHead;
-    struct Function *functionListTail;
-       struct Expression *globalsListHead;
-       struct Expression *globalsListTail;
-};
-
-
-struct Epoch {
-    struct Trace *traceListHead;
-    struct Trace *traceListTail;
-} *epoch;
-
-struct WatchInfo {
-    struct WatchInfo *next;
-    struct WatchInfo *prev;
-    int hitNumber;
-    const char *value;
-};
-
-
-static void cb_console(const char *str, void *data)
-{
-    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)
-{
-    printf("TARGET> %s\n", str);
-}
-
-
-static void cb_log(const char *str, void *data)
-{
-    printf("LOG> %s\n", str);
-}
-
-
-static void cb_to(const char *str, void *data)
-{
-    printf(">> %s", str);
-}
-
-
-static void cb_from(const char *str, void *data)
-{
-    printf("<< %s\n", str);
-}
-
-
-static void cb_async(mi_output * o, void *data)
-{
-    printf("ASYNC\n");
-    async_c++;
-}
-
-static int isInCodeBase(const char *name)
-{
-    struct FileName *fileName = fileNameListHead;
-    while (NULL != fileName) {
-       if (strcmp(fileName->name, name) == 0)
-           return MONKEY_YES;
-       fileName = fileName->next;
-    }
-    return MONKEY_NO;
-}
-
-
-static int wait_for_stop(struct MONKEY_ACTION_Context *cntxt)
-{
-    static int safetyCount = 0;
-
-    while (!mi_get_response(cntxt->gdb_handle))
-               usleep(GDB_MI_ASYNC_WAIT);
-    /* The end of the async. */
-
-    cntxt->gdb_stop_reason = mi_res_stop(cntxt->gdb_handle);
-
-    if (cntxt->gdb_stop_reason) {
-               safetyCount = 0;        // reset the Safety Count whenever you 
stop for a meaningful reason
-
-               switch (cntxt->gdb_stop_reason->reason) {
-               case sr_exited_normally:
-                       return GDB_STATE_EXIT_NORMALLY;
-               case sr_signal_received:
-                       //gmi_set_unwind_on_signal_on(cntxt->gdb_handle);       
// Program crashed. From now on preserve stack on any further received signals
-                       break;
-               case sr_bkpt_hit:
-                       {
-                       /* continue execution */
-                       gmi_exec_continue(cntxt->gdb_handle);
-                       return wait_for_stop(cntxt);
-                       }
-               case sr_wp_trigger:
-                       {
-                       /* Execution stopped because of hitting a watch point */
-                       static int watchPointHitNumber = 0;
-                       struct WatchInfo *watchInfo =
-                               MONKEY_malloc(sizeof(struct WatchInfo));
-                       watchInfo->hitNumber = ++watchPointHitNumber;
-                       watchInfo->value = cntxt->gdb_stop_reason->wp_val;
-                       MONKEY_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);
-                       }
-               case sr_wp_scope:
-                       gmi_exec_continue(cntxt->gdb_handle);
-                       return wait_for_stop(cntxt);
-               default:
-                       break;
-               }
-
-               /* Reaching this line means that the program has stopped 
abnormally OR we are in backtracking mode, and it's a step backward */
-               cntxt->gdb_frames = gmi_stack_list_frames(cntxt->gdb_handle);
-               while ((NULL != cntxt->gdb_frames) && (NULL == 
cntxt->gdb_frames->file)) {
-                       cntxt->gdb_frames = cntxt->gdb_frames->next;
-               }
-
-               if ((NULL != cntxt->gdb_frames) && (MONKEY_YES != 
isInCodeBase(cntxt->gdb_frames->file))) {
-                       do {
-                               cntxt->gdb_frames = cntxt->gdb_frames->next;
-                       } while ((NULL != cntxt->gdb_frames) && (MONKEY_YES != 
isInCodeBase(cntxt->gdb_frames->file)));
-
-                       if ((NULL != cntxt->gdb_frames) && (MONKEY_YES == 
cntxt->run_reverse)) {
-                               /* We are in backtracking mode, we need to move 
GDB from the shared library to our source code */
-                               stoppedInSharedLib = MONKEY_YES;
-                               gmi_break_insert(cntxt->gdb_handle, 
cntxt->gdb_frames->file,
-                                                cntxt->gdb_frames->line);
-                               gmi_exec_continue_reverse(cntxt->gdb_handle);
-                               while (!mi_get_response(cntxt->gdb_handle))
-                                       usleep(GDB_MI_ASYNC_WAIT);
-                               cntxt->gdb_frames = 
gmi_stack_list_frames(cntxt->gdb_handle);
-                       }
-               }
-
-               if (NULL == cntxt->gdb_frames) {
-                       fprintf(stderr, "Cannot get stack frames from gdb. You 
might be debugging the wrong program.\n"); // Something really bad happened. 
Abort!
-                       return GDB_STATE_ERROR;
-               }
-
-               /* 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;
-    }
-    else if ((MONKEY_YES == cntxt->run_reverse) && (safetyCount < 
GDB_SAFETY_COUNT)) { // GDB_SAFETY_COUNT prevents infinite analysis
-       /* If the stop reason is NULL, don't bail out immediately, wait for 
stop again.
-        * It happens when a breakpoint is placed (for backtracking) that the 
program stops for an unknown reason,
-        * resulting in a NULL stop reason which causes Monkey to bail out 
before finishing its analysis. This else if
-        * clause prevents premature bail out
-        */
-       safetyCount++;
-       return wait_for_stop(cntxt);
-    }
-
-    return GDB_STATE_ERROR;
-}
-
-
-int
-MONKEY_ACTION_report_file(struct MONKEY_ACTION_Context *cntxt,
-                         const char *dumpFileName, int isXML)
-{
-       FILE *f;
-       f = MONKEY_XML_WRITER_create_document(dumpFileName);
-       if (NULL == f) {
-               fprintf(stderr, "Error: pathologist was not able to create 
report file.\n");
-               return MONKEY_NO;
-       }
-       MONKEY_XML_WRITER_write_document(f, cntxt->xml_report_node);
-       if (0 != fclose(f)) {
-               fprintf(stderr, "Error: pathologist could not close report 
file.\n");
-               return MONKEY_NO;
-       }
-    return MONKEY_OK;
-}
-
-
-int MONKEY_ACTION_report_email(struct MONKEY_ACTION_Context *cntxt, const char 
* dumpFileName)
-{
-       FILE *f;
-       MONKEY_ACTION_format_report_xml(cntxt);
-       f = MONKEY_XML_WRITER_create_document(dumpFileName);
-       MONKEY_XML_WRITER_write_document(f, cntxt->xml_report_node);
-       fclose(f);
-       sendMail(NULL, dumpFileName, cntxt->email_address);
-    return MONKEY_OK;
-}
-
-
-static int
-iterateFileNames(void *cls, int numColumns, char **colValues,
-                char **colNames)
-{
-    struct FileName *fileName;
-    char *token;
-
-    if (NULL == colValues[0])
-       return 1;               /* Error */
-
-    // This is done to extract the only the file name from the full path 
coming from the Database
-    token = strrchr(colValues[0], '/');
-    if (NULL == token) {
-       token = colValues[0];
-    } else {
-       token++;
-    }
-    fileName = MONKEY_malloc(sizeof(struct FileName));
-    fileName->prev = NULL;
-    fileName->next = NULL;
-    fileName->name = MONKEY_strdup(token);
-    MONKEY_CONTAINER_DLL_insert(fileNameListHead, fileNameListTail, fileName);
-    return 0; /* OK */
-}
-
-
-static int
-outerScopesCallback(void *cls, int numColumns, char **colValues,
-                   char **colNames)
-{
-    if (NULL == colValues[0])
-       return 1;               /* Error */
-
-    struct ScopeEnd *scopeEnd = MONKEY_malloc(sizeof(struct ScopeEnd));
-    scopeEnd->lineNo = atoi(colValues[0]);
-    MONKEY_CONTAINER_DLL_insert(scopeEndListHead, scopeEndListTail,
-                               scopeEnd);
-    return 0;                  /* OK */
-}
-
-
-static int
-iterateExpressions(void *cls, int numColumns, char **colValues,
-                  char **colNames)
-{
-    struct Expression *expression;
-    struct Function *function = (struct Function *) cls;
-
-    if (NULL == colValues[0] || NULL == colValues[1])
-               return 1;               /* Error */
-
-    expression = MONKEY_malloc(sizeof(struct Expression));
-    expression->expressionSyntax = MONKEY_strdup(colValues[0]);
-    expression->isCall = atoi(colValues[1]);
-    expression->expressionValue = NULL;
-    expression->next = NULL;
-    expression->prev = NULL;
-
-    MONKEY_CONTAINER_DLL_insert(function->expressionListHead,
-                               function->expressionListTail, expression);
-
-    return 0;                  /* OK */
-}
-
-
-static int
-iterateGlobals(void *cls, int numColumns, char **colValues,
-                  char **colNames)
-{
-    struct Expression *expression;
-    struct Trace *trace = (struct Trace *) cls;
-
-    if (NULL == colValues[0] || NULL == colValues[1])
-               return 1;               /* Error */
-
-    expression = MONKEY_malloc(sizeof(struct Expression));
-    expression->expressionSyntax = MONKEY_strdup(colValues[0]);
-    expression->isCall = atoi(colValues[1]);
-    expression->expressionValue = NULL;
-    expression->next = NULL;
-    expression->prev = NULL;
-
-    MONKEY_CONTAINER_DLL_insert(trace->globalsListHead,
-                               trace->globalsListTail, 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 isAssignment(const char *expressionSyntax)
-{
-    return (NULL != strstr(expressionSyntax, "=")) ? MONKEY_YES : MONKEY_NO;
-}
-
-
-static struct Expression*
-analyzeExpressionValue(        struct MONKEY_ACTION_Context *cntxt,
-                                       struct Expression *expr,
-                                       struct Expression **expressionListHead,
-                                       struct Expression **expressionListTail)
-{
-       MONKEY_assert(expr);
-       struct Expression *next = expr->next;
-       struct Expression *removedExpression = expr;
-
-       // We will not evaluate function calls (because GDB will evaluate by 
calling the function)
-       if( expr->isCall )
-               goto remove;
-
-       // We should NOT evaluate assignments, otherwise subsequent expression 
evaluations will be spoiled
-       else if( isAssignment(expr->expressionSyntax) )
-               goto remove;
-
-       // NULL Pointer are also ignored (cause theire NULL)
-       if (strcmp(expr->expressionSyntax, "NULL") == 0 ||
-               strcmp(expr->expressionSyntax, "0x0") == 0 ||
-               strcmp(expr->expressionSyntax, "((void*)0)") == 0)
-               goto remove;
-
-       expr->expressionValue =
-       gmi_data_evaluate_expression(   cntxt->gdb_handle,
-                                                                       
expr->expressionSyntax);
-
-       // ignore trivial report entries (constants for that matter)
-       if (expr->expressionValue && strcmp(expr->expressionSyntax, 
expr->expressionValue) == 0)
-               goto remove;
-
-       // ignore functionpointers with their default names
-       size_t value_len; //= strlen(expr->expressionValue);
-       size_t syntax_len; //= strlen(expr->expressionSyntax);
-       if (expr->expressionValue &&
-               (value_len = strlen(expr->expressionValue)) > (syntax_len = 
strlen(expr->expressionSyntax)) + 2 &&
-               !strncmp(expr->expressionValue + value_len - 1, ">", 1) &&
-               !strncmp(expr->expressionValue + value_len - syntax_len - 2, 
"<", 1) &&
-               !strncmp(expr->expressionValue + value_len - syntax_len - 1, 
expr->expressionSyntax, syntax_len))
-               goto remove;
-       
-       if (NULL != expr->expressionValue
-       && (strcmp(expr->expressionValue, "0x0") == 0
-               || strcmp(expr->expressionValue, "NULL") == 0))
-       {
-               expr->expressionValue = "NULL";
-               cntxt->gdb_null_variable = expr->expressionSyntax;
-               cntxt->has_null = MONKEY_YES;
-       }
-
-       return next;
-
-remove:
-       MONKEY_CONTAINER_DLL_remove(*expressionListHead,
-                                                               
*expressionListTail,
-                                                               
removedExpression);
-       return next;
-}
-
-
-static int
-analyzeExpressionValues(struct Function *function,
-                        struct MONKEY_ACTION_Context *cntxt)
-{
-    struct Expression *tmp;
-
-       tmp = function->expressionListHead;
-       while (NULL != tmp) {
-               tmp = analyzeExpressionValue(cntxt, tmp, 
&(function->expressionListHead), &(function->expressionListTail));
-       }
-
-    return MONKEY_OK;
-}
-
-
-static int
-analyzeGlobalsValues(struct Trace *trace,
-                        struct MONKEY_ACTION_Context *cntxt)
-{
-    struct Expression *tmp;
-
-       tmp = trace->globalsListHead;
-       while (NULL != tmp) {
-               tmp = analyzeExpressionValue(cntxt, tmp, 
&(trace->globalsListHead), &(trace->globalsListTail));
-       }
-
-    return MONKEY_OK;
-}
-
-
-static int flushTrace(struct Trace *trace)
-{
-    struct Function *functionPtr = NULL;
-    struct Expression *expressionPtr = NULL;
-
-    while (NULL != trace->functionListHead) {
-       functionPtr = trace->functionListHead;
-       trace->functionListHead = trace->functionListHead->next;
-
-       while (NULL != functionPtr->expressionListHead) {
-           expressionPtr = functionPtr->expressionListHead;
-           functionPtr->expressionListHead =
-               functionPtr->expressionListHead->next;
-
-           MONKEY_free((char *) expressionPtr->expressionSyntax);
-           MONKEY_free(expressionPtr);
-       }
-       MONKEY_free(functionPtr);
-    }
-    return MONKEY_OK;
-}
-
-static void printTrace()
-{
-    int i = 0;
-    struct Function *functionPtr;
-    struct Expression *expressionPtr;
-    struct Trace *tracePtr = epoch->traceListHead;
-    while (NULL != tracePtr) {
-       printf("Program Stack Trace: Epoch Step %d\n", i++);
-       functionPtr = tracePtr->functionListHead;
-       while (NULL != functionPtr) {
-           printf("Function: %s, file: %s, line: %d\n", functionPtr->name,
-                  functionPtr->file, functionPtr->line);
-           printf
-               
("--------------------------------------------------------------------------------------------------\n");
-           printf("Expressions:\n");
-
-           expressionPtr = functionPtr->expressionListHead;
-           while (NULL != expressionPtr) {
-               printf("%s = %s\n",
-                      expressionPtr->expressionSyntax,
-                      (NULL ==
-                       expressionPtr->
-                       expressionValue) ? "No Value" : expressionPtr->
-                      expressionValue);
-               expressionPtr = expressionPtr->next;
-           }
-
-           functionPtr = functionPtr->next;
-       }
-       printf
-           ("############################## End Stack Trace 
######################################################\n\n");
-       tracePtr = tracePtr->next;
-    }
-}
-
-static void flushScopeEndList()
-{
-       struct ScopeEnd* scopeEndPtr;
-       while (NULL != scopeEndListHead) {
-               scopeEndPtr = scopeEndListHead;
-               scopeEndListHead = scopeEndPtr->next;
-               MONKEY_free(scopeEndPtr);
-       }
-
-       scopeEndListHead = NULL;
-       scopeEndListTail = NULL;
-}
-
-int MONKEY_ACTION_inspect_expression_database(struct MONKEY_ACTION_Context 
*cntxt)
-{
-    int ret = MONKEY_OK;
-    int stackDepth = 0;
-       char* file_names = NULL;
-    struct Function *function = NULL;
-    struct Trace *trace = NULL;
-
-    /* Variables used across recursive calls */
-    static struct MONKEY_EDB_Context *edbCntxt;
-
-    if (NULL == epoch) {
-               epoch = MONKEY_malloc(sizeof(struct Epoch));
-               epoch->traceListHead = NULL;
-               epoch->traceListTail = NULL;
-    }
-
-       // Initialize the trace structure for this particular epoch step
-       trace = MONKEY_malloc(sizeof(struct Trace));
-       trace->globalsListHead = NULL;
-       trace->globalsListTail = NULL;
-       MONKEY_CONTAINER_DLL_insert_tail(epoch->traceListHead,
-                                        epoch->traceListTail, trace);
-
-
-       // Create a connection to the Expression Database
-       edbCntxt = MONKEY_EDB_connect(cntxt->expression_database_path);
-       if (NULL == edbCntxt) {
-               fprintf(stderr, "Unable to connect to Expression Database 
file!\n");
-               ret = MONKEY_NO;
-               goto cleanup;
-       }
-
-       while( cntxt->gdb_frames && stackDepth <= cntxt->scope_depth) {
-               gmi_stack_select_frame(cntxt->gdb_handle, 
cntxt->gdb_frames->level);
-       gmi_stack_info_frame(cntxt->gdb_handle);
-
-               // build the function struct
-               function = MONKEY_malloc(sizeof(struct Function));
-               function->depth = stackDepth++;
-               function->line = cntxt->gdb_frames->line;
-               function->name = cntxt->gdb_frames->func;
-               function->file = cntxt->gdb_frames->file;
-               function->expressionListHead = NULL;
-               function->expressionListTail = NULL;
-               function->next = NULL;
-               function->prev = NULL;
-               MONKEY_CONTAINER_DLL_insert_tail(trace->functionListHead,
-                                                trace->functionListTail, 
function);
-
-               // Retrieve scope expressions from the database
-               MONKEY_EDB_get_expressions(edbCntxt,
-                                                                  
cntxt->gdb_frames->file,
-                                                                  
cntxt->gdb_frames->line,
-                                                                  
&iterateExpressions, function);
-
-               // Do value analysis for relevant expressions
-               analyzeExpressionValues(function, cntxt);
-
-               // add current filename to the list
-               char* tmp = file_names;
-               MONKEY_asprintf(&file_names,
-                                               "%s OR file_name LIKE \'%%%s\'",
-                                               file_names,
-                                               cntxt->gdb_frames->file);
-               MONKEY_free_non_null(tmp);
-
-               /* Now, dive deeper into the stack trace */
-               cntxt->gdb_frames = cntxt->gdb_frames->next;
-       }
-
-
-       // Retrieve globals from the database
-       file_names += 10;  // cut the first 10 chars "(null) OR "
-       MONKEY_EDB_get_globals( edbCntxt,
-                                                       file_names,
-                                                       &iterateGlobals, trace);
-       file_names -= 10;
-
-       // Do value analysis for globals
-       analyzeGlobalsValues(trace, cntxt);
-       
-cleanup:
-       MONKEY_EDB_disconnect(edbCntxt);
-       MONKEY_free_non_null(file_names);
-    return ret;
-}
-
-
-int MONKEY_ACTION_start_reverse_execution(struct MONKEY_ACTION_Context
-                                         *cntxt)
-{
-    const char *failureFile = epoch->traceListHead->functionListHead->file;
-    const char *failureFunction =
-       epoch->traceListHead->functionListHead->name;
-    struct Trace *tracePtr = epoch->traceListHead;
-    int oldLine;
-
-    /*
-     * We execute one step back operation before starting analysis. We do that 
to go to the expression before the one where the crash occurred.
-     * Because we already have the expression where the crash happened in our 
stack structure from the previous epoch step (the initial epoch)
-     */
-    if (MONKEY_NO == stoppedInSharedLib) {
-               if (MONKEY_NO != gmi_exec_next_reverse(cntxt->gdb_handle)) {
-                       while (!mi_get_response(cntxt->gdb_handle))
-                               usleep(GDB_MI_ASYNC_WAIT);
-               } else {
-                       fprintf(stderr, "Error: Reverse Execution has failed! 
Backtracking might not be supported for the current architecture.\n");
-                       if (MONKEY_YES == cntxt->gdb_connected) {
-                               mi_disconnect(cntxt->gdb_handle);       // No 
need for gdb mi at this point!
-                               cntxt->gdb_connected = MONKEY_NO;
-                       }
-                       return MONKEY_NO;
-               }
-    }
-
-    /* Do reverse execution for all expressions in the function in which the 
failure occurred */
-    do {
-       oldLine = tracePtr->functionListHead->line;
-               if (MONKEY_NO != gmi_exec_next_reverse(cntxt->gdb_handle)) {
-                       if (GDB_STATE_ERROR == wait_for_stop(cntxt)) {
-                               fprintf(stderr, "Error: Analysis during Reverse 
Execution has failed!\n");
-                               return MONKEY_NO;
-                       }
-                       if (oldLine == cntxt->gdb_frames->line)
-                               break;// We reached the end of record history 
TODO: DIRTY SOLUTION! WILL FAIL IF TWO EXPRESSIONS ON THE SAME LINE
-                       MONKEY_ACTION_inspect_expression_database(cntxt);
-               } else {
-                       fprintf(stderr, "Error: Reverse Execution has 
failed!\n");
-                       return MONKEY_NO;
-               }
-
-       tracePtr = tracePtr->next; // tracePtr will have the new trace added 
after examining the expression database for this reverse execution step
-    } while ((NULL != tracePtr)
-            && (strcmp(failureFile, tracePtr->functionListHead->file) ==
-                0)
-            && (strcmp(failureFunction, tracePtr->functionListHead->name)
-                == 0));
-
-    // stop recording and return
-    gmi_exec_record_stop(cntxt->gdb_handle);
-    return MONKEY_OK;
-}
-
-int MONKEY_ACTION_rerun_with_valgrind(struct MONKEY_ACTION_Context
-                                     *cntxt)
-{
-    char *valgrindCommand;
-    FILE *valgrindPipe;
-    const char *valgrindPath = cntxt->valgrind_binary_path;
-    struct stat buf;
-
-    if (NULL == valgrindPath)
-       valgrindPath = "/usr/bin/valgrind";     /* Assumption for valgrind 
installation */
-
-    /* Check if Valgrind is installed */
-    if (stat(valgrindPath, &buf) != 0 && errno == ENOENT ) {
-       fprintf(stderr,
-               "Warning: Valgrind is not installed. Memory check aborted!\n");
-       return MONKEY_NO;
-    }
-
-    MONKEY_asprintf(&cntxt->valgrind_output_tmp_file_name, "%d", rand());
-    cntxt->debug_mode = DEBUG_MODE_VALGRIND;
-    MONKEY_asprintf(&valgrindCommand,
-                   "%s --leak-check=yes --log-file=%s %s", valgrindPath,
-                   cntxt->valgrind_output_tmp_file_name,
-                   cntxt->binary_name);
-    valgrindPipe = popen(valgrindCommand, "r");
-    if (NULL == valgrindPipe) {
-       fprintf(stderr, "Error in running Valgrind! Memory check aborted!\n");
-       MONKEY_free(valgrindCommand);
-       return MONKEY_NO;
-    }
-
-    pclose(valgrindPipe);
-    MONKEY_free(valgrindCommand);
-    return MONKEY_OK;
-}
-
-
-int MONKEY_ACTION_rerun_with_gdb(struct MONKEY_ACTION_Context
-                                *cntxt)
-{
-    struct MONKEY_EDB_Context *edbCntxt;
-    struct stat buf;
-
-    /* Check if gdb is installed */
-    if (NULL == cntxt->gdb_binary_path) {
-       cntxt->gdb_binary_path = "/usr/bin/gdb"; /* Assumption for gdb default 
installation */
-    }
-       if (stat(cntxt->gdb_binary_path, &buf) != 0 && errno == ENOENT ) {
-               fprintf(stderr,
-                       "Error: gdb is not installed!\n");
-               return MONKEY_NO;
-       }
-
-    epoch = NULL;              /* Initializing epoch Data Structure */
-    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;
-
-    /* Connect to gdb child. */
-    cntxt->gdb_handle = mi_connect_local();
-    if (!cntxt->gdb_handle) {
-       fprintf(stderr, "Error: failed to connect to gdb!\n");
-       return MONKEY_NO;
-    }
-    fprintf(stderr, "Info: Connected to gdb!\n");
-    cntxt->gdb_connected = MONKEY_YES;
-
-    /* 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, 
cntxt->binaryArgs)) {
-               fprintf(stderr, "Error: could not set gdb exec y args\n");
-               goto fail;
-    }
-
-    /* Tell gdb to attach the child to a terminal. */
-    if (!gmi_target_terminal(cntxt->gdb_handle, ttyname(STDIN_FILENO))) {
-               fprintf(stderr, "Error: could not select gdb target 
terminal\n");
-               goto fail;
-    }
-
-
-    if (MONKEY_YES == cntxt->run_reverse) {
-               /* If Backtracking is enabled, we must set a breakpoint at the 
main function, starting the program, then starting recording */
-               mi_bkpt *bp = gmi_break_insert_full(cntxt->gdb_handle, 0, 0, 
NULL, -1, -1, "main");
-               if (NULL == bp) {
-                       fprintf(stderr, "Error: gdb could not set a breakpoint 
at function:%s\n",
-                          cntxt->inspect_function);
-                       goto fail;
-               }
-               mi_free_bkpt(bp);
-    }
-
-
-    if ((NULL != cntxt->inspect_expression) && (NULL != 
cntxt->inspect_function)) {
-               /* 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) {
-                       fprintf(stderr, "Error: gdb could not set a breakpoint 
at function:%s\n", cntxt->inspect_function);
-                       goto fail;
-               }
-               mi_free_bkpt(bp);
-    }
-
-    /* Prepare a list of the file names for the source files we are analyzing 
*/
-    edbCntxt = MONKEY_EDB_connect(cntxt->expression_database_path);
-    if (NULL == edbCntxt) {
-               fprintf(stderr,
-                       "Unable to connect to Expression Database file!\n");
-               goto fail;
-    }
-
-    if (MONKEY_OK != MONKEY_EDB_get_file_names(edbCntxt, &iterateFileNames, 
NULL)) {
-       fprintf(stderr, "Error: Pathologist could not retrieve source file 
names from expression database!\n");
-               goto fail;
-    }
-    MONKEY_EDB_disconnect(edbCntxt);
-
-
-    /* Run the program. */
-    if (!gmi_exec_run(cntxt->gdb_handle)) {
-               fprintf(stderr, "Error: gdb could not run the target 
program!\n");
-               goto fail;
-    }
-
-    /* Backtracking is issued after running the program */
-    if (MONKEY_YES == cntxt->run_reverse) {
-               gmi_exec_record_process(cntxt->gdb_handle);
-    }
-
-    /* Here we should be stopped when the program crashes */
-    ret = wait_for_stop(cntxt);
-    if (ret == GDB_STATE_ERROR || ret == GDB_STATE_EXIT_NORMALLY) {
-               if (MONKEY_YES == cntxt->gdb_connected) {
-                       mi_disconnect(cntxt->gdb_handle);
-                       cntxt->gdb_connected = MONKEY_NO;
-               }
-    }
-
-    return ret;
-
-       // cleanup and abort
-fail:
-       if (MONKEY_YES == cntxt->gdb_connected) {
-               mi_disconnect(cntxt->gdb_handle);
-               cntxt->gdb_connected = MONKEY_NO;
-       }
-       return MONKEY_NO;
-}
-
-
-static const char *expressionListToString(struct Expression *head)
-{
-    char *string = MONKEY_strdup("");
-    char *strTmp;
-    struct Expression *tmp;
-
-    for (tmp = head; NULL != tmp; tmp = tmp->next) {
-       MONKEY_asprintf(&strTmp,
-                       "%s%s => %s\n",
-                       string,
-                       tmp->expressionSyntax,
-                       NULL ==
-                       tmp->
-                       expressionValue ? "Not evaluated" :
-                       tmp->expressionValue);
-       MONKEY_free(string);
-       string = strTmp;
-    }
-    return string;
-}
-
-#if 0
-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 = MONKEY_malloc(getWatchInfoListSize(head));
-    char *strTmp;
-    struct WatchInfo *tmp = head;
-
-    MONKEY_asprintf(&strTmp, "%s\t \t%s\n", tmp->hitNumber, tmp->value);
-    strcpy(string, strTmp);
-    MONKEY_free(strTmp);
-    tmp = tmp->next;
-
-    while (NULL != tmp) {
-       MONKEY_asprintf(&strTmp, "%s\t \t%s\n", tmp->hitNumber,
-                       tmp->value);
-       strcat(string, strTmp);
-       MONKEY_free(strTmp);
-       tmp = tmp->next;
-    }
-
-    return string;
-}
-#endif
-
-static const char *getValgrindOutput(struct 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 = MONKEY_malloc(size);
-    fread(valgrindOutput, size - 1, 1, valgrindFile);
-    fclose(valgrindFile);
-    return valgrindOutput;
-}
-
-
-static struct MONKEY_XML_Node *createXmlSimpleNode(const char *nodeName,
-                                                  const char
-                                                  *nodeInnerText)
-{
-    struct MONKEY_XML_Node *node =
-       MONKEY_XML_WRITER_new_node(nodeName, nodeInnerText);
-    return node;
-}
-
-
-static struct MONKEY_XML_Node *createXmlCrashNode(const char *category,
-                                                 const char *function,
-                                                 int line,
-                                                 const char *file)
-{
-    struct MONKEY_XML_Node *node;
-    char *lineStr;
-
-    MONKEY_asprintf(&lineStr, "%d", line);
-    node = MONKEY_XML_WRITER_new_node("crash", NULL);
-    MONKEY_XML_WRITER_add_attribute(node, "category", category);
-    MONKEY_XML_WRITER_add_attribute(node, "function", function);
-    MONKEY_XML_WRITER_add_attribute(node, "line", lineStr);
-    MONKEY_XML_WRITER_add_attribute(node, "file", file);
-    return node;
-}
-
-
-static struct MONKEY_XML_Node *createXmlEpochStep(int step)
-{
-    struct MONKEY_XML_Node *node;
-    char *stepStr;
-    MONKEY_asprintf(&stepStr, "%d", step);
-    node = MONKEY_XML_WRITER_new_node("epoch", NULL);
-    MONKEY_XML_WRITER_add_attribute(node, "step", stepStr);
-    return node;
-}
-
-
-static struct MONKEY_XML_Node *createXmlFunctionNode(const char *name,
-                                                    int line,
-                                                    const char *file,
-                                                    int depth)
-{
-    struct MONKEY_XML_Node *node;
-    char *lineStr;
-    char *depthStr;
-
-    MONKEY_asprintf(&lineStr, "%d", line);
-    MONKEY_asprintf(&depthStr, "%d", depth);
-    node = MONKEY_XML_WRITER_new_node("function", NULL);
-    MONKEY_XML_WRITER_add_attribute(node, "name", name);
-    MONKEY_XML_WRITER_add_attribute(node, "line", lineStr);
-    MONKEY_XML_WRITER_add_attribute(node, "file", file);
-    MONKEY_XML_WRITER_add_attribute(node, "depth", depthStr);
-    return node;
-}
-
-
-static struct MONKEY_XML_Node *createXmlExpressionNode(const char *name,
-                                                      const char *value)
-{
-    struct MONKEY_XML_Node *node;
-
-    node = MONKEY_XML_WRITER_new_node("expression", value);
-    MONKEY_XML_WRITER_add_attribute(node, "name", name);
-    return node;
-}
-
-
-static struct MONKEY_XML_Node *createXmlGlobalExpressionNode(const char *name,
-                                                       const char *value)
-{
-    struct MONKEY_XML_Node *node;
-
-    node = MONKEY_XML_WRITER_new_node("expression", value);
-    MONKEY_XML_WRITER_add_attribute(node, "name", name);
-    return node;
-}
-
-
-int MONKEY_ACTION_is_Nullpointer(struct MONKEY_ACTION_Context* cntxt)
-{
-       mi_asm_insns* disassembled_code = 
gmi_data_disassemble_se(cntxt->gdb_handle, "$pc", "$pc+1", 0);
-       char* reg;
-       while(reg = strstr(disassembled_code->ins->inst, "(%")) {
-               //printf("%s\n", reg);
-               reg++;
-               size_t len = strcspn(reg, "),");
-               reg[0]='$';
-               reg[len]='\0';
-               char* val = gmi_data_evaluate_expression(cntxt->gdb_handle, 
reg);
-               //printf("%s\n", val);
-               if( !strcmp(val, "0") ) return 1;
-       }
-       return 0;
-}
-
-
-int MONKEY_ACTION_format_report_xml(struct MONKEY_ACTION_Context
-                                   *cntxt)
-{
-    int i = 0;
-    struct MONKEY_XML_Node *node;
-    struct MONKEY_XML_Node *historyNode;
-    struct MONKEY_XML_Node *traceNode;
-    struct MONKEY_XML_Node *globalsNode;
-    struct Trace *tracePtr = epoch->traceListHead;
-    struct Function *functionPtr = tracePtr->functionListHead;
-    struct Expression *expressionPtr;
-
-
-    switch (cntxt->bug_detected) {
-       case BUG_NULL_POINTER:
-               cntxt->xml_report_node = createXmlCrashNode("npe", 
functionPtr->name, functionPtr->line, functionPtr->file);
-               break;
-    case BUG_BAD_MEM_ACCESS:
-               cntxt->xml_report_node = createXmlCrashNode("Bad memory 
access", functionPtr->name, functionPtr->line, functionPtr->file);
-               node = MONKEY_XML_WRITER_add_child(cntxt->xml_report_node, 
createXmlSimpleNode("valgrind", getValgrindOutput(cntxt)));
-               break;
-    case BUG_ABORT:
-               cntxt->xml_report_node = createXmlCrashNode("Assertion 
Failure", functionPtr->name, functionPtr->line, functionPtr->file);
-               break;
-    case BUG_ARITHMETIC:
-               cntxt->xml_report_node = createXmlCrashNode("Division By Zero", 
functionPtr->name, functionPtr->line, functionPtr->file);
-               break;
-    case BUG_SIG_BUS:
-       cntxt->xml_report_node = createXmlCrashNode("Bus Error", 
functionPtr->name, functionPtr->line, functionPtr->file);
-               break;
-    default:
-       cntxt->xml_report_node = createXmlCrashNode("Unknown", 
functionPtr->name, functionPtr->line, functionPtr->file);
-       break;
-    }
-
-    historyNode = MONKEY_XML_WRITER_add_child(cntxt->xml_report_node, 
createXmlSimpleNode("history", NULL));
-
-    /* Adding Stack Trace Nodes to XML Report */
-    while (NULL != tracePtr) {
-               node = MONKEY_XML_WRITER_add_child(historyNode, 
createXmlEpochStep(i));
-               traceNode = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("trace", NULL));
-               globalsNode = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("globals", NULL));
-
-               functionPtr = tracePtr->functionListHead;
-               while (NULL != functionPtr) {
-                       node = MONKEY_XML_WRITER_add_child(traceNode, 
createXmlFunctionNode(functionPtr->name,
-                                                                               
                                                                                
functionPtr->line,
-                                                                               
                                                                                
functionPtr->file,
-                                                                               
                                                                                
functionPtr->depth));
-                       node = MONKEY_XML_WRITER_add_child(node, 
createXmlSimpleNode("expressions", NULL));
-
-                       expressionPtr = functionPtr->expressionListHead;
-                       while (NULL != expressionPtr) {
-                               // ignore non helpful expressions
-                               if( expressionPtr->expressionValue )
-                                       MONKEY_XML_WRITER_add_child(node, 
createXmlExpressionNode(expressionPtr->expressionSyntax, 
expressionPtr->expressionValue));
-                               expressionPtr = expressionPtr->next;
-                       }
-
-                       functionPtr = functionPtr->next;
-               }
-
-               expressionPtr = tracePtr->globalsListHead;
-               while( expressionPtr ) {
-                       if( expressionPtr->expressionValue )
-                               MONKEY_XML_WRITER_add_child(globalsNode, 
createXmlGlobalExpressionNode(expressionPtr->expressionSyntax, 
expressionPtr->expressionValue));
-                       expressionPtr = expressionPtr->next;
-               }
-               
-
-               tracePtr = tracePtr->next;
-               i++;
-    }
-    return MONKEY_OK;
-}
-
-
-
-
-int MONKEY_ACTION_delete_context(struct MONKEY_ACTION_Context
-                                *cntxt)
-{
-       if (MONKEY_YES == cntxt->gdb_connected) {
-               mi_disconnect(cntxt->gdb_handle);
-               cntxt->gdb_connected = MONKEY_NO;
-       }
-    if (NULL != cntxt->debug_report)
-       MONKEY_free(cntxt->debug_report);
-    if (NULL != cntxt->valgrind_output_tmp_file_name) {
-       remove(cntxt->valgrind_output_tmp_file_name);
-       MONKEY_free(cntxt->valgrind_output_tmp_file_name);
-    }
-    if (NULL != cntxt->xml_report_node)
-       MONKEY_XML_WRITER_delete_tree(cntxt->xml_report_node);
-    if (NULL != cntxt->binaryArgs)
-       MONKEY_free(cntxt->binaryArgs);
-
-    MONKEY_free(cntxt);
-    return MONKEY_OK;
-}
-
-
-int MONKEY_ACTION_check_bug_redundancy()
-{
-    return MONKEY_OK;
-}

Modified: monkey/trunk/pathologist/src/pathologist/pathologist.c
===================================================================
--- monkey/trunk/pathologist/src/pathologist/pathologist.c      2013-02-11 
08:49:40 UTC (rev 26062)
+++ monkey/trunk/pathologist/src/pathologist/pathologist.c      2013-02-11 
09:49:40 UTC (rev 26063)
@@ -28,11 +28,9 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include "monkey_common.h"
-#include "pathologist_action.h"
+#include "action.h"
 #include "monkey_getopt_lib.h"
 
-#define MIN_ARG_REQUIRED 2
-
 static char *dumpFileName;
 static char *binaryName;
 static char *command;

Deleted: monkey/trunk/pathologist/src/pathologist/pathologist_action.h
===================================================================
--- monkey/trunk/pathologist/src/pathologist/pathologist_action.h       
2013-02-11 08:49:40 UTC (rev 26062)
+++ monkey/trunk/pathologist/src/pathologist/pathologist_action.h       
2013-02-11 09:49:40 UTC (rev 26063)
@@ -1,100 +0,0 @@
-/**
- * @file monkey/MONKEY_action.h
- * @brief Monkey API for actions taken by Monkey while debugging
- */
-
-#ifndef MONKEY_ACTION_H
-#define MONKEY_ACTION_H
-
-#include "gdbmi.h"
-#include "pathologist_xml_writer.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                          /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-
-/* Debug constants */
-#define DEBUG_MODE_GDB 0
-#define GDB_STATE_STOPPED 1
-#define GDB_STATE_EXIT_NORMALLY 2
-#define GDB_STATE_ERROR 3
-#define GDB_SAFETY_COUNT 2
-#define DEBUG_MODE_VALGRIND 4
-#define DEBUG_MODE_REPORT_READY 5
-#define NO_BUG_DETECTED -1
-#define BUG_NULL_POINTER 6
-#define BUG_ABORT 7
-#define BUG_ARITHMETIC 8
-#define BUG_BAD_MEM_ACCESS 9
-#define BUG_SIG_BUS 10
-#define GDB_MI_ASYNC_WAIT 5
-
-/**
- * Context for the Action API
- */
-struct MONKEY_ACTION_Context
-{
-  const char *binary_name;
-  char *binaryArgs;
-  const char *email_address;
-  const char *expression_database_path;
-  const char *gdb_binary_path;
-  const char *valgrind_binary_path;
-  const char *inspect_expression;
-  const char *inspect_function;
-  int debug_mode;
-  int bug_detected;
-  int has_null;
-  char *debug_report;
-  struct MONKEY_XML_Node *xml_report_node;
-
-  /* gdb debugging attributes */
-  int run_reverse;
-  int scope_depth;
-  mi_h *gdb_handle;
-  int gdb_connected;
-  const char *gdb_in_use;
-  mi_stop *gdb_stop_reason;
-  mi_frames *gdb_frames;
-  const char *gdb_null_variable;
-
-  /* Valgrind memcheck attributes */
-  char* valgrind_output_tmp_file_name;
-};
-
-
-int MONKEY_ACTION_report_file (struct MONKEY_ACTION_Context
-                                     *cntxt, const char *dumpFileName, int 
isXML);
-int MONKEY_ACTION_report_email (struct MONKEY_ACTION_Context
-                                      *cntxt, const char *dumpFileName);
-int MONKEY_ACTION_inspect_expression_database (struct
-                                                     MONKEY_ACTION_Context
-                                                     *cntxt);
-int MONKEY_ACTION_rerun_with_gdb (struct MONKEY_ACTION_Context
-                                        *cntxt);
-int MONKEY_ACTION_start_reverse_execution(struct MONKEY_ACTION_Context * 
cntxt);
-int MONKEY_ACTION_rerun_with_valgrind (struct
-                                             MONKEY_ACTION_Context
-                                             *cntxt);
-int MONKEY_ACTION_format_report (struct MONKEY_ACTION_Context
-                                       *cntxt);
-int
-MONKEY_ACTION_format_report_xml (struct MONKEY_ACTION_Context
-                                       *cntxt);
-int MONKEY_ACTION_delete_context(struct MONKEY_ACTION_Context *cntxt);
-
-int MONKEY_ACTION_check_bug_redundancy (void);
-
-
-#if 0                          /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif




reply via email to

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