2 This file is part of GNUnet.
3 (C) 2010, 2011 Christian Grothoff (and other contributing authors)
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file monkey/action_api.c
23 * @brief Monkey API for actions taken by Monkey while debugging
27 #include "gnunet_common.h"
28 #include "gnunet_monkey_action.h"
31 extern void sendMail (const char *messageContents, const char *emailAddress);
37 static void cb_console(const char *str, void *data)
39 printf("CONSOLE> %s\n",str);
43 /* Note that unlike what's documented in gdb docs it isn't usable. */
44 static void cb_target(const char *str, void *data)
46 printf("TARGET> %s\n",str);
50 static void cb_log(const char *str, void *data)
52 printf("LOG> %s\n",str);
56 static void cb_to(const char *str, void *data)
62 static void cb_from(const char *str, void *data)
64 printf("<< %s\n",str);
68 static void cb_async(mi_output *o, void *data)
75 static int wait_for_stop(mi_h *h, struct GNUNET_MONKEY_ACTION_Context *cntxt)
77 while (!mi_get_response(h))
79 /* The end of the async. */
80 cntxt->gdb_stop_reason=mi_res_stop(h);
81 if (cntxt->gdb_stop_reason)
83 if (cntxt->gdb_stop_reason->reason == sr_exited_normally)
84 return GDB_STATE_EXIT_NORMALLY;
86 cntxt->gdb_frames = gmi_stack_info_frame(h);
87 if (NULL == cntxt->gdb_frames)
90 return GDB_STATE_STOPPED;
92 return GDB_STATE_ERROR;
96 int GNUNET_MONKEY_ACTION_report_file(struct GNUNET_MONKEY_ACTION_Context* cntxt, const char* dumpFileName)
98 FILE* file = fopen(dumpFileName, "w");
99 GNUNET_assert(NULL != file);
100 fprintf(file,"%s", cntxt->debug_report);
106 int GNUNET_MONKEY_ACTION_report_email(struct GNUNET_MONKEY_ACTION_Context* cntxt)
108 if (cntxt->debug_mode == DEBUG_MODE_REPORT_READY)
109 sendMail(cntxt->debug_report, cntxt->email_address);
116 int GNUNET_MONKEY_ACTION_rerun_with_valgrind()
122 int GNUNET_MONKEY_ACTION_rerun_with_gdb(struct GNUNET_MONKEY_ACTION_Context* cntxt)
124 cntxt->debug_mode = DEBUG_MODE_GDB;
126 /* This is like a file-handle for fopen.
127 Here we have all the state of gdb "connection". */
128 mi_set_gdb_exe("/tmp/gdb/bin/gdb");
132 /* Connect to gdb child. */
133 h = mi_connect_local();
136 printf("Connect failed\n");
139 printf("Connected to gdb!\n");
141 /* Set all callbacks. */
142 mi_set_console_cb(h,cb_console,NULL);
143 mi_set_target_cb(h,cb_target,NULL);
144 mi_set_log_cb(h,cb_log,NULL);
145 mi_set_async_cb(h,cb_async,NULL);
146 mi_set_to_gdb_cb(h,cb_to,NULL);
147 mi_set_from_gdb_cb(h,cb_from,NULL);
149 /* Set the name of the child and the command line aguments. */
150 if (!gmi_set_exec(h, cntxt->binary_name, NULL))
152 printf("Error setting exec y args\n");
157 /* Tell gdb to attach the child to a terminal. */
158 if (!gmi_target_terminal(h, ttyname(STDIN_FILENO)))
160 printf("Error selecting target terminal\n");
165 /* Run the program. */
166 if (!gmi_exec_run(h))
168 printf("Error in run!\n");
172 /* Here we should be stopped when the program crashes */
173 ret = wait_for_stop(h, cntxt);
174 if (ret != GDB_STATE_ERROR)
181 int GNUNET_MONKEY_ACTION_format_report(struct GNUNET_MONKEY_ACTION_Context* cntxt)
183 switch (cntxt->debug_mode) {
185 GNUNET_asprintf(&(cntxt->debug_report),
186 "Bug detected in file:%s\nfunction:%s\nline:%d\nreason:%s\nreceived signal:%s\n%s\n",
187 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);
189 case DEBUG_MODE_VALGRIND:
195 cntxt->debug_mode = DEBUG_MODE_REPORT_READY;
200 int GNUNET_MONKEY_ACTION_check_bug_redundancy()