From a75c70e3dc0ade30cc805c05d44b0659311a7d2e Mon Sep 17 00:00:00 2001 From: "Safey A.Halim" Date: Fri, 4 Feb 2011 11:47:20 +0000 Subject: Monkey Action API. --- src/monkey/action_api.c | 187 +++++++++++++++++++++++++++++++++++++- src/monkey/gdbmi.h | 5 +- src/monkey/gnunet-monkey.c | 173 ++++++++++++++++++----------------- src/monkey/gnunet_monkey_action.h | 24 ++++- 4 files changed, 300 insertions(+), 89 deletions(-) (limited to 'src/monkey') diff --git a/src/monkey/action_api.c b/src/monkey/action_api.c index c1f39e788..6c7441ad7 100644 --- a/src/monkey/action_api.c +++ b/src/monkey/action_api.c @@ -26,16 +26,101 @@ #include "platform.h" #include "gnunet_common.h" #include "gnunet_monkey_action.h" +#include -int GNUNET_MONKEY_ACTION_report_file() +#define DEBUG_MODE_GDB 0 +#define DEBUG_MODE_VALGRIND 1 +#define DEBUG_MODE_REPORT_READY 2 + +extern void sendMail (const char *messageContents); + + +static int async_c=0; + + +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 wait_for_stop(mi_h *h) +{ + int res=1; + mi_stop *sr; + mi_frames *f; + + while (!mi_get_response(h)) + usleep(1000); + /* The end of the async. */ + sr=mi_res_stop(h); + if (sr) + { + f = gmi_stack_info_frame(h); + if (NULL == f) + printf("f is NULL!\n"); + if (NULL == f) + GNUNET_break(0); + + mi_free_stop(sr); + res = 0; + } + else + { + res=0; + } + return res; +} + + +int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName) { + FILE* file = fopen(dumpFileName, "w"); + GNUNET_assert(NULL != file); + fprintf(file,"%s", cntxt->debug_report); + fclose(file); return GNUNET_OK; } -int GNUNET_MONKEY_ACTION_report_email() +int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt) { + if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY) + sendMail(cntxt->debug_report); + return GNUNET_OK; } @@ -47,8 +132,104 @@ int GNUNET_MONKEY_ACTION_rerun_with_valgrind() } -int GNUNET_MONKEY_ACTION_rerun_with_gdb() +int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt) +{ + cntxt->debug_mode = DEBUG_MODE_GDB; + mi_aux_term *xterm_tty=NULL; + + /* This is like a file-handle for fopen. + Here we have all the state of gdb "connection". */ + mi_h *h; + + /* Connect to gdb child. */ + h = mi_connect_local(); + if (!h) + { + printf("Connect failed\n"); + return GNUNET_NO; + } + printf("Connected to gdb!\n"); + + /* Set all callbacks. */ + mi_set_console_cb(h,cb_console,NULL); + mi_set_target_cb(h,cb_target,NULL); + mi_set_log_cb(h,cb_log,NULL); + mi_set_async_cb(h,cb_async,NULL); + mi_set_to_gdb_cb(h,cb_to,NULL); + mi_set_from_gdb_cb(h,cb_from,NULL); + + /* Set the name of the child and the command line aguments. */ + if (!gmi_set_exec(h, cntxt->binary_name, NULL)) + { + printf("Error setting exec y args\n"); + mi_disconnect(h); + return GNUNET_NO; + } + + /* Tell gdb to attach the child to a terminal. */ + if (!gmi_target_terminal(h, ttyname(STDIN_FILENO))) + { + printf("Error selecting target terminal\n"); + mi_disconnect(h); + return GNUNET_NO; + } + + /* Run the program. */ + if (!gmi_exec_run(h)) + { + printf("Error in run!\n"); + mi_disconnect(h); + return GNUNET_NO; + } + /* Here we should be stopped when the program crashes */ + if (!wait_for_stop(h)) + { + mi_disconnect(h); + return GNUNET_NO; + } + + /* Continue execution. */ + if (!gmi_exec_continue(h)) + { + printf("Error in continue!\n"); + mi_disconnect(h); + return GNUNET_NO; + } + /* Here we should be terminated. */ + if (!wait_for_stop(h)) + { + mi_disconnect(h); + return GNUNET_NO; + } + + /* Exit from gdb. */ + gmi_gdb_exit(h); + /* Close the connection. */ + mi_disconnect(h); + /* Wait 5 seconds and close the auxiliar terminal. */ + printf("Waiting 5 seconds\n"); + sleep(5); + gmi_end_aux_term(xterm_tty); + + return GNUNET_OK; +} + + +int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt) { + switch (cntxt->debug_mode) { + case DEBUG_MODE_GDB: + GNUNET_asprintf(&cntxt->debug_report, + "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n", + cntxt->gdb_frames->file, cntxt->gdb_frames->func, cntxt->gdb_frames->line, mi_reason_enum_to_str(cntxt->gdb_stop_reason->reason), cntxt->gdb_stop_reason->signal_name, cntxt->gdb_stop_reason->signal_meaning); + break; + case DEBUG_MODE_VALGRIND: + break; + default: + break; + } + + cntxt->debug_mode = DEBUG_MODE_REPORT_READY; return GNUNET_OK; } diff --git a/src/monkey/gdbmi.h b/src/monkey/gdbmi.h index eac429411..c03d09b61 100644 --- a/src/monkey/gdbmi.h +++ b/src/monkey/gdbmi.h @@ -8,6 +8,9 @@ ***************************************************************************/ +#ifndef GDBMI_H +#define GDBMI_H + #ifdef __cplusplus extern "C" { @@ -710,4 +713,4 @@ int gmi_var_list_children(mi_h *h, mi_gvar *var); } #endif - +#endif diff --git a/src/monkey/gnunet-monkey.c b/src/monkey/gnunet-monkey.c index 61579817d..13bd71e84 100644 --- a/src/monkey/gnunet-monkey.c +++ b/src/monkey/gnunet-monkey.c @@ -17,6 +17,7 @@ #include "gnunet_common.h" #include "gnunet_getopt_lib.h" #include "gnunet_program_lib.h" +#include "gnunet_monkey_action.h" extern void sendMail (const char *messageContents); static const char* mode; @@ -128,88 +129,96 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - mi_aux_term *xterm_tty=NULL; - - /* This is like a file-handle for fopen. - Here we have all the state of gdb "connection". */ - mi_h *h; - - /* Connect to gdb child. */ - h=mi_connect_local(); - if (!h) - { - printf("Connect failed\n"); - ret = 1; - return; - } - printf("Connected to gdb!\n"); - - /* Set all callbacks. */ - mi_set_console_cb(h,cb_console,NULL); - mi_set_target_cb(h,cb_target,NULL); - mi_set_log_cb(h,cb_log,NULL); - mi_set_async_cb(h,cb_async,NULL); - mi_set_to_gdb_cb(h,cb_to,NULL); - mi_set_from_gdb_cb(h,cb_from,NULL); - - /* Set the name of the child and the command line aguments. */ - if (!gmi_set_exec(h, binaryName, NULL)) - { - printf("Error setting exec y args\n"); - mi_disconnect(h); - ret = 1; - return; - } - - /* Tell gdb to attach the child to a terminal. */ - if (!gmi_target_terminal(h, ttyname(STDIN_FILENO))) - { - printf("Error selecting target terminal\n"); - mi_disconnect(h); - ret = 1; - return; - } - - /* Run the program. */ - if (!gmi_exec_run(h)) - { - printf("Error in run!\n"); - mi_disconnect(h); - ret = 1; - return; - } - /* Here we should be stopped when the program crashes */ - if (!wait_for_stop(h)) - { - mi_disconnect(h); - ret = 1; - return; - } - - /* Continue execution. */ - if (!gmi_exec_continue(h)) - { - printf("Error in continue!\n"); - mi_disconnect(h); - ret = 1; - return; - } - /* Here we should be terminated. */ - if (!wait_for_stop(h)) - { - mi_disconnect(h); - ret = 1; - return; - } - - /* Exit from gdb. */ - gmi_gdb_exit(h); - /* Close the connection. */ - mi_disconnect(h); - /* Wait 5 seconds and close the auxiliar terminal. */ - printf("Waiting 5 seconds\n"); - sleep(5); - gmi_end_aux_term(xterm_tty); + struct GNUNET_MONKEY_ACTION_Context* cntxt = + GNUNET_malloc(sizeof(struct GNUNET_MONKEY_ACTION_Context)); + cntxt->binary_name = binaryName; + if (GNUNET_OK == GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt)) { + GNUNET_MONKEY_ACTION_format_report(cntxt); + GNUNET_MONKEY_ACTION_report_file(cntxt, dumpFileName); + } + +// mi_aux_term *xterm_tty=NULL; +// +// /* This is like a file-handle for fopen. +// Here we have all the state of gdb "connection". */ +// mi_h *h; +// +// /* Connect to gdb child. */ +// h=mi_connect_local(); +// if (!h) +// { +// printf("Connect failed\n"); +// ret = 1; +// return; +// } +// printf("Connected to gdb!\n"); +// +// /* Set all callbacks. */ +// mi_set_console_cb(h,cb_console,NULL); +// mi_set_target_cb(h,cb_target,NULL); +// mi_set_log_cb(h,cb_log,NULL); +// mi_set_async_cb(h,cb_async,NULL); +// mi_set_to_gdb_cb(h,cb_to,NULL); +// mi_set_from_gdb_cb(h,cb_from,NULL); +// +// /* Set the name of the child and the command line aguments. */ +// if (!gmi_set_exec(h, binaryName, NULL)) +// { +// printf("Error setting exec y args\n"); +// mi_disconnect(h); +// ret = 1; +// return; +// } +// +// /* Tell gdb to attach the child to a terminal. */ +// if (!gmi_target_terminal(h, ttyname(STDIN_FILENO))) +// { +// printf("Error selecting target terminal\n"); +// mi_disconnect(h); +// ret = 1; +// return; +// } +// +// /* Run the program. */ +// if (!gmi_exec_run(h)) +// { +// printf("Error in run!\n"); +// mi_disconnect(h); +// ret = 1; +// return; +// } +// /* Here we should be stopped when the program crashes */ +// if (!wait_for_stop(h)) +// { +// mi_disconnect(h); +// ret = 1; +// return; +// } +// +// /* Continue execution. */ +// if (!gmi_exec_continue(h)) +// { +// printf("Error in continue!\n"); +// mi_disconnect(h); +// ret = 1; +// return; +// } +// /* Here we should be terminated. */ +// if (!wait_for_stop(h)) +// { +// mi_disconnect(h); +// ret = 1; +// return; +// } +// +// /* Exit from gdb. */ +// gmi_gdb_exit(h); +// /* Close the connection. */ +// mi_disconnect(h); +// /* Wait 5 seconds and close the auxiliar terminal. */ +// printf("Waiting 5 seconds\n"); +// sleep(5); +// gmi_end_aux_term(xterm_tty); } diff --git a/src/monkey/gnunet_monkey_action.h b/src/monkey/gnunet_monkey_action.h index da8f85396..8430c9f88 100644 --- a/src/monkey/gnunet_monkey_action.h +++ b/src/monkey/gnunet_monkey_action.h @@ -26,6 +26,8 @@ #ifndef GNUNET_MONKEY_ACTION_H #define GNUNET_MONKEY_ACTION_H +#include "gdbmi.h" + #ifdef __cplusplus extern "C" { @@ -34,10 +36,26 @@ extern "C" #endif #endif -int GNUNET_MONKEY_ACTION_report_file(); -int GNUNET_MONKEY_ACTION_report_email(); + +/** + * Context for the Action API + */ +struct GNUNET_MONKEY_ACTION_Context +{ + const char* binary_name; + int debug_mode; + char* debug_report; + + /* gdb debugging attributes */ + mi_stop* gdb_stop_reason; + mi_frames* gdb_frames; +}; + +int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName); +int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt); int GNUNET_MONKEY_ACTION_rerun_with_valgrind(); -int GNUNET_MONKEY_ACTION_rerun_with_gdb(); +int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt); +int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt); int GNUNET_MONKEY_ACTION_check_bug_redundancy(); -- cgit v1.2.3