From: Safey A.Halim Date: Mon, 21 Mar 2011 07:58:04 +0000 (+0000) Subject: Action API fixed X-Git-Tag: initial-import-from-subversion-38251~18950 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=ab8d56ea330a41dfb0a7b82e91a097a41f56254d;p=oweals%2Fgnunet.git Action API fixed --- diff --git a/src/monkey/action_api.c b/src/monkey/action_api.c index 6c7441ad7..ff5c59bf9 100644 --- a/src/monkey/action_api.c +++ b/src/monkey/action_api.c @@ -28,12 +28,7 @@ #include "gnunet_monkey_action.h" #include - -#define DEBUG_MODE_GDB 0 -#define DEBUG_MODE_VALGRIND 1 -#define DEBUG_MODE_REPORT_READY 2 - -extern void sendMail (const char *messageContents); +extern void sendMail (const char *messageContents, const char *emailAddress); static int async_c=0; @@ -77,32 +72,24 @@ static void cb_async(mi_output *o, void *data) } -static int wait_for_stop(mi_h *h) +static int wait_for_stop(mi_h *h, struct GNUNET_MONKEY_ACTION_Context *cntxt) { - 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) + cntxt->gdb_stop_reason=mi_res_stop(h); + if (cntxt->gdb_stop_reason) { - f = gmi_stack_info_frame(h); - if (NULL == f) - printf("f is NULL!\n"); - if (NULL == f) + if (cntxt->gdb_stop_reason->reason == sr_exited_normally) + return GDB_STATE_EXIT_NORMALLY; + + cntxt->gdb_frames = gmi_stack_info_frame(h); + if (NULL == cntxt->gdb_frames) GNUNET_break(0); - mi_free_stop(sr); - res = 0; - } - else - { - res=0; + return GDB_STATE_STOPPED; } - return res; + return GDB_STATE_ERROR; } @@ -119,7 +106,7 @@ int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt) { if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY) - sendMail(cntxt->debug_report); + sendMail(cntxt->debug_report, cntxt->email_address); return GNUNET_OK; } @@ -135,11 +122,12 @@ int GNUNET_MONKEY_ACTION_rerun_with_valgrind() 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; + mi_set_gdb_exe("/tmp/gdb/bin/gdb"); + mi_h *h; + int ret; /* Connect to gdb child. */ h = mi_connect_local(); @@ -182,36 +170,11 @@ int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cnt 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)) - { + ret = wait_for_stop(h, cntxt); + if (ret != GDB_STATE_ERROR) 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; + return ret; } @@ -219,7 +182,7 @@ int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntx { switch (cntxt->debug_mode) { case DEBUG_MODE_GDB: - GNUNET_asprintf(&cntxt->debug_report, + 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; diff --git a/src/monkey/gnunet-monkey.c b/src/monkey/gnunet-monkey.c index 13bd71e84..c8ac4369c 100644 --- a/src/monkey/gnunet-monkey.c +++ b/src/monkey/gnunet-monkey.c @@ -1,122 +1,43 @@ -/**[txh]******************************************************************** +/* + This file is part of GNUnet. + (C) 2010, 2011 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ - Copyright (c) 2004 by Salvador E. Tropea. - Covered by the GPL license. - - Comment: - X11 example/test of the libmigdb. - Run it from an X11 terminal (xterm, Eterm, etc.). - -***************************************************************************/ +/** + * @file monkey/gnunet-monkey.c + * @brief Monkey: gnunet automated debugging tool + */ #include -#include //usleep -#include -#include "gdbmi.h" #include "platform.h" #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; static const char* dumpFileName; static const char* binaryName; +static const char* emailAddress; static int ret = 0; -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. */ -void cb_target(const char *str, void *data) -{ - printf("TARGET> %s\n",str); -} - -void cb_log(const char *str, void *data) -{ - printf("LOG> %s\n",str); -} - -void cb_to(const char *str, void *data) -{ - printf(">> %s",str); -} - -void cb_from(const char *str, void *data) -{ - printf("<< %s\n",str); -} - -static int async_c=0; - -void cb_async(mi_output *o, void *data) -{ - printf("ASYNC\n"); - async_c++; -} - - -static void dumpText(const char* message) -{ - FILE* file = fopen(dumpFileName, "w"); - GNUNET_assert(NULL != file); - fprintf(file,"%s", message); - fclose(file); -} - - -void send_bug_mail(mi_stop* sr, mi_frames* f) -{ - char *message; - GNUNET_asprintf(&message, - "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n", - f->file, f->func, f->line, mi_reason_enum_to_str(sr->reason), sr->signal_name, sr->signal_meaning); - if (strcasecmp(mode, "mail") == 0) - sendMail(message); - else - dumpText(message); - - GNUNET_free (message); -} - - -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 (f != NULL) - send_bug_mail(sr, f); - else - GNUNET_break (0); - mi_free_stop(sr); - res = 0; - } - else - { - printf("Error while waiting\n"); - printf("mi_error: %d\nmi_error_from_gdb: %s\n",mi_error,mi_error_from_gdb); - res=0; - } - return res; -} - - - /** - * Main function that will be run by the scheduler. + * Main function that will launch the action api. * * @param cls closure * @param args remaining command-line arguments @@ -129,113 +50,69 @@ run (void *cls, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *c) { - 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); + int result; + struct GNUNET_MONKEY_ACTION_Context* cntxt; + + if (strcasecmp(mode, "email") == 0) { + if (NULL == emailAddress) { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Working in email mode requires an email address!\n"); + ret = 1; + return; + } + } else if (strcasecmp(mode, "text") == 0) { + if (NULL == dumpFileName) { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Working in text mode requires a path for the dump file!\n"); + ret = 1; + return; + } } -// 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); + cntxt = GNUNET_malloc(sizeof(struct GNUNET_MONKEY_ACTION_Context)); + cntxt->binary_name = binaryName; + result = GNUNET_MONKEY_ACTION_rerun_with_gdb(cntxt); + switch (result) { + case GDB_STATE_ERROR: + break; + case GDB_STATE_EXIT_NORMALLY: + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Debug with gdb, program exited normally!\n"); + /*FIXME: Valgrind should be launched here */ + break; + case GDB_STATE_STOPPED: + /*FIXME: Expression Database should be inspected here (before writing the report) */ + if(GNUNET_OK != GNUNET_MONKEY_ACTION_format_report(cntxt)){ + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in generating debug report!\n"); + ret = 1; + } + if (strcasecmp(mode, "email") == 0) { + if (GNUNET_OK != GNUNET_MONKEY_ACTION_report_email(cntxt)) { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error sending email!\n"); + ret = 1; + } + } else { + /* text mode */ + if (GNUNET_OK != GNUNET_MONKEY_ACTION_report_file(cntxt, dumpFileName)) { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Error in saving debug file!\n"); + ret = 1; + } + } + break; + default: + break; + } } int main(int argc, char *argv[]) { - /* - * FIXME: - * Command should accept email address to which monkey sends the debugging report. - * The email address can also be read from the configuration file. - */ static const struct GNUNET_GETOPT_CommandLineOption options[] = { {'m', "mode", NULL, gettext_noop ("monkey's mode of operation: options are \"text\" or \"email\""), GNUNET_YES, &GNUNET_GETOPT_set_string, &mode}, {'b', "binary", NULL, gettext_noop ("binary for program to debug with monkey"), GNUNET_YES, &GNUNET_GETOPT_set_string, &binaryName}, - {'o', "output", NULL, gettext_noop ("path to file to dump monkey's output in case of working in text mode"), + {'o', "output", NULL, gettext_noop ("path to file to dump monkey's output in case of text mode"), GNUNET_YES, &GNUNET_GETOPT_set_string, &dumpFileName}, + {'a', "address", NULL, gettext_noop ("address to send email to in case of email mode"), + GNUNET_YES, &GNUNET_GETOPT_set_string, &emailAddress}, GNUNET_GETOPT_OPTION_END }; diff --git a/src/monkey/gnunet_monkey_action.h b/src/monkey/gnunet_monkey_action.h index 8430c9f88..93f2dea4e 100644 --- a/src/monkey/gnunet_monkey_action.h +++ b/src/monkey/gnunet_monkey_action.h @@ -37,12 +37,22 @@ extern "C" #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 DEBUG_MODE_VALGRIND 4 +#define DEBUG_MODE_REPORT_READY 5 + + /** * Context for the Action API */ struct GNUNET_MONKEY_ACTION_Context { const char* binary_name; + const char* email_address; int debug_mode; char* debug_report; diff --git a/src/monkey/mail_sender.c b/src/monkey/mail_sender.c index 6279ad984..122a4d0ab 100644 --- a/src/monkey/mail_sender.c +++ b/src/monkey/mail_sender.c @@ -144,7 +144,7 @@ print_recipient_status (smtp_recipient_t recipient, } -void sendMail(const char *messageContents) +void sendMail(const char *messageContents, const char *emailAddress) { smtp_session_t session; smtp_message_t message; @@ -154,7 +154,7 @@ void sendMail(const char *messageContents) char *host = "localhost:25"; char *from = "gnunet-monkey"; char *subject = "e-mail from Libesmtp!"; - const char *recipient_address = "safey.allah@gmail.com"; + const char *recipient_address = emailAddress; char tempFileName[1000]; int tempFd; FILE *fp;