libanjuta: Added "opened" signal to IAnjutaFile interface
[anjuta.git] / plugins / gdb / debugger.c
blob898a6db9454fd98fb1f6efc2308180ed906b86f0
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * debugger.c Copyright (C) 2000 Kh. Naba Kumar Singh
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc., 59
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 /*#define DEBUG*/
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <sys/wait.h>
33 #include <errno.h>
34 #include <assert.h>
35 #include <fcntl.h>
37 #include <glib.h>
38 #include <glib/gi18n.h>
40 #include <libanjuta/anjuta-launcher.h>
41 #include <libanjuta/anjuta-debug.h>
42 #include <libanjuta/anjuta-marshal.h>
43 #include <libanjuta/anjuta-utils.h>
44 #include <libanjuta/interfaces/ianjuta-debugger-breakpoint.h>
45 #include <libanjuta/interfaces/ianjuta-debugger-register.h>
46 #include <libanjuta/interfaces/ianjuta-debugger-memory.h>
47 #include <libanjuta/interfaces/ianjuta-debugger-instruction.h>
48 #include <libanjuta/interfaces/ianjuta-debugger-variable.h>
49 #include <libanjuta/interfaces/ianjuta-environment.h>
51 #include "debugger.h"
52 #include "utilities.h"
54 #define ANJUTA_LOG_ENV "ANJUTA_LOG"
55 #define DEBUGGER_LOG_LEVEL 1
57 #define GDB_PROMPT "(gdb)"
58 #define FILE_BUFFER_SIZE 1024
59 #define GDB_PATH "gdb"
60 #define MAX_CHILDREN 25 /* Limit the number of variable children
61 * returned by debugger */
62 #define SUMMARY_MAX_LENGTH 90 /* Should be smaller than 4K to be displayed
63 * in GtkCellRendererCell */
65 enum {
66 DEBUGGER_NONE,
67 DEBUGGER_EXIT,
68 DEBUGGER_RERUN_PROGRAM
71 enum
73 PROGRAM_LOADED_SIGNAL,
74 PROGRAM_RUNNING_SIGNAL,
75 PROGRAM_EXITED_SIGNAL,
76 PROGRAM_STOPPED_SIGNAL,
77 RESULTS_ARRIVED_SIGNAL,
78 LOCATION_CHANGED_SIGNAL,
79 BREAKPOINT_CHANGED_SIGNAL,
80 VARIABLE_CHANGED_SIGNAL,
81 LAST_SIGNAL
84 struct _DebuggerPriv
86 GtkWindow *parent_win;
88 IAnjutaDebuggerOutputCallback output_callback;
89 gpointer output_user_data;
91 GList *search_dirs;
93 gboolean prog_is_running;
94 gboolean prog_is_attached;
95 gboolean prog_is_loaded;
96 gboolean prog_is_remote; /* Whether we are debugging a remote target */
97 gboolean debugger_is_started;
98 guint debugger_is_busy;
99 gint post_execution_flag;
101 AnjutaLauncher *launcher;
102 GString *stdo_line;
103 GString *stdo_acc;
104 GString *stde_line;
106 GList *cli_lines;
108 /* State */
109 gboolean solib_event;
110 gboolean stopping;
111 gboolean exiting;
112 gboolean starting;
113 gboolean terminating;
114 gboolean loading;
115 gchar *remote_server;
117 /* GDB command queue */
118 GList *cmd_queqe;
119 DebuggerCommand current_cmd;
120 gboolean skip_next_prompt;
121 gboolean command_output_sent;
123 pid_t inferior_pid;
124 gint current_thread;
125 guint current_frame;
127 GObject* instance;
129 IAnjutaMessageView *log;
130 gboolean gdb_log;
132 /* Environment */
133 IAnjutaEnvironment *environment;
135 /* GDB Features */
136 gboolean has_pending_breakpoints;
137 gboolean has_python_support;
138 gboolean has_thread_info;
139 gboolean has_frozen_varobjs;
141 /* Pretty printers command */
142 gchar *load_pretty_printer;
145 static gpointer parent_class;
147 static void debugger_queue_clear (Debugger *debugger);
148 static void debugger_queue_execute_command (Debugger *debugger);
150 static void gdb_stdout_line_arrived (Debugger *debugger, const gchar * line);
151 static void gdb_stderr_line_arrived (Debugger *debugger, const gchar * line);
152 static void debugger_stdo_flush (Debugger *debugger);
153 static void debugger_stde_flush (Debugger *debugger);
154 static void on_gdb_output_arrived (AnjutaLauncher *launcher,
155 AnjutaLauncherOutputType output_type,
156 const gchar *chars, gpointer data);
157 static void on_gdb_terminated (AnjutaLauncher *launcher,
158 gint child_pid, gint status,
159 gulong t, gpointer data);
161 static void debugger_class_init (DebuggerClass *klass);
162 static void debugger_instance_init (Debugger *debugger);
164 typedef struct _GdbGListPacket
166 GList* list;
167 gint tag;
168 } GdbGListPacket;
170 /* Useful functions
171 *---------------------------------------------------------------------------*/
173 static gchar * gdb_quote (const gchar *unquoted_string)
175 const char *p;
176 g_return_val_if_fail (unquoted_string != NULL, NULL);
179 p = strpbrk (unquoted_string, "\"\\");
180 if (p == NULL)
182 /* No need to quote anything */
183 return g_strdup (unquoted_string);
185 else
187 GString *dest;
189 dest = g_string_new_len (unquoted_string, p - unquoted_string);
190 for (;;)
192 g_string_append_c (dest, '\\');
193 unquoted_string = p;
194 p = strpbrk (unquoted_string + 1, "\"\\");
195 if (p == NULL)
197 g_string_append (dest, unquoted_string);
198 break;
200 else
202 g_string_append_len (dest, unquoted_string, p - unquoted_string);
205 return g_string_free (dest, FALSE);
209 typedef struct _GdbMessageCode GdbMessageCode;
211 struct _GdbMessageCode
213 const gchar *msg;
214 guint code;
217 const static GdbMessageCode GdbErrorMessage[] =
218 {{"mi_cmd_var_create: unable to create variable object",
219 IANJUTA_DEBUGGER_UNABLE_TO_CREATE_VARIABLE},
220 {"Cannot access memory at address ",
221 IANJUTA_DEBUGGER_UNABLE_TO_ACCESS_MEMORY},
222 {"No source file named ",
223 IANJUTA_DEBUGGER_UNABLE_TO_OPEN_FILE},
224 {"No executable file specified.",
225 IANJUTA_DEBUGGER_PROGRAM_NOT_FOUND},
226 {"*: Connection refused.",
227 IANJUTA_DEBUGGER_UNABLE_TO_CONNECT},
228 {NULL, 0}};
230 static guint
231 gdb_match_error(const gchar *message)
233 const GdbMessageCode* msg;
235 for (msg = GdbErrorMessage; msg->msg != NULL; msg++)
237 if (g_pattern_match_simple(msg->msg, message))
239 return msg->code;
243 return IANJUTA_DEBUGGER_UNKNOWN_ERROR;
246 static void
247 debugger_message_view_append (Debugger *debugger, IAnjutaMessageViewType type, const char *message)
249 guint len = strlen(message);
250 gchar buf[SUMMARY_MAX_LENGTH];
251 const gchar* summary = message;
252 const gchar* detail = "";
255 if (len > SUMMARY_MAX_LENGTH)
258 memcpy(buf, message, SUMMARY_MAX_LENGTH - 4);
259 memcpy(buf + SUMMARY_MAX_LENGTH - 4, "...", 4);
260 summary = buf;
261 detail = message;
264 ianjuta_message_view_append (debugger->priv->log, type, summary, detail, NULL);
267 static void
268 debugger_initialize (Debugger *debugger)
270 const gchar* anjuta_log;
272 DEBUG_PRINT ("%s", "In function: debugger_init()");
274 debugger->priv = g_new0 (DebuggerPriv, 1);
276 debugger->priv->output_callback = NULL;
277 debugger->priv->parent_win = NULL;
278 debugger->priv->search_dirs = NULL;
279 debugger->priv->launcher = anjuta_launcher_new ();
281 debugger->priv->debugger_is_started = FALSE;
282 debugger->priv->prog_is_running = FALSE;
283 debugger->priv->debugger_is_busy = 0;
284 debugger->priv->starting = FALSE;
285 debugger->priv->terminating = FALSE;
286 debugger->priv->skip_next_prompt = FALSE;
287 debugger->priv->command_output_sent = FALSE;
288 debugger->priv->prog_is_remote = FALSE;
289 debugger->priv->remote_server = NULL;
291 debugger->priv->current_cmd.cmd = NULL;
292 debugger->priv->current_cmd.parser = NULL;
294 debugger->priv->cmd_queqe = NULL;
295 debugger->priv->cli_lines = NULL;
296 debugger->priv->solib_event = FALSE;
298 debugger->priv->stdo_line = g_string_sized_new (FILE_BUFFER_SIZE);
299 g_string_assign (debugger->priv->stdo_line, "");
300 debugger->priv->stdo_acc = g_string_new ("");
302 debugger->priv->stde_line = g_string_sized_new (FILE_BUFFER_SIZE);
303 g_string_assign (debugger->priv->stde_line, "");
305 debugger->priv->post_execution_flag = DEBUGGER_NONE;
307 anjuta_log = g_getenv (ANJUTA_LOG_ENV);
308 debugger->priv->gdb_log = anjuta_log && (atoi(anjuta_log) > DEBUGGER_LOG_LEVEL);
310 debugger->priv->environment = NULL;
312 debugger->priv->load_pretty_printer = NULL;
315 static void
316 debugger_instance_init (Debugger *debugger)
318 debugger_initialize (debugger);
321 Debugger*
322 debugger_new (GtkWindow *parent_win, GObject* instance)
324 Debugger *debugger;
326 debugger = g_object_new (DEBUGGER_TYPE, NULL);
327 debugger->priv->parent_win = parent_win;
328 debugger->priv->instance = instance;
330 return debugger;
333 void
334 debugger_free (Debugger *debugger)
336 g_return_if_fail (IS_DEBUGGER (debugger));
338 if (debugger->priv->environment)
340 g_object_unref (debugger->priv->environment);
341 debugger->priv->environment = NULL;
344 g_object_unref (debugger);
347 gboolean
348 debugger_is_ready (Debugger *debugger)
350 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
351 return !debugger->priv->debugger_is_busy;
354 gboolean
355 debugger_program_is_running (Debugger *debugger)
357 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
358 return debugger->priv->prog_is_running;
361 gboolean
362 debugger_program_is_attached (Debugger *debugger)
364 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
365 return debugger->priv->prog_is_attached;
368 gboolean
369 debugger_program_is_loaded (Debugger *debugger)
371 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
372 return debugger->priv->prog_is_loaded;
375 static void
376 debugger_log_command (Debugger *debugger, const gchar *command)
378 gchar* str;
379 gsize len;
381 if (debugger->priv->log == NULL) return;
383 if (*command == '-')
385 str = g_strdup (command);
386 len = strlen (command);
388 /* Remove trailing carriage return */
389 if (str[len - 1] == '\n') str[len - 1] = '\0';
391 /* Log only MI command as other are echo */
392 #ifdef DEBUG
393 DEBUG_PRINT ("GDB:> %s", str);
394 #else
395 if (debugger->priv->gdb_log) g_message ("GDB:> %s", str);
396 #endif
397 debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, str);
398 g_free (str);
402 static void
403 debugger_log_output (Debugger *debugger, const gchar *line)
405 gchar* str;
406 const gchar* start;
407 IAnjutaMessageViewType type;
408 gsize len;
410 if (debugger->priv->log == NULL) return;
412 type = IANJUTA_MESSAGE_VIEW_TYPE_NORMAL;
413 switch (*line)
415 case '~':
416 type = IANJUTA_MESSAGE_VIEW_TYPE_INFO;
417 /* Go through */
418 case '&':
419 len = strlen(line);
420 start = line + 1;
422 /* Remove double quote if necessary */
423 if ((line[1] == '\"') && (line[len - 1] == '\"')) start++;
424 str = g_strcompress (line + 2);
425 len = strlen (str);
426 if (start == line + 2)
428 str[len - 1] = '\0';
429 len--;
432 /* Remove trailing carriage return */
433 if (str[len - 1] == '\n') str[len - 1] = '\0';
435 debugger_message_view_append (debugger, type, str);
436 g_free (str);
437 break;
438 case '^':
439 if (strncmp(line + 1, "error", 5) == 0)
441 debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_ERROR, line + 1);
443 else
445 debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_WARNING, line + 1);
447 break;
448 case '@':
449 debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, line + 1);
450 break;
451 default:
452 debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_NORMAL, line);
453 break;
457 /* Emit ready signal (= command completed) for debuger manager and change the
458 * debugger state.
460 static void
461 debugger_emit_ready (Debugger *debugger)
463 if (!debugger->priv->debugger_is_busy)
465 if (debugger->priv->loading)
467 debugger->priv->starting = FALSE;
468 debugger->priv->loading = FALSE;
469 debugger->priv->exiting = FALSE;
470 debugger->priv->stopping = FALSE;
471 debugger->priv->solib_event = FALSE;
472 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_LOADED);
474 else if (debugger->priv->starting)
476 debugger->priv->starting = FALSE;
477 debugger->priv->loading = FALSE;
478 debugger->priv->exiting = FALSE;
479 debugger->priv->stopping = FALSE;
480 debugger->priv->solib_event = FALSE;
481 if (debugger->priv->prog_is_attached)
483 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_STOPPED);
485 else
487 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_STARTED);
490 else if (debugger->priv->exiting)
492 debugger->priv->exiting = FALSE;
493 debugger->priv->stopping = FALSE;
494 debugger->priv->solib_event = FALSE;
495 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_LOADED);
497 else if (debugger->priv->solib_event)
499 debugger->priv->exiting = FALSE;
500 debugger->priv->stopping = FALSE;
501 debugger->priv->solib_event = FALSE;
502 g_signal_emit_by_name (debugger->priv->instance, "sharedlib-event");
504 else if (debugger->priv->stopping)
506 debugger->priv->exiting = FALSE;
507 debugger->priv->stopping = FALSE;
508 debugger->priv->solib_event = FALSE;
509 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_STOPPED);
511 else
513 if (debugger->priv->prog_is_running || debugger->priv->prog_is_attached)
515 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_STOPPED);
517 else if (debugger->priv->prog_is_loaded)
519 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_LOADED);
521 else
523 g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_STARTED);
529 IAnjutaDebuggerState
530 debugger_get_state (Debugger *debugger)
532 if (debugger->priv->debugger_is_busy)
534 return IANJUTA_DEBUGGER_BUSY;
536 else
538 if (debugger->priv->prog_is_running || debugger->priv->prog_is_attached)
540 return IANJUTA_DEBUGGER_PROGRAM_STOPPED;
542 else if (debugger->priv->prog_is_loaded)
544 return IANJUTA_DEBUGGER_PROGRAM_LOADED;
546 else if (debugger->priv->debugger_is_started)
548 return IANJUTA_DEBUGGER_STARTED;
550 else
552 return IANJUTA_DEBUGGER_STOPPED;
557 static void
558 debugger_clear_buffers (Debugger *debugger)
560 DEBUG_PRINT ("%s", "In function: debugger_clear_buffers()");
562 /* Clear the output line buffer */
563 g_string_assign (debugger->priv->stdo_line, "");
564 if (!(debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT))
565 g_string_assign (debugger->priv->stdo_acc, "");
567 /* Clear the error line buffer */
568 g_string_assign (debugger->priv->stde_line, "");
570 /* Clear CLI output lines */
571 g_list_foreach (debugger->priv->cli_lines, (GFunc)g_free, NULL);
572 g_list_free (debugger->priv->cli_lines);
573 debugger->priv->cli_lines = NULL;
576 static DebuggerCommand *
577 debugger_queue_get_next_command (Debugger *debugger)
579 DebuggerCommand *dc;
581 DEBUG_PRINT ("%s", "In function: debugger_get_next_command()");
583 if (debugger->priv->cmd_queqe)
585 dc = g_list_nth_data (debugger->priv->cmd_queqe, 0);
586 debugger->priv->cmd_queqe = g_list_remove (debugger->priv->cmd_queqe, dc);
588 else
589 dc = NULL;
590 return dc;
593 static gboolean
594 debugger_queue_set_next_command (Debugger *debugger)
596 DebuggerCommand *dc;
598 DEBUG_PRINT ("%s", "In function: debugger_set_next_command()");
600 dc = debugger_queue_get_next_command (debugger);
601 if (!dc)
603 debugger->priv->current_cmd.cmd = NULL;
604 debugger->priv->current_cmd.parser = NULL;
605 debugger->priv->current_cmd.callback = NULL;
606 debugger->priv->current_cmd.user_data = NULL;
607 debugger->priv->current_cmd.flags = 0;
609 return FALSE;
611 g_free (debugger->priv->current_cmd.cmd);
612 debugger->priv->current_cmd.cmd = dc->cmd;
613 debugger->priv->current_cmd.parser = dc->parser;
614 debugger->priv->current_cmd.callback = dc->callback;
615 debugger->priv->current_cmd.user_data = dc->user_data;
616 debugger->priv->current_cmd.flags = dc->flags;
617 g_free (dc);
619 return TRUE;
622 static void
623 debugger_queue_command (Debugger *debugger, const gchar *cmd,
624 gint flags,
625 DebuggerParserFunc parser,
626 IAnjutaDebuggerCallback callback, gpointer user_data)
628 DebuggerCommand *dc;
631 DEBUG_PRINT ("In function: debugger_queue_command (%s)", cmd);
633 dc = g_malloc (sizeof (DebuggerCommand));
634 if (dc)
636 dc->cmd = g_strdup(cmd);
637 dc->parser = parser;
638 dc->callback = callback;
639 dc->user_data = user_data;
640 dc->flags = flags;
642 if (flags & DEBUGGER_COMMAND_PREPEND)
644 debugger->priv->cmd_queqe = g_list_prepend (debugger->priv->cmd_queqe, dc);
646 else
648 debugger->priv->cmd_queqe = g_list_append (debugger->priv->cmd_queqe, dc);
650 debugger_queue_execute_command (debugger);
653 static void
654 debugger_queue_clear (Debugger *debugger)
656 GList *node;
658 DEBUG_PRINT ("%s", "In function: debugger_queue_clear()");
660 node = debugger->priv->cmd_queqe;
661 while (node)
663 g_free (((DebuggerCommand *)node->data)->cmd);
664 g_free (node->data);
665 node = g_list_next (node);
667 g_list_free (debugger->priv->cmd_queqe);
668 debugger->priv->cmd_queqe = NULL;
669 g_free (debugger->priv->current_cmd.cmd);
670 debugger->priv->current_cmd.cmd = NULL;
671 debugger->priv->current_cmd.parser = NULL;
672 debugger->priv->current_cmd.callback = NULL;
673 debugger->priv->current_cmd.user_data = NULL;
674 debugger->priv->current_cmd.flags = 0;
675 debugger_clear_buffers (debugger);
678 static void
679 debugger_execute_command (Debugger *debugger, const gchar *command)
681 gchar *cmd;
683 DEBUG_PRINT ("In function: debugger_execute_command(%s) %d\n",command, debugger->priv->debugger_is_busy);
684 debugger->priv->debugger_is_busy++;
685 debugger->priv->command_output_sent = FALSE;
686 cmd = g_strconcat (command, "\n", NULL);
687 debugger_log_command (debugger, cmd);
688 anjuta_launcher_send_stdin (debugger->priv->launcher, cmd);
689 g_free (cmd);
692 static void
693 debugger_queue_execute_command (Debugger *debugger)
695 DEBUG_PRINT ("%s", "In function: debugger_queue_execute_command()");
697 if (!debugger->priv->debugger_is_busy &&
698 g_list_length (debugger->priv->cmd_queqe) >= 1)
700 debugger_clear_buffers (debugger);
701 if (debugger_queue_set_next_command (debugger))
702 debugger_execute_command (debugger, debugger->priv->current_cmd.cmd);
706 static void
707 debugger_load_executable_finish (Debugger *debugger, const GDBMIValue *mi_results,
708 const GList *cli_results, GError *error)
710 DEBUG_PRINT ("%s", "Program loaded");
711 debugger->priv->prog_is_loaded = TRUE;
713 g_signal_emit_by_name (debugger->priv->instance, "program-loaded");
716 void
717 debugger_load_executable (Debugger *debugger, const gchar *prog)
719 gchar *command, *dir, *msg;
721 g_return_if_fail (IS_DEBUGGER (debugger));
722 g_return_if_fail (prog != NULL);
724 DEBUG_PRINT ("In function: debugger_load_executable(%s)", prog);
726 if (debugger->priv->output_callback)
728 /* The %s argument is a program name, anjuta by example */
729 msg = g_strdup_printf (_("Loading Executable: %s\n"), prog);
730 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT, msg,
731 debugger->priv->output_user_data);
732 g_free (msg);
735 command = g_strconcat ("-file-exec-and-symbols ", prog, NULL);
736 dir = g_path_get_dirname (prog);
737 /* TODO
738 anjuta_set_execution_dir(dir);
740 g_free (dir);
741 debugger_queue_command (debugger, command, 0, debugger_load_executable_finish, NULL, NULL);
742 g_free (command);
743 debugger->priv->starting = TRUE;
744 debugger->priv->terminating = FALSE;
747 void
748 debugger_load_core (Debugger *debugger, const gchar *core)
750 gchar *command, *dir, *msg;
752 g_return_if_fail (IS_DEBUGGER (debugger));
753 g_return_if_fail (core != NULL);
755 DEBUG_PRINT ("In function: debugger_load_core(%s)", core);
757 if (debugger->priv->output_callback)
759 /* The %s argument is a file name */
760 msg = g_strdup_printf (_("Loading Core: %s\n"), core);
761 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT, msg,
762 debugger->priv->output_user_data);
763 g_free (msg);
766 command = g_strconcat ("core ", core, NULL);
767 dir = g_path_get_dirname (core);
768 debugger->priv->search_dirs =
769 g_list_prepend (debugger->priv->search_dirs, dir);
770 debugger_queue_command (debugger, command, 0, NULL, NULL, NULL);
771 g_free (command);
774 /* Set environment
775 *---------------------------------------------------------------------------*/
777 gboolean
778 debugger_set_working_directory (Debugger *debugger, const gchar *directory)
780 gchar *buff;
782 DEBUG_PRINT ("%s", "In function: set_working_directory()");
784 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
786 buff = g_strdup_printf ("-environment-cd %s", directory);
787 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
788 g_free (buff);
790 return TRUE;
793 gboolean
794 debugger_set_environment (Debugger *debugger, gchar **variables)
796 gchar *buff;
798 DEBUG_PRINT ("%s", "In function: set_environment()");
800 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
802 if ((variables != NULL) && (*variables != NULL))
804 for (; *variables != NULL; variables++)
806 buff = g_strdup_printf("set environment %s", *variables);
807 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
808 g_free (buff);
811 else
813 debugger_emit_ready (debugger);
816 return TRUE;
819 gboolean
820 debugger_set_pretty_printers (Debugger *debugger, const GList *pretty_printers)
822 GString *load = g_string_new (NULL);
823 GList *item;
824 GList *directories = NULL;
826 /* Unload previous pretty printers */
827 g_free (debugger->priv->load_pretty_printer);
829 /* Get all necessary directories */
830 for (item = g_list_first ((GList *)pretty_printers); item != NULL; item = g_list_next (item))
832 GdbPrettyPrinter *printer = (GdbPrettyPrinter *)item->data;
833 gchar *dir;
835 if (printer->enable)
837 dir = g_path_get_dirname (printer->path);
838 if (g_list_find_custom (directories, dir, (GCompareFunc)strcmp) == NULL)
840 directories = g_list_prepend (directories, dir);
842 else
844 g_free (dir);
848 /* Add them in the command */
849 if (directories != NULL)
851 g_string_append (load, "python\nimport sys\n");
853 for (item = g_list_first (directories); item != NULL; item = g_list_next (item))
855 g_string_append_printf (load, "sys.path.insert(0,'%s')\n", (gchar *)item->data);
856 g_free (item->data);
858 g_list_free (directories);
860 /* Import all modules and call register function*/
861 for (item = g_list_first ((GList *)pretty_printers); item != NULL; item = g_list_next (item))
863 GdbPrettyPrinter *printer = (GdbPrettyPrinter *)item->data;
864 gchar *name;
866 if (printer->enable && (printer->function != NULL))
868 /* Remove .py extension */
869 name = g_path_get_basename (printer->path);
870 if (g_str_has_suffix (name, ".py"))
872 name[strlen (name) - 3] = '\0';
875 if (printer->function != NULL)
876 g_string_append_printf (load, "import %s\n%s.%s(None)\n", name, name, printer->function);
879 g_string_append (load, "end");
882 debugger->priv->load_pretty_printer = g_string_free (load, FALSE);
884 return TRUE;
887 static void
888 debugger_list_features_completed (Debugger *debugger,
889 const GDBMIValue *mi_result,
890 const GList *cli_result,
891 GError* error)
893 const GDBMIValue *features;
894 gint i;
896 debugger->priv->has_pending_breakpoints = FALSE;
897 debugger->priv->has_python_support = FALSE;
898 debugger->priv->has_frozen_varobjs = FALSE;
899 debugger->priv->has_thread_info = FALSE;
901 features = gdbmi_value_hash_lookup (mi_result, "features");
903 for (i = 0; i < gdbmi_value_get_size (features); i++)
905 const GDBMIValue *feature;
906 const gchar *value;
908 feature = gdbmi_value_list_get_nth (features, i);
909 value = gdbmi_value_literal_get (feature);
911 if (g_strcmp0 (value, "frozen-varobjs") == 0)
913 debugger->priv->has_frozen_varobjs = TRUE;
915 else if (g_strcmp0 (value, "thread-info") == 0)
917 debugger->priv->has_thread_info = TRUE;
919 else if (g_strcmp0 (value, "pending-breakpoints") == 0)
921 debugger->priv->has_pending_breakpoints = TRUE;
923 else if (g_strcmp0 (value, "python") == 0)
925 debugger->priv->has_python_support = TRUE;
929 if (debugger->priv->has_pending_breakpoints)
931 debugger_queue_command (debugger, "set stop-on-solib-events 0", DEBUGGER_COMMAND_PREPEND, NULL, NULL, NULL);
933 else
935 debugger_queue_command (debugger, "set stop-on-solib-events 1", DEBUGGER_COMMAND_PREPEND, NULL, NULL, NULL);
938 if (debugger->priv->has_python_support && (debugger->priv->load_pretty_printer != NULL))
940 debugger_queue_command (debugger, debugger->priv->load_pretty_printer, 0, NULL, NULL, NULL);
941 debugger_queue_command (debugger, "-enable-pretty-printing", 0, NULL, NULL, NULL);
945 static gboolean
946 debugger_list_features (Debugger *debugger)
948 DEBUG_PRINT ("%s", "In function: list_featues()");
950 g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
952 debugger_queue_command (debugger, "-list-features", 0, debugger_list_features_completed, NULL, NULL);
954 return TRUE;
957 gboolean
958 debugger_start (Debugger *debugger,
959 const GList *search_dirs,
960 const gchar *prog,
961 gboolean is_libtool_prog)
963 gchar *command_str, *dir, *tmp, *text, *msg;
964 gboolean ret;
965 const GList *node;
966 AnjutaPluginManager *plugin_manager;
967 AnjutaLauncher *launcher;
968 GList *dir_list = NULL;
969 gchar *term = NULL;
970 gchar **argv = NULL;
971 gchar **envp = NULL;
972 gchar *work_dir = NULL;
974 DEBUG_PRINT ("In function: debugger_start(%s) libtool %d", prog == NULL ? "(null)" : prog, is_libtool_prog);
976 if (anjuta_util_prog_is_installed ("gdb", TRUE) == FALSE)
977 return FALSE;
979 debugger_queue_clear (debugger);
981 tmp = g_strconcat (PACKAGE_DATA_DIR, "/", "gdb.init", NULL);
982 if (g_file_test (tmp, G_FILE_TEST_IS_REGULAR) == FALSE)
984 anjuta_util_dialog_error (debugger->priv->parent_win,
985 _("Unable to find: %s.\n"
986 "Unable to initialize debugger.\n"
987 "Make sure Anjuta is installed correctly."),
988 tmp);
989 g_free (tmp);
990 return FALSE;
992 g_free (tmp);
994 /* Prepare source search directories */
995 work_dir = NULL;
996 if (prog)
997 work_dir = g_path_get_dirname (prog);
999 dir = g_strdup (" ");
1000 node = search_dirs;
1001 while (node)
1003 text = node->data;
1004 if (strncmp (text, "file://", 7) == 0)
1006 text += 7;
1008 else
1010 g_warning ("Debugger source search uri '%s' is not a local uri", text);
1013 if (text[0] == '/')
1015 tmp = g_strconcat (dir, " -directory=", text, NULL);
1016 g_free (dir);
1017 dir = tmp;
1019 dir_list = g_list_prepend (dir_list, g_strdup (text));
1021 else
1023 g_warning ("Debugger source search dir '%s' is not absolute",
1024 text);
1026 node = g_list_next (node);
1029 /* Now save the dir list. Order is automatically reversed */
1030 node = dir_list;
1031 while (node)
1033 debugger->priv->search_dirs =
1034 g_list_prepend (debugger->priv->search_dirs, node->data);
1035 node = g_list_next (node);
1037 g_list_free (dir_list);
1039 if (prog && strlen(prog) > 0)
1041 gchar *quoted_prog = gdb_quote (prog);
1042 if (is_libtool_prog == FALSE)
1044 command_str = g_strdup_printf (GDB_PATH " -f -n -i=mi2 %s %s "
1045 "-x %s/gdb.init \"%s\"", dir, term == NULL ? "" : term,
1046 PACKAGE_DATA_DIR, quoted_prog);
1048 else
1050 command_str = g_strdup_printf ("libtool --mode=execute " GDB_PATH
1051 " -f -n -i=mi2 %s %s "
1052 "-x %s/gdb.init \"%s\"", dir, term == NULL ? "" : term,
1053 PACKAGE_DATA_DIR, quoted_prog);
1055 g_free (quoted_prog);
1057 else
1059 if (is_libtool_prog == FALSE)
1061 command_str = g_strdup_printf (GDB_PATH " -f -n -i=mi2 %s %s "
1062 "-x %s/gdb.init ", term == NULL ? "" : term,
1063 dir, PACKAGE_DATA_DIR);
1065 else
1067 command_str = g_strdup_printf ("libtool --mode=execute " GDB_PATH
1068 " -f -n -i=mi2 %s %s -x "
1069 "%s/gdb.init ",
1070 dir, term == NULL ? "" : term, PACKAGE_DATA_DIR);
1073 g_shell_parse_argv (command_str, NULL, &argv, NULL);
1074 g_free (command_str);
1076 g_free (dir);
1077 g_free (term);
1078 debugger->priv->starting = TRUE;
1079 debugger->priv->terminating = FALSE;
1080 debugger->priv->loading = prog != NULL ? TRUE : FALSE;
1081 debugger->priv->debugger_is_busy = 1;
1083 /* Get environment */
1084 plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (debugger->priv->instance)->shell, NULL);
1085 if (debugger->priv->environment != NULL)
1087 g_object_unref (debugger->priv->environment);
1089 if (anjuta_plugin_manager_is_active_plugin (plugin_manager, "IAnjutaEnvironment"))
1091 IAnjutaEnvironment *env = IANJUTA_ENVIRONMENT (anjuta_shell_get_object (ANJUTA_PLUGIN (debugger->priv->instance)->shell,
1092 "IAnjutaEnvironment", NULL));
1094 g_object_ref (env);
1095 debugger->priv->environment = env;
1096 ianjuta_environment_override (debugger->priv->environment, &work_dir, &argv, &envp, NULL);
1098 else
1100 debugger->priv->environment = NULL;
1103 /* Prepare for launch. */
1104 launcher = debugger->priv->launcher;
1105 anjuta_launcher_set_terminate_on_exit (launcher, TRUE);
1106 g_signal_connect (G_OBJECT (launcher), "child-exited",
1107 G_CALLBACK (on_gdb_terminated), debugger);
1108 ret = anjuta_launcher_execute_v (launcher,
1109 work_dir,
1110 argv,
1111 envp,
1112 on_gdb_output_arrived, debugger);
1113 g_strfreev (argv);
1114 g_strfreev (envp);
1115 g_free (work_dir);
1117 if (ret)
1119 debugger->priv->debugger_is_started = TRUE;
1120 debugger->priv->prog_is_loaded = prog != NULL;
1122 anjuta_launcher_set_encoding (launcher, "ISO-8859-1");
1124 if (debugger->priv->output_callback != NULL)
1126 if (ret == TRUE)
1128 /* TODO anjuta_update_app_status (TRUE, _("Debugger")); */
1129 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1130 _("Getting ready to start debugging "
1131 "session…\n"),
1132 debugger->priv->output_user_data);
1134 if (prog)
1136 msg = g_strconcat (_("Loading Executable: "), prog, "\n", NULL);
1137 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1138 msg,
1139 debugger->priv->output_user_data);
1140 g_free (msg);
1142 else
1144 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1145 _("No executable specified.\n"),
1146 debugger->priv->output_user_data);
1147 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1148 _("Open an executable or attach "
1149 "to a process to start "
1150 "debugging.\n"),
1151 debugger->priv->output_user_data);
1154 else
1156 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1157 _("There was an error whilst "
1158 "launching the debugger.\n"),
1159 debugger->priv->output_user_data);
1160 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1161 _("Make sure 'gdb' is installed "
1162 "on the system.\n"),
1163 debugger->priv->output_user_data);
1167 /* Check available features */
1168 debugger_list_features (debugger);
1170 debugger_queue_command (debugger, "handle SIGINT stop print nopass", 0, NULL, NULL, NULL);
1172 return TRUE;
1175 static void
1176 gdb_stdout_line_arrived (Debugger *debugger, const gchar * chars)
1178 gint i = 0;
1180 while (chars[i])
1182 if (chars[i] == '\n')
1184 debugger_stdo_flush (debugger);
1186 else
1188 g_string_append_c (debugger->priv->stdo_line, chars[i]);
1190 i++;
1194 static void
1195 gdb_stderr_line_arrived (Debugger *debugger, const gchar * chars)
1197 gint i;
1199 for (i = 0; i < strlen (chars); i++)
1201 if (chars[i] == '\n')
1202 debugger_stde_flush (debugger);
1203 else
1204 g_string_append_c (debugger->priv->stde_line, chars[i]);
1208 static void
1209 on_gdb_output_arrived (AnjutaLauncher *launcher,
1210 AnjutaLauncherOutputType output_type,
1211 const gchar *chars, gpointer data)
1213 Debugger *debugger = DEBUGGER (data);
1214 DEBUG_PRINT ("%s", "on gdb output arrived");
1216 /* Do not emit signal when the debugger is destroyed */
1217 if (debugger->priv->instance == NULL) return;
1219 switch (output_type)
1221 case ANJUTA_LAUNCHER_OUTPUT_STDERR:
1222 gdb_stderr_line_arrived (debugger, chars);
1223 break;
1224 case ANJUTA_LAUNCHER_OUTPUT_STDOUT:
1225 gdb_stdout_line_arrived (debugger, chars);
1226 break;
1227 default:
1228 break;
1232 static void
1233 debugger_handle_post_execution (Debugger *debugger)
1235 switch (debugger->priv->post_execution_flag)
1237 case DEBUGGER_NONE:
1238 break;
1239 case DEBUGGER_EXIT:
1240 DEBUG_PRINT ("%s", "debugger stop in handle post execution\n");
1241 debugger_stop (debugger);
1242 break;
1243 case DEBUGGER_RERUN_PROGRAM:
1244 DEBUG_PRINT ("%s", "debugger run in handle post execution\n");
1245 debugger_run (debugger);
1246 break;
1247 default:
1248 g_warning ("Execution should not reach here");
1252 static const gchar *
1253 debugger_parse_filename (const GDBMIValue *frame)
1255 const GDBMIValue *filename, *fullname;
1256 const gchar *file_str = NULL;
1258 /* Get filename from file if possible to keep symbolic links */
1259 filename = gdbmi_value_hash_lookup (frame, "file");
1260 if (filename)
1262 file_str = gdbmi_value_literal_get (filename);
1263 if (!g_path_is_absolute (file_str))
1265 /* Path is not absolute */
1266 file_str = NULL;
1270 /* Try fullname value to get an absolute path */
1271 if (file_str == NULL)
1273 fullname = gdbmi_value_hash_lookup (frame, "fullname");
1274 if (fullname)
1276 file_str = gdbmi_value_literal_get (fullname);
1278 else
1280 if (filename)
1282 file_str = gdbmi_value_literal_get (filename);
1287 if ((file_str != NULL) && (*file_str == '\0')) file_str = NULL;
1289 return file_str;
1292 static void
1293 debugger_process_frame (Debugger *debugger, const GDBMIValue *val)
1295 const GDBMIValue *line, *frame, *addr, *thread;
1296 const gchar *file_str = NULL;
1297 guint line_num = 0;
1298 gulong addr_num = 0;
1300 g_return_if_fail (val != NULL);
1302 thread = gdbmi_value_hash_lookup (val, "thread-id");
1303 if (thread)
1305 debugger->priv->current_thread = strtoul (gdbmi_value_literal_get (thread), NULL, 0);
1307 debugger->priv->current_frame = 0;
1309 frame = gdbmi_value_hash_lookup (val, "frame");
1310 if (frame)
1312 file_str = debugger_parse_filename (frame);
1314 if (file_str != NULL)
1316 line = gdbmi_value_hash_lookup (frame, "line");
1317 if (line)
1319 line_num = strtoul (gdbmi_value_literal_get (line), NULL, 0);
1323 addr = gdbmi_value_hash_lookup (frame, "addr");
1324 if (addr)
1326 addr_num = strtoul (gdbmi_value_literal_get (addr), NULL, 0);
1328 debugger_program_moved (debugger, file_str, line_num, addr_num);
1332 static GError*
1333 gdb_parse_error (Debugger *debugger, const GDBMIValue *mi_results)
1335 const GDBMIValue *message;
1336 const gchar *literal;
1337 guint code = IANJUTA_DEBUGGER_UNKNOWN_ERROR;
1339 message = gdbmi_value_hash_lookup (mi_results, "msg");
1340 literal = gdbmi_value_literal_get (message);
1342 if ((mi_results != NULL)
1343 && ((message = gdbmi_value_hash_lookup (mi_results, "msg")) != NULL)
1344 && ((literal = gdbmi_value_literal_get (message)) != NULL)
1345 && (*literal != '\0'))
1347 code = gdb_match_error (literal);
1348 DEBUG_PRINT ("error code %d", code);
1350 else
1352 /* No error message */
1353 literal = "Error without a message";
1356 return g_error_new_literal (IANJUTA_DEBUGGER_ERROR, code, literal);
1360 /* Parsing output
1361 *---------------------------------------------------------------------------*/
1363 static void
1364 debugger_parse_output (Debugger *debugger)
1366 gchar *line;
1368 line = debugger->priv->stdo_line->str;
1370 if (line[0] == '\032' && line[1] == '\032')
1372 gchar *filename;
1373 guint lineno;
1375 gdb_util_parse_error_line (&(line[2]), &filename, &lineno);
1376 if (filename)
1378 debugger_program_moved (debugger, filename, lineno, 0);
1379 g_free (filename);
1382 else
1384 gchar *proper_msg;
1385 gsize len;
1387 len = strlen (line);
1388 if (line[1] == '\"' && line [strlen(line) - 1] == '\"')
1390 line[1] = line[0];
1391 /* Reserve space for an additional carriage return */
1392 line[strlen(line) - 1] = ' ';
1393 proper_msg = g_strcompress (line + 1);
1394 len = strlen (proper_msg) - 1;
1395 proper_msg[len] = '\0';
1397 else
1399 /* Reserve space for an additional carriage return */
1400 proper_msg = g_strndup (line, len + 1);
1403 if (strcmp(proper_msg, "~Stopped due to shared library event\n") == 0)
1405 /* Recognize a solib event */
1406 debugger->priv->solib_event = TRUE;
1407 g_free (proper_msg);
1409 else if (debugger->priv->current_cmd.parser)
1411 /* Save GDB CLI output */
1412 debugger->priv->cli_lines = g_list_prepend (debugger->priv->cli_lines,
1413 proper_msg);
1415 else
1417 /* Discard CLI output */
1418 g_free (proper_msg);
1423 static void
1424 debugger_parse_stopped (Debugger *debugger)
1426 gchar *line = debugger->priv->stdo_line->str;
1429 if (!debugger->priv->solib_event)
1431 gboolean program_exited = FALSE;
1432 GDBMIValue *val;
1434 /* Check if program has exited */
1435 val = gdbmi_value_parse (line);
1436 if (val)
1438 const GDBMIValue *reason;
1439 const gchar *str = NULL;
1441 debugger_process_frame (debugger, val);
1443 reason = gdbmi_value_hash_lookup (val, "reason");
1444 if (reason)
1445 str = gdbmi_value_literal_get (reason);
1447 if (str && (strncmp (str, "exited", 6) == 0))
1449 program_exited = TRUE;
1452 /* Emit signal received if necessary */
1453 if (str && strcmp (str, "exited-signalled") == 0)
1455 const GDBMIValue *signal_name, *signal_meaning;
1456 const gchar *signal_str, *signal_meaning_str;
1458 signal_name = gdbmi_value_hash_lookup (val, "signal-name");
1459 signal_str = gdbmi_value_literal_get (signal_name);
1460 signal_meaning = gdbmi_value_hash_lookup (val, "signal-meaning");
1461 signal_meaning_str = gdbmi_value_literal_get (signal_meaning);
1462 g_signal_emit_by_name (debugger->priv->instance, "signal-received", signal_str, signal_meaning_str);
1464 else if (str && strcmp (str, "signal-received") == 0)
1466 const GDBMIValue *signal_name, *signal_meaning;
1467 const gchar *signal_str, *signal_meaning_str;
1469 signal_name = gdbmi_value_hash_lookup (val, "signal-name");
1470 signal_str = gdbmi_value_literal_get (signal_name);
1471 signal_meaning = gdbmi_value_hash_lookup (val, "signal-meaning");
1472 signal_meaning_str = gdbmi_value_literal_get (signal_meaning);
1474 g_signal_emit_by_name (debugger->priv->instance, "signal-received", signal_str, signal_meaning_str);
1477 if (debugger->priv->output_callback)
1479 if (str && strcmp (str, "exited-normally") == 0)
1481 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1482 _("Program exited normally\n"),
1483 debugger->priv->output_user_data);
1485 else if (str && strcmp (str, "exited") == 0)
1487 const GDBMIValue *errcode;
1488 const gchar *errcode_str;
1489 gchar *msg;
1491 errcode = gdbmi_value_hash_lookup (val, "exit-code");
1492 errcode_str = gdbmi_value_literal_get (errcode);
1493 msg = g_strdup_printf (_("Program exited with error code %s\n"),
1494 errcode_str);
1495 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1496 msg, debugger->priv->output_user_data);
1497 g_free (msg);
1499 else if (str && strcmp (str, "breakpoint-hit") == 0)
1501 const GDBMIValue *bkptno;
1502 const gchar *bkptno_str;
1503 gchar *msg;
1505 bkptno = gdbmi_value_hash_lookup (val, "bkptno");
1506 bkptno_str = gdbmi_value_literal_get (bkptno);
1507 /* The program has reached one breakpoint and will stop */
1508 msg = g_strdup_printf (_("Breakpoint number %s hit\n"),
1509 bkptno_str);
1510 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1511 msg, debugger->priv->output_user_data);
1512 g_free (msg);
1514 else if (str && strcmp (str, "function-finished") == 0)
1516 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1517 _("Function finished\n"),
1518 debugger->priv->output_user_data);
1520 else if (str && strcmp (str, "end-stepping-range") == 0)
1522 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1523 _("Stepping finished\n"),
1524 debugger->priv->output_user_data);
1526 else if (str && strcmp (str, "location-reached") == 0)
1528 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1529 _("Location reached\n"),
1530 debugger->priv->output_user_data);
1535 if (program_exited)
1537 debugger->priv->prog_is_running = FALSE;
1538 debugger->priv->prog_is_attached = FALSE;
1539 debugger_handle_post_execution (debugger);
1540 debugger->priv->exiting = TRUE;
1542 else
1544 // g_signal_emit_by_name (debugger->priv->instance, "program-stopped");
1545 debugger->priv->stopping = TRUE;
1548 debugger->priv->cli_lines = g_list_reverse (debugger->priv->cli_lines);
1549 if ((debugger->priv->current_cmd.cmd != NULL) &&
1550 (debugger->priv->current_cmd.parser != NULL))
1552 debugger->priv->current_cmd.parser (debugger, val,
1553 debugger->priv->cli_lines, FALSE);
1554 debugger->priv->command_output_sent = TRUE;
1555 DEBUG_PRINT ("%s", "In function: Sending output…");
1558 if (val)
1559 gdbmi_value_free (val);
1563 static void
1564 debugger_parse_prompt (Debugger *debugger)
1566 /* If the parser has not yet been called, call it now. */
1567 if (debugger->priv->command_output_sent == FALSE &&
1568 debugger->priv->current_cmd.parser)
1570 debugger->priv->current_cmd.parser (debugger, NULL,
1571 debugger->priv->cli_lines, FALSE);
1572 debugger->priv->command_output_sent = TRUE;
1575 debugger->priv->debugger_is_busy--;
1576 debugger_queue_execute_command (debugger); /* Next command. Go. */
1577 debugger_emit_ready (debugger);
1580 static gboolean
1581 parse_breakpoint (IAnjutaDebuggerBreakpointItem* bp, const GDBMIValue *brkpnt)
1583 const GDBMIValue *literal;
1584 const gchar* value;
1586 memset (bp, 0, sizeof (*bp));
1588 literal = gdbmi_value_hash_lookup (brkpnt, "number");
1589 if (literal)
1591 value = gdbmi_value_literal_get (literal);
1592 bp->id = strtoul (value, NULL, 10);
1595 bp->file = (gchar *)debugger_parse_filename (brkpnt);
1597 literal = gdbmi_value_hash_lookup (brkpnt, "line");
1598 if (literal)
1600 value = gdbmi_value_literal_get (literal);
1601 bp->line = strtoul (value, NULL, 10);
1602 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_LINE;
1605 literal = gdbmi_value_hash_lookup (brkpnt, "type");
1606 if (literal)
1608 value = gdbmi_value_literal_get (literal);
1611 literal = gdbmi_value_hash_lookup (brkpnt, "disp");
1612 if (literal)
1614 value = gdbmi_value_literal_get (literal);
1615 if (strcmp (value, "keep") == 0)
1617 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TEMPORARY;
1618 bp->temporary = FALSE;
1620 else if ((strcmp (value, "nokeep") == 0) || (strcmp (value, "del") == 0))
1622 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TEMPORARY;
1623 bp->temporary = TRUE;
1627 literal = gdbmi_value_hash_lookup (brkpnt, "enabled");
1628 if (literal)
1630 value = gdbmi_value_literal_get (literal);
1631 if (strcmp (value, "n") == 0)
1633 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_ENABLE;
1634 bp->enable = FALSE;
1636 else if (strcmp (value, "y") == 0)
1638 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_ENABLE;
1639 bp->enable = TRUE;
1643 literal = gdbmi_value_hash_lookup (brkpnt, "addr");
1644 if (literal)
1646 value = gdbmi_value_literal_get (literal);
1647 if (strcmp (value, "<PENDING>") == 0)
1649 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_PENDING;
1650 bp->pending = TRUE;
1652 else
1654 bp->address = strtoul (value, NULL, 16);
1655 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_ADDRESS;
1656 bp->pending = FALSE;
1660 literal = gdbmi_value_hash_lookup (brkpnt, "func");
1661 if (literal)
1663 value = gdbmi_value_literal_get (literal);
1664 bp->function = (gchar *)value;
1665 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_FUNCTION;
1668 literal = gdbmi_value_hash_lookup (brkpnt, "times");
1669 if (literal)
1671 value = gdbmi_value_literal_get (literal);
1672 bp->times = strtoul (value, NULL, 10);
1673 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TIME;
1675 DEBUG_PRINT("parse time %d", bp->times);
1677 literal = gdbmi_value_hash_lookup (brkpnt, "ignore");
1678 if (literal)
1680 value = gdbmi_value_literal_get (literal);
1681 bp->ignore = strtoul (value, NULL, 10);
1682 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_IGNORE;
1685 literal = gdbmi_value_hash_lookup (brkpnt, "cond");
1686 if (literal)
1688 value = gdbmi_value_literal_get (literal);
1689 bp->condition = (gchar *)value;
1690 bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_CONDITION;
1693 return TRUE;
1696 static void
1697 debugger_stdo_flush (Debugger *debugger)
1699 gchar *line;
1701 line = debugger->priv->stdo_line->str;
1703 #ifdef DEBUG
1704 DEBUG_PRINT ("GDB:< %s", line);
1705 #else
1706 if (debugger->priv->gdb_log) g_message ("GDB:< %s", line);
1707 #endif
1708 debugger_log_output (debugger, line);
1709 if (strlen (line) == 0)
1711 return;
1713 if (strncasecmp (line, "^error", 6) == 0)
1715 /* GDB reported error */
1716 if ((debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT) || (debugger->priv->stdo_acc->len != 0))
1718 /* Keep result for next command */
1720 if (debugger->priv->stdo_acc->len == 0)
1722 g_string_append (debugger->priv->stdo_acc, line);
1724 else
1726 line = strchr (line, ',');
1727 if (line != NULL)
1729 g_string_append (debugger->priv->stdo_acc, line);
1732 line = debugger->priv->stdo_acc->str;
1735 GDBMIValue *val = gdbmi_value_parse (line);
1736 GError *error;
1738 error = gdb_parse_error (debugger, val);
1740 /* Trap state error */
1741 if ((error != NULL) && ((error->code == IANJUTA_DEBUGGER_PROGRAM_NOT_FOUND) ||
1742 (error->code == IANJUTA_DEBUGGER_UNABLE_TO_CONNECT)))
1744 debugger->priv->prog_is_running = FALSE;
1745 debugger->priv->prog_is_attached = FALSE;
1746 debugger->priv->prog_is_remote = FALSE;
1747 debugger->priv->prog_is_loaded = FALSE;
1750 if (debugger->priv->current_cmd.parser != NULL)
1752 debugger->priv->current_cmd.parser (debugger, val, debugger->priv->cli_lines, error);
1753 debugger->priv->command_output_sent = TRUE; }
1754 DEBUG_PRINT("GDB: error %s", error->message);
1755 /*else
1757 anjuta_util_dialog_error (debugger->priv->parent_win, "%s", error->message);
1759 g_error_free (error);
1760 gdbmi_value_free (val);
1762 else if (strncasecmp(line, "^running", 8) == 0)
1764 /* Program started running */
1765 debugger->priv->prog_is_running = TRUE;
1766 /* debugger->priv->skip_next_prompt = TRUE; Replaced by debugger_is_busy++ */
1767 debugger->priv->debugger_is_busy++;
1768 g_signal_emit_by_name (debugger->priv->instance, "program-running");
1770 else if (strncasecmp (line, "*stopped", 8) == 0)
1772 /* Process has stopped */
1773 debugger_parse_stopped (debugger);
1775 else if (strncasecmp (line, "^done", 5) == 0)
1777 if ((debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT) || (debugger->priv->stdo_acc->len != 0))
1779 /* Keep result for next command */
1781 if (debugger->priv->stdo_acc->len == 0)
1783 g_string_append (debugger->priv->stdo_acc, line);
1785 else
1787 line = strchr (line, ',');
1788 if (line != NULL)
1790 g_string_append (debugger->priv->stdo_acc, line);
1793 line = debugger->priv->stdo_acc->str;
1796 if (!(debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT))
1798 /* GDB command has reported output */
1799 GDBMIValue *val = gdbmi_value_parse (line);
1801 debugger->priv->cli_lines = g_list_reverse (debugger->priv->cli_lines);
1802 if ((debugger->priv->current_cmd.cmd != NULL) &&
1803 (debugger->priv->current_cmd.parser != NULL))
1805 debugger->priv->current_cmd.parser (debugger, val,
1806 debugger->priv->cli_lines, FALSE);
1807 debugger->priv->command_output_sent = TRUE;
1808 DEBUG_PRINT ("%s", "In function: Sending output…");
1810 else /* if (val) */
1812 /*g_signal_emit_by_name (debugger, "results-arrived",
1813 debugger->priv->current_cmd.cmd, val);*/
1816 if (val)
1818 /*debugger_process_frame (debugger, val);*/
1819 gdbmi_value_free (val);
1823 if (!(debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT))
1825 g_string_assign (debugger->priv->stdo_acc, "");
1828 else if (strncasecmp (line, GDB_PROMPT, strlen (GDB_PROMPT)) == 0)
1830 debugger_parse_prompt (debugger);
1832 else
1834 debugger_parse_output (debugger);
1837 /* Clear the line buffer */
1838 g_string_assign (debugger->priv->stdo_line, "");
1841 void
1842 debugger_stde_flush (Debugger *debugger)
1844 if ((debugger->priv->output_callback) && (strlen (debugger->priv->stde_line->str) > 0))
1846 debugger->priv->output_callback (IANJUTA_DEBUGGER_ERROR_OUTPUT,
1847 debugger->priv->stde_line->str,
1848 debugger->priv->output_user_data);
1850 /* Clear the line buffer */
1851 g_string_assign (debugger->priv->stde_line, "");
1854 static void
1855 on_gdb_terminated (AnjutaLauncher *launcher,
1856 gint child_pid, gint status, gulong t,
1857 gpointer data)
1859 Debugger *debugger = DEBUGGER (data);
1860 GError *err = NULL;
1862 g_signal_handlers_disconnect_by_func (G_OBJECT (launcher),
1863 G_CALLBACK (on_gdb_terminated),
1864 debugger);
1866 DEBUG_PRINT ("%s", "In function: gdb_terminated()");
1868 /* Clear the command queue & Buffer */
1869 debugger_clear_buffers (debugger);
1871 /* Good Bye message */
1872 /*if (!debugger->priv->terminating)
1874 anjuta_util_dialog_error (debugger->priv->parent_win,
1875 _("gdb terminated unexpectedly with status %d\n"), status);
1877 debugger->priv->prog_is_running = FALSE;
1878 debugger->priv->prog_is_attached = FALSE;
1879 debugger->priv->prog_is_loaded = FALSE;
1880 debugger->priv->prog_is_remote = FALSE;
1881 debugger->priv->debugger_is_busy = 0;
1882 debugger->priv->skip_next_prompt = FALSE;
1884 if (!debugger->priv->terminating)
1886 err = g_error_new (IANJUTA_DEBUGGER_ERROR,
1887 IANJUTA_DEBUGGER_OTHER_ERROR,
1888 "gdb terminated with status %d", status);
1890 debugger->priv->terminating = FALSE;
1891 debugger->priv->debugger_is_started = FALSE;
1892 if (debugger->priv->instance)
1894 g_signal_emit_by_name (debugger->priv->instance, "debugger-stopped", err);
1896 if (err != NULL) g_error_free (err);
1899 static void
1900 debugger_stop_real (Debugger *debugger)
1902 DEBUG_PRINT ("%s", "In function: debugger_stop_real()");
1904 /* if program is attached - detach from it before quiting */
1905 if (debugger->priv->prog_is_attached == TRUE)
1907 debugger_detach_process(debugger);
1910 debugger->priv->terminating = TRUE;
1911 debugger_queue_command (debugger, "-gdb-exit", 0, NULL, NULL, NULL);
1914 gboolean
1915 debugger_stop (Debugger *debugger)
1917 #if 0
1918 gboolean ret = TRUE;
1920 if (debugger->priv->prog_is_running == TRUE)
1922 GtkWidget *dialog;
1923 gchar *mesg;
1925 if (debugger->priv->prog_is_attached == TRUE)
1926 mesg = _("The program is attached.\n"
1927 "Do you still want to stop the debugger?");
1928 else
1929 mesg = _("The program is running.\n"
1930 "Do you still want to stop the debugger?");
1931 dialog = gtk_message_dialog_new (debugger->priv->parent_win,
1932 GTK_DIALOG_DESTROY_WITH_PARENT,
1933 GTK_MESSAGE_QUESTION,
1934 GTK_BUTTONS_NONE, mesg);
1935 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
1936 GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
1937 GTK_STOCK_STOP, GTK_RESPONSE_YES,
1938 NULL);
1939 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
1940 debugger_stop_real (debugger);
1941 else
1942 ret = FALSE;
1943 gtk_widget_destroy (dialog);
1945 else
1946 debugger_stop_real (debugger);
1947 return ret;
1948 #endif
1949 debugger_stop_real (debugger);
1951 return TRUE;
1954 gboolean
1955 debugger_abort (Debugger *debugger)
1957 DEBUG_PRINT ("%s", "In function: debugger_abort()");
1959 /* Stop inferior */
1960 if ((debugger->priv->prog_is_attached == FALSE) && (debugger->priv->inferior_pid != 0))
1962 kill (debugger->priv->inferior_pid, SIGTERM);
1963 debugger->priv->inferior_pid = 0;
1966 /* Stop gdb */
1967 debugger->priv->terminating = TRUE;
1968 g_signal_handlers_disconnect_by_func (G_OBJECT (debugger->priv->launcher), G_CALLBACK (on_gdb_terminated), debugger);
1969 anjuta_launcher_reset (debugger->priv->launcher);
1971 /* Free memory */
1972 debugger_queue_clear (debugger);
1973 g_list_foreach (debugger->priv->search_dirs, (GFunc)g_free, NULL);
1974 g_list_free (debugger->priv->search_dirs);
1975 debugger->priv->search_dirs = NULL;
1977 /* Emit signal, state of the debugger must be DEBUGGER_STOPPED */
1978 debugger->priv->prog_is_running = FALSE;
1979 debugger->priv->prog_is_attached = FALSE;
1980 debugger->priv->inferior_pid = 0;
1981 debugger->priv->prog_is_loaded = FALSE;
1982 debugger->priv->prog_is_remote = FALSE;
1983 debugger->priv->debugger_is_busy = 0;
1984 debugger->priv->debugger_is_started = FALSE;
1986 if (debugger->priv->instance != NULL)
1988 /* debugger-stopped triggers a call to debugger_free that
1989 * will free the debugger instance, so no access to it is
1990 * allowed after the following line */
1991 g_signal_emit_by_name (debugger->priv->instance, "debugger-stopped", NULL);
1994 return TRUE;
1997 gchar*
1998 debugger_get_source_path (Debugger *debugger, const gchar *file)
2000 GList *node;
2001 gchar *path = NULL;
2003 if (g_path_is_absolute (file))
2004 return g_strdup (file);
2006 node = debugger->priv->search_dirs;
2007 while (node)
2009 path = g_build_filename (node->data, file, NULL);
2010 if (g_file_test (path, G_FILE_TEST_EXISTS))
2011 break;
2012 g_free (path);
2013 path = NULL;
2014 node = g_list_next (node);
2017 if (path == NULL)
2019 /* The file could be found nowhere. Use current directory */
2020 gchar *cwd;
2021 cwd = anjuta_util_get_current_dir ();
2022 path = g_build_filename (cwd, file, NULL);
2023 g_free (cwd);
2025 return path;
2028 void
2029 debugger_set_output_callback (Debugger *debugger, IAnjutaDebuggerOutputCallback callback, gpointer user_data)
2031 debugger->priv->output_callback = callback;
2032 debugger->priv->output_user_data = user_data;
2035 void
2036 debugger_program_moved (Debugger *debugger, const gchar *file,
2037 gint line, gulong address)
2039 gchar *src_path;
2041 if ((file != NULL) && (*file != G_DIR_SEPARATOR))
2043 src_path = debugger_get_source_path (debugger, file);
2044 g_signal_emit_by_name (debugger->priv->instance, "program-moved", debugger->priv->inferior_pid, debugger->priv->current_thread, address, src_path, line);
2045 g_free (src_path);
2047 else
2049 g_signal_emit_by_name (debugger->priv->instance, "program-moved", debugger->priv->inferior_pid, debugger->priv->current_thread, address, file, line);
2053 static void
2054 debugger_info_program_finish (Debugger *debugger, const GDBMIValue *mi_results,
2055 const GList *cli_results, GError *error)
2057 DEBUG_PRINT ("%s", "In function: debugger_info_program()");
2059 /* Hack: find message string giving inferior pid */
2060 while (cli_results != NULL)
2062 gchar* child_proc;
2064 child_proc = strstr(cli_results->data, " child process ");
2065 if (child_proc != NULL)
2067 debugger->priv->inferior_pid = strtoul (child_proc + 15, NULL, 10);
2068 break;
2070 cli_results = g_list_next (cli_results);
2074 static void
2075 debugger_is_connected (Debugger *debugger, const GDBMIValue *mi_results,
2076 const GList *cli_results, GError *error)
2078 g_return_if_fail (debugger->priv->remote_server != NULL);
2080 if (error != NULL)
2082 gchar *msg;
2083 gboolean retry;
2085 /* The %s argument is an error message returned by gdb.
2086 * It is something like, "No such file or directory" */
2087 msg = g_strdup_printf(_("Unable to connect to remote target, %s\nDo you want to try again?"),
2088 error->message);
2089 retry = anjuta_util_dialog_boolean_question (debugger->priv->parent_win, msg);
2090 g_free (msg);
2091 if (retry)
2093 gchar *cmd;
2095 cmd = g_strconcat ("-target-select remote ", debugger->priv->remote_server, NULL);
2096 debugger_queue_command (debugger, cmd, 0, debugger_is_connected, NULL, NULL);
2097 g_free (cmd);
2100 else
2102 if (debugger->priv->output_callback)
2104 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2105 _("Debugger connected\n"),
2106 debugger->priv->output_user_data);
2108 debugger->priv->prog_is_remote = TRUE;
2109 debugger->priv->prog_is_running = TRUE;
2110 /* It is not really a shared lib event, but it allows to restart
2111 * the program after setting breakpoints. It is better to restart
2112 * it because we don't have the normal stop frame that tell where
2113 * the program is stopped */
2114 debugger->priv->solib_event = TRUE;
2118 void
2119 debugger_start_program (Debugger *debugger, const gchar *remote, const gchar* args, const gchar* tty, gboolean stop)
2121 gchar *cmd;
2123 DEBUG_PRINT ("%s", "In function: debugger_start_program()");
2125 g_return_if_fail (IS_DEBUGGER (debugger));
2126 g_return_if_fail (debugger->priv->prog_is_running == FALSE);
2129 /* Without a terminal, the output of the debugged program
2130 * are lost */
2131 if (tty)
2133 cmd = g_strdup_printf ("-inferior-tty-set %s", tty);
2134 debugger_queue_command (debugger, cmd, 0, NULL, NULL, NULL);
2135 g_free (cmd);
2138 debugger->priv->inferior_pid = 0;
2139 if (stop)
2141 debugger_queue_command (debugger, "-break-insert -t main", 0, NULL, NULL, NULL);
2143 if (args && (*args))
2145 cmd = g_strconcat ("-exec-arguments ", args, NULL);
2146 debugger_queue_command (debugger, cmd, 0, NULL, NULL, NULL);
2147 g_free (cmd);
2150 /* If we are remote then we have to just continue here since we always
2151 * get stopped as part of the remote target setup.
2153 g_free (debugger->priv->remote_server);
2154 if (remote != NULL)
2156 debugger->priv->remote_server = g_strdup (remote);
2157 cmd = g_strconcat ("-target-select remote ", remote, NULL);
2158 debugger_queue_command (debugger, cmd, 0, debugger_is_connected, NULL, NULL);
2159 g_free (cmd);
2161 else
2163 debugger_queue_command (debugger, "-exec-run", 0, NULL, NULL, NULL);
2165 /* Get pid of program on next stop */
2166 debugger_queue_command (debugger, "info program", 0, debugger_info_program_finish, NULL, NULL);
2167 debugger->priv->post_execution_flag = DEBUGGER_NONE;
2171 static void
2172 debugger_attach_process_finish (Debugger *debugger, const GDBMIValue *mi_results,
2173 const GList *cli_results, GError *error)
2175 DEBUG_PRINT ("%s", "Program attach finished");
2176 if (debugger->priv->output_callback)
2178 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2179 _("Program attached\n"),
2180 debugger->priv->output_user_data);
2182 debugger->priv->prog_is_attached = TRUE;
2183 debugger->priv->prog_is_running = TRUE;
2184 /* It is not really a shared lib event, but it allows to restart
2185 * the program after setting breakpoints. It is better to restart
2186 * it because we don't have the normal stop frame that tell where
2187 * the program is stopped */
2188 debugger->priv->solib_event = TRUE;
2191 static void
2192 debugger_attach_process_real (Debugger *debugger, pid_t pid)
2194 gchar *buff;
2196 DEBUG_PRINT ("%s", "In function: debugger_attach_process_real()");
2198 if (debugger->priv->output_callback)
2200 buff = g_strdup_printf (_("Attaching to process: %d…\n"), pid);
2201 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2202 buff, debugger->priv->output_user_data);
2203 g_free (buff);
2206 debugger->priv->inferior_pid = pid;
2207 buff = g_strdup_printf ("attach %d", pid);
2208 debugger_queue_command (debugger, buff, 0,
2209 debugger_attach_process_finish, NULL, NULL);
2210 g_free (buff);
2213 void
2214 debugger_attach_process (Debugger *debugger, pid_t pid)
2216 DEBUG_PRINT ("%s", "In function: debugger_attach_process()");
2218 g_return_if_fail (IS_DEBUGGER (debugger));
2220 if (debugger->priv->prog_is_running == TRUE)
2222 // TODO: Dialog to be made HIG compliant.
2223 gchar *mesg;
2224 GtkWidget *dialog;
2226 mesg = _("A process is already running.\n"
2227 "Would you like to terminate it and attach the new process?"),
2228 dialog = gtk_message_dialog_new (debugger->priv->parent_win,
2229 GTK_DIALOG_DESTROY_WITH_PARENT,
2230 GTK_MESSAGE_QUESTION,
2231 GTK_BUTTONS_YES_NO, "%s", mesg);
2232 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
2234 debugger_stop_program (debugger);
2235 debugger_attach_process_real (debugger, pid);
2237 gtk_widget_destroy (dialog);
2239 else if (getpid () == pid ||
2240 anjuta_launcher_get_child_pid (debugger->priv->launcher) == pid)
2242 anjuta_util_dialog_error (debugger->priv->parent_win,
2243 _("Anjuta is unable to attach to itself."));
2244 return;
2246 else
2247 debugger_attach_process_real (debugger, pid);
2250 void
2251 debugger_restart_program (Debugger *debugger)
2253 DEBUG_PRINT ("%s", "In function: debugger_restart_program()");
2255 g_return_if_fail (debugger->priv->prog_is_attached == FALSE);
2258 debugger->priv->post_execution_flag = DEBUGGER_RERUN_PROGRAM;
2259 debugger_stop_program (debugger);
2261 debugger_put_cmd_in_queqe ("tbreak main", DB_CMD_NONE, NULL, NULL);
2262 debugger_put_cmd_in_queqe ("run >/dev/null 2>/dev/null", DB_CMD_ALL,
2263 NULL, NULL);
2264 debugger_put_cmd_in_queqe ("info program", DB_CMD_NONE,
2265 on_debugger_update_prog_status, NULL);
2266 debugger_put_cmd_in_queqe ("continue", DB_CMD_NONE, NULL, NULL);
2267 debugger_execute_cmd_in_queqe ();
2271 void
2272 debugger_stop_program (Debugger *debugger)
2274 DEBUG_PRINT ("%s", "In function: debugger_stop_program()");
2276 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2278 if (debugger->priv->prog_is_attached == TRUE)
2280 debugger_detach_process (debugger);
2282 else
2284 /* FIXME: Why doesn't -exec-abort work??? */
2285 /* debugger_queue_command (debugger, "-exec-abort", NULL, NULL); */
2286 debugger_queue_command (debugger, "kill", 0, NULL, NULL, NULL);
2287 debugger->priv->prog_is_running = FALSE;
2288 debugger->priv->prog_is_attached = FALSE;
2289 g_signal_emit_by_name (debugger->priv->instance, "program-exited");
2290 if (debugger->priv->output_callback)
2292 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2293 _("Program terminated\n"),
2294 debugger->priv->output_user_data);
2296 debugger_handle_post_execution (debugger);
2300 static void
2301 debugger_detach_process_finish (Debugger *debugger, const GDBMIValue *mi_results,
2302 const GList *cli_results, GError *error)
2304 DEBUG_PRINT ("%s", "Program detach finished");
2305 if (debugger->priv->output_callback)
2307 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2308 _("Program detached\n"),
2309 debugger->priv->output_user_data);
2311 debugger->priv->inferior_pid = 0;
2312 debugger->priv->prog_is_attached = FALSE;
2313 debugger->priv->prog_is_running = FALSE;
2314 g_signal_emit_by_name (debugger->priv->instance, "program-exited");
2317 void
2318 debugger_detach_process (Debugger *debugger)
2320 gchar *buff;
2322 DEBUG_PRINT ("%s", "In function: debugger_detach_process()");
2324 g_return_if_fail (debugger->priv->prog_is_attached == TRUE);
2326 if (debugger->priv->output_callback)
2328 buff = g_strdup_printf (_("Detaching the process…\n"));
2329 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2330 buff, debugger->priv->output_user_data);
2331 g_free (buff);
2334 debugger_queue_command (debugger, "detach", 0,
2335 debugger_detach_process_finish, NULL, NULL);
2338 void
2339 debugger_interrupt (Debugger *debugger)
2341 DEBUG_PRINT ("%s", "In function: debugger_interrupt()");
2343 g_message ("debugger_interrupt inferiod_pid %d", debugger->priv->inferior_pid);
2345 g_return_if_fail (IS_DEBUGGER (debugger));
2346 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2348 if (debugger->priv->output_callback)
2350 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2351 _("Interrupting the process\n"),
2352 debugger->priv->output_user_data);
2355 if (debugger->priv->inferior_pid == 0)
2357 /* In case we do not have the inferior pid, send signal to gdb */
2358 anjuta_launcher_signal (debugger->priv->launcher, SIGINT);
2360 else
2362 /* Send signal directly to inferior */
2363 kill (debugger->priv->inferior_pid, SIGINT);
2365 //g_signal_emit_by_name (debugger->priv->instance, "program-running");
2368 void
2369 debugger_run (Debugger *debugger)
2371 DEBUG_PRINT ("%s", "In function: debugger_run()");
2373 g_return_if_fail (IS_DEBUGGER (debugger));
2374 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2376 /* Program running - continue */
2377 debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2380 void
2381 debugger_step_in (Debugger *debugger)
2383 DEBUG_PRINT ("%s", "In function: debugger_step_in()");
2385 g_return_if_fail (IS_DEBUGGER (debugger));
2386 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2388 debugger_queue_command (debugger, "-exec-step", 0, NULL, NULL, NULL);
2391 void
2392 debugger_step_over (Debugger *debugger)
2394 DEBUG_PRINT ("%s", "In function: debugger_step_over()");
2396 g_return_if_fail (IS_DEBUGGER (debugger));
2397 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2399 debugger_queue_command (debugger, "-exec-next", 0, NULL, NULL, NULL);
2402 void
2403 debugger_step_out (Debugger *debugger)
2405 DEBUG_PRINT ("%s", "In function: debugger_step_out()");
2407 g_return_if_fail (IS_DEBUGGER (debugger));
2408 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2410 debugger_queue_command (debugger, "-exec-finish", 0, NULL, NULL, NULL);
2413 void
2414 debugger_stepi_in (Debugger *debugger)
2416 DEBUG_PRINT ("%s", "In function: debugger_step_in()");
2418 g_return_if_fail (IS_DEBUGGER (debugger));
2419 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2421 debugger_queue_command (debugger, "-exec-step-instruction", 0, NULL, NULL, NULL);
2424 void
2425 debugger_stepi_over (Debugger *debugger)
2427 DEBUG_PRINT ("%s", "In function: debugger_step_over()");
2429 g_return_if_fail (IS_DEBUGGER (debugger));
2430 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2432 debugger_queue_command (debugger, "-exec-next-instruction", 0, NULL, NULL, NULL);
2435 void
2436 debugger_run_to_location (Debugger *debugger, const gchar *loc)
2438 gchar *buff;
2440 DEBUG_PRINT ("%s", "In function: debugger_run_to_location()");
2442 g_return_if_fail (IS_DEBUGGER (debugger));
2443 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2445 buff = g_strdup_printf ("-exec-until %s", loc);
2446 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2447 g_free (buff);
2450 void
2451 debugger_run_to_position (Debugger *debugger, const gchar *file, guint line)
2453 gchar *buff;
2454 gchar *quoted_file;
2456 DEBUG_PRINT ("%s", "In function: debugger_run_to_position()");
2458 g_return_if_fail (IS_DEBUGGER (debugger));
2459 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2461 quoted_file = gdb_quote (file);
2462 buff = g_strdup_printf ("-break-insert -t %s \"\\\"%s\\\":%u\"",
2463 debugger->priv->has_pending_breakpoints ? "-f" : "",
2464 quoted_file, line);
2465 g_free (quoted_file);
2466 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2467 g_free (buff);
2468 debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2471 void
2472 debugger_run_from_position (Debugger *debugger, const gchar *file, guint line)
2474 gchar *buff;
2475 gchar *quoted_file;
2477 DEBUG_PRINT ("%s", "In function: debugger_run_from_position()");
2479 g_return_if_fail (IS_DEBUGGER (debugger));
2480 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2482 quoted_file = gdb_quote (file);
2483 buff = g_strdup_printf ("-exec-jump \"\\\"%s\\\":%u\"",
2484 quoted_file, line);
2485 g_free (quoted_file);
2486 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2487 g_free (buff);
2490 void
2491 debugger_run_to_address (Debugger *debugger, gulong address)
2493 gchar *buff;
2495 DEBUG_PRINT ("%s", "In function: debugger_run_to_address()");
2497 g_return_if_fail (IS_DEBUGGER (debugger));
2498 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2500 buff = g_strdup_printf ("-break-insert -t %s *0x%lx",
2501 debugger->priv->has_pending_breakpoints ? "-f" : "",
2502 address);
2503 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2504 g_free (buff);
2505 debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2508 void
2509 debugger_run_from_address (Debugger *debugger, gulong address)
2511 gchar *buff;
2513 DEBUG_PRINT ("%s", "In function: debugger_run_from_address()");
2515 g_return_if_fail (IS_DEBUGGER (debugger));
2516 g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2518 buff = g_strdup_printf ("-exec-jump *0x%lx", address);
2519 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2520 g_free (buff);
2523 void
2524 debugger_command (Debugger *debugger, const gchar *command,
2525 gboolean suppress_error, DebuggerParserFunc parser,
2526 gpointer user_data)
2528 if (strncasecmp (command, "-exec-run",
2529 strlen ("-exec-run")) == 0 ||
2530 strncasecmp (command, "run", strlen ("run")) == 0)
2532 /* FIXME: The user might have passed args to the command */
2533 debugger_run (debugger);
2535 else if (strncasecmp (command, "-exec-step",
2536 strlen ("-exec-step")) == 0 ||
2537 strncasecmp (command, "step", strlen ("step")) == 0)
2539 debugger_step_in (debugger);
2541 else if (strncasecmp (command, "-exec-next",
2542 strlen ("-exec-next")) == 0 ||
2543 strncasecmp (command, "next", strlen ("next")) == 0)
2545 debugger_step_over (debugger);
2547 else if (strncasecmp (command, "-exec-finish",
2548 strlen ("-exec-finish")) == 0 ||
2549 strncasecmp (command, "finish", strlen ("finish")) == 0)
2551 debugger_step_out (debugger);
2553 else if (strncasecmp (command, "-exec-continue",
2554 strlen ("-exec-continue")) == 0 ||
2555 strncasecmp (command, "continue", strlen ("continue")) == 0)
2557 debugger_run (debugger);
2559 else if (strncasecmp (command, "-exec-until",
2560 strlen ("-exec-until")) == 0 ||
2561 strncasecmp (command, "until", strlen ("until")) == 0)
2563 debugger_run_to_location (debugger, strchr (command, ' '));
2565 else if (strncasecmp (command, "-exec-abort",
2566 strlen ("-exec-abort")) == 0 ||
2567 strncasecmp (command, "kill", strlen ("kill")) == 0)
2569 debugger_stop_program (debugger);
2571 else if (strncasecmp (command, "-target-attach",
2572 strlen ("-target-attach")) == 0 ||
2573 strncasecmp (command, "attach", strlen ("attach")) == 0)
2575 pid_t pid = 0;
2576 gchar *pid_str = strchr (command, ' ');
2577 if (pid_str)
2578 pid = atoi (pid_str);
2579 debugger_attach_process (debugger, pid);
2581 else if (strncasecmp (command, "-target-detach",
2582 strlen ("-target-detach")) == 0 ||
2583 strncasecmp (command, "detach", strlen ("detach")) == 0)
2585 debugger_detach_process (debugger);
2587 else if (strncasecmp (command, "-file-exec-and-symbols",
2588 strlen ("-file-exec-and-symbols")) == 0 ||
2589 strncasecmp (command, "file", strlen ("file")) == 0)
2591 debugger_load_executable (debugger, strchr (command, ' '));
2593 else if (strncasecmp (command, "core", strlen ("core")) == 0)
2595 debugger_load_core (debugger, strchr (command, ' '));
2597 else
2599 debugger_queue_command (debugger, command, suppress_error ? DEBUGGER_COMMAND_NO_ERROR : 0,
2600 parser, user_data, NULL);
2604 static void
2605 debugger_add_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2607 IAnjutaDebuggerBreakpointItem bp;
2608 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2609 gpointer user_data = debugger->priv->current_cmd.user_data;
2611 if ((error != NULL) || (mi_results == NULL))
2613 /* Call callback in all case (useful for enable that doesn't return
2614 * anything */
2615 if (callback != NULL)
2616 callback (NULL, user_data, error);
2618 else if (callback != NULL)
2620 const GDBMIValue *brkpnt;
2622 brkpnt = gdbmi_value_hash_lookup (mi_results, "bkpt");
2623 parse_breakpoint (&bp, brkpnt);
2625 /* Call callback in all case (useful for enable that doesn't return
2626 * anything */
2627 callback (&bp, user_data, error);
2632 void
2633 debugger_add_breakpoint_at_line (Debugger *debugger, const gchar *file, guint line, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2635 gchar *buff;
2636 gchar *quoted_file;
2638 DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2640 g_return_if_fail (IS_DEBUGGER (debugger));
2642 quoted_file = gdb_quote (file);
2643 buff = g_strdup_printf ("-break-insert %s \"\\\"%s\\\":%u\"",
2644 debugger->priv->has_pending_breakpoints ? "-f" : "",
2645 quoted_file, line);
2646 g_free (quoted_file);
2647 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2648 g_free (buff);
2651 void
2652 debugger_add_breakpoint_at_function (Debugger *debugger, const gchar *file, const gchar *function, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2654 gchar *buff;
2655 gchar *quoted_file;
2657 DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2659 g_return_if_fail (IS_DEBUGGER (debugger));
2661 quoted_file = file == NULL ? NULL : gdb_quote (file);
2662 buff = g_strdup_printf ("-break-insert %s %s%s%s%s%s",
2663 debugger->priv->has_pending_breakpoints ? "-f" : "",
2664 file == NULL ? "" : "\"\\\"",
2665 file == NULL ? "" : quoted_file,
2666 file == NULL ? "" : "\\\":" ,
2667 function,
2668 file == NULL ? "" : "\"");
2669 g_free (quoted_file);
2670 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2671 g_free (buff);
2674 void
2675 debugger_add_breakpoint_at_address (Debugger *debugger, gulong address, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2677 gchar *buff;
2679 DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2681 g_return_if_fail (IS_DEBUGGER (debugger));
2683 buff = g_strdup_printf ("-break-insert %s *0x%lx",
2684 debugger->priv->has_pending_breakpoints ? "-f" : "",
2685 address);
2686 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2687 g_free (buff);
2690 void
2691 debugger_enable_breakpoint (Debugger *debugger, guint id, gboolean enable, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2694 gchar *buff;
2696 DEBUG_PRINT ("%s", "In function: debugger_enable_breakpoint()");
2698 g_return_if_fail (IS_DEBUGGER (debugger));
2700 buff = g_strdup_printf (enable ? "-break-enable %d" : "-break-disable %d",id);
2701 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2702 g_free (buff);
2705 void
2706 debugger_ignore_breakpoint (Debugger *debugger, guint id, guint ignore, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2708 gchar *buff;
2710 DEBUG_PRINT ("%s", "In function: debugger_ignore_breakpoint()");
2712 g_return_if_fail (IS_DEBUGGER (debugger));
2714 buff = g_strdup_printf ("-break-after %d %d", id, ignore);
2715 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2716 g_free (buff);
2719 void
2720 debugger_condition_breakpoint (Debugger *debugger, guint id, const gchar *condition, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2722 gchar *buff;
2724 DEBUG_PRINT ("%s", "In function: debugger_ignore_breakpoint()");
2726 g_return_if_fail (IS_DEBUGGER (debugger));
2728 buff = g_strdup_printf ("-break-condition %d %s", id, condition == NULL ? "" : condition);
2729 debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2730 g_free (buff);
2733 static void
2734 debugger_remove_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2736 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2737 gpointer user_data = debugger->priv->current_cmd.user_data;
2738 IAnjutaDebuggerBreakpointItem bp;
2740 bp.type = IANJUTA_DEBUGGER_BREAKPOINT_REMOVED;
2741 bp.id = atoi (debugger->priv->current_cmd.cmd + 14);
2742 if (callback != NULL)
2743 callback (&bp, user_data, NULL);
2746 void
2747 debugger_remove_breakpoint (Debugger *debugger, guint id, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2749 gchar *buff;
2751 DEBUG_PRINT ("%s", "In function: debugger_delete_breakpoint()");
2753 g_return_if_fail (IS_DEBUGGER (debugger));
2755 buff = g_strdup_printf ("-break-delete %d", id);
2756 debugger_queue_command (debugger, buff, 0, debugger_remove_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2757 g_free (buff);
2760 static void
2761 debugger_list_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2763 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2764 gpointer user_data = debugger->priv->current_cmd.user_data;
2765 IAnjutaDebuggerBreakpointItem* bp;
2766 const GDBMIValue *table;
2767 GList *list = NULL;
2769 if ((error != NULL) || (mi_results == NULL))
2771 /* Call callback in all case (useful for enable that doesn't return
2772 * anything */
2773 if (callback != NULL)
2774 callback (NULL, user_data, error);
2777 table = gdbmi_value_hash_lookup (mi_results, "BreakpointTable");
2778 if (table)
2780 table = gdbmi_value_hash_lookup (table, "body");
2782 if (table)
2784 int i;
2786 for (i = 0; i < gdbmi_value_get_size (table); i++)
2788 const GDBMIValue *brkpnt;
2790 bp = g_new0 (IAnjutaDebuggerBreakpointItem, 1);
2792 brkpnt = gdbmi_value_list_get_nth (table, i);
2793 parse_breakpoint(bp, brkpnt);
2794 list = g_list_prepend (list, bp);
2799 /* Call callback in all case (useful for enable that doesn't return
2800 * anything */
2801 if (callback != NULL)
2803 list = g_list_reverse (list);
2804 callback (list, user_data, error);
2807 g_list_foreach (list, (GFunc)g_free, NULL);
2808 g_list_free (list);
2811 void
2812 debugger_list_breakpoint (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
2814 DEBUG_PRINT ("%s", "In function: debugger_list_breakpoint()");
2816 g_return_if_fail (IS_DEBUGGER (debugger));
2818 debugger_queue_command (debugger, "-break-list", 0, debugger_list_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2821 static void
2822 debugger_print_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2824 gchar *ptr = NULL;
2825 gchar *tmp;
2826 GList *list, *node;
2827 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2828 gpointer user_data = debugger->priv->current_cmd.user_data;
2831 list = gdb_util_remove_blank_lines (cli_results);
2832 if (g_list_length (list) < 1)
2834 tmp = NULL;
2836 else
2838 tmp = strchr ((gchar *) list->data, '=');
2840 if (tmp != NULL)
2842 ptr = g_strdup (tmp);
2843 for (node = list ? list->next : NULL; node != NULL; node = node->next)
2845 tmp = ptr;
2846 ptr = g_strconcat (tmp, (gchar *) node->data, NULL);
2847 g_free (tmp);
2851 callback (ptr, user_data, NULL);
2852 g_free (ptr);
2855 void
2856 debugger_print (Debugger *debugger, const gchar* variable, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
2858 gchar *buff;
2860 DEBUG_PRINT ("%s", "In function: debugger_print()");
2862 g_return_if_fail (IS_DEBUGGER (debugger));
2864 buff = g_strdup_printf ("print %s", variable);
2865 debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_print_finish, (IAnjutaDebuggerCallback)callback, user_data);
2866 g_free (buff);
2869 static void
2870 debugger_evaluate_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2873 const GDBMIValue *value = NULL;
2874 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2875 gpointer user_data = debugger->priv->current_cmd.user_data;
2877 if (mi_results)
2878 value = gdbmi_value_hash_lookup (mi_results, "value");
2880 /* Call user function */
2881 if (callback != NULL)
2882 callback (value == NULL ? "?" : (char *)gdbmi_value_literal_get (value), user_data, NULL);
2885 void
2886 debugger_evaluate (Debugger *debugger, const gchar* name, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
2888 gchar *buff;
2889 DEBUG_PRINT ("%s", "In function: debugger_add_watch()");
2891 g_return_if_fail (IS_DEBUGGER (debugger));
2893 buff = g_strdup_printf ("-data-evaluate-expression %s", name);
2894 debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_evaluate_finish, (IAnjutaDebuggerCallback)callback, user_data);
2895 g_free (buff);
2898 static void
2899 debugger_list_local_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2902 const GDBMIValue *local, *var, *frame, *args, *stack;
2903 const gchar * name;
2904 GList* list;
2905 guint i;
2906 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2907 gpointer user_data = debugger->priv->current_cmd.user_data;
2910 list = NULL;
2911 /* Add arguments */
2912 stack = gdbmi_value_hash_lookup (mi_results, "stack-args");
2913 if (stack)
2915 frame = gdbmi_value_list_get_nth (stack, 0);
2916 if (frame)
2918 args = gdbmi_value_hash_lookup (frame, "args");
2919 if (args)
2921 for (i = 0; i < gdbmi_value_get_size (args); i++)
2923 var = gdbmi_value_list_get_nth (args, i);
2924 if (var)
2926 name = gdbmi_value_literal_get (var);
2927 list = g_list_prepend (list, (gchar *)name);
2935 /* List local variables */
2936 local = gdbmi_value_hash_lookup (mi_results, "locals");
2937 if (local)
2939 for (i = 0; i < gdbmi_value_get_size (local); i++)
2941 var = gdbmi_value_list_get_nth (local, i);
2942 if (var)
2944 name = gdbmi_value_literal_get (var);
2945 list = g_list_prepend (list, (gchar *)name);
2949 list = g_list_reverse (list);
2950 callback (list, user_data, NULL);
2951 g_list_free (list);
2954 void
2955 debugger_list_local (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
2957 gchar *buff;
2958 DEBUG_PRINT ("%s", "In function: debugger_list_local()");
2960 g_return_if_fail (IS_DEBUGGER (debugger));
2962 buff = g_strdup_printf("-stack-list-arguments 0 %d %d", debugger->priv->current_frame, debugger->priv->current_frame);
2963 debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR | DEBUGGER_COMMAND_KEEP_RESULT, NULL, NULL, NULL);
2964 g_free (buff);
2965 debugger_queue_command (debugger, "-stack-list-locals 0", DEBUGGER_COMMAND_NO_ERROR, debugger_list_local_finish, (IAnjutaDebuggerCallback)callback, user_data);
2968 static void
2969 debugger_list_argument_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2972 const GDBMIValue *frame, *var, *args, *stack;
2973 const gchar * name;
2974 GList* list;
2975 guint i;
2976 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2977 gpointer user_data = debugger->priv->current_cmd.user_data;
2980 list = NULL;
2981 args = NULL;
2982 stack = gdbmi_value_hash_lookup (mi_results, "stack-args");
2983 if (stack)
2985 frame = gdbmi_value_list_get_nth (stack, 0);
2986 if (frame)
2988 args = gdbmi_value_hash_lookup (frame, "args");
2992 if (args)
2994 for (i = 0; i < gdbmi_value_get_size (args); i++)
2996 var = gdbmi_value_list_get_nth (args, i);
2997 if (var)
2999 name = gdbmi_value_literal_get (var);
3000 list = g_list_prepend (list, (gchar *)name);
3004 list = g_list_reverse (list);
3005 callback (list, user_data, NULL);
3006 g_list_free (list);
3009 void
3010 debugger_list_argument (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3012 gchar *buff;
3014 DEBUG_PRINT ("%s", "In function: debugger_list_argument()");
3016 g_return_if_fail (IS_DEBUGGER (debugger));
3018 buff = g_strdup_printf("-stack-list-arguments 0 %d %d", debugger->priv->current_frame, debugger->priv->current_frame);
3019 debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_list_argument_finish, (IAnjutaDebuggerCallback)callback, user_data);
3020 g_free (buff);
3023 static void
3024 debugger_info_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3027 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3028 gpointer user_data = debugger->priv->current_cmd.user_data;
3030 if (callback != NULL)
3031 callback ((GList *)cli_results, user_data, NULL);
3034 void
3035 debugger_info_signal (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3037 DEBUG_PRINT ("%s", "In function: debugger_info_signal()");
3039 g_return_if_fail (IS_DEBUGGER (debugger));
3041 debugger_queue_command (debugger, "info signals", DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_info_finish, (IAnjutaDebuggerCallback)callback, user_data);
3044 void
3045 debugger_info_sharedlib (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3047 gchar *buff;
3049 DEBUG_PRINT ("%s", "In function: debugger_info_sharedlib()");
3051 g_return_if_fail (IS_DEBUGGER (debugger));
3053 buff = g_strdup_printf ("info sharedlib");
3054 debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_info_finish, (IAnjutaDebuggerCallback)callback, user_data); g_free (buff);
3057 static void
3058 debugger_read_memory_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3061 const GDBMIValue *literal;
3062 const GDBMIValue *mem;
3063 const gchar *value;
3064 gchar *data;
3065 gchar *ptr;
3066 gulong address;
3067 guint len;
3068 guint i;
3069 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3070 gpointer user_data = debugger->priv->current_cmd.user_data;
3071 IAnjutaDebuggerMemoryBlock read = {0,};
3073 literal = gdbmi_value_hash_lookup (mi_results, "total-bytes");
3074 if (literal)
3076 guint size;
3078 len = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3079 data = g_new (gchar, len * 2);
3080 memset (data + len, 0, len);
3082 literal = gdbmi_value_hash_lookup (mi_results, "addr");
3083 address = strtoul (gdbmi_value_literal_get (literal), NULL, 0);
3085 ptr = data;
3086 size = 0;
3087 mem = gdbmi_value_hash_lookup (mi_results, "memory");
3088 if (mem)
3090 mem = gdbmi_value_list_get_nth (mem, 0);
3091 if (mem)
3093 mem = gdbmi_value_hash_lookup (mem, "data");
3094 if (mem)
3096 size = gdbmi_value_get_size (mem);
3101 if (size < len) len = size;
3102 for (i = 0; i < len; i++)
3104 literal = gdbmi_value_list_get_nth (mem, i);
3105 if (literal)
3107 gchar *endptr;
3108 value = gdbmi_value_literal_get (literal);
3109 *ptr = strtoul (value, &endptr, 16);
3110 if ((*value != '\0') && (*endptr == '\0'))
3112 /* valid data */
3113 ptr[len] = 1;
3115 ptr++;
3118 read.address = address;
3119 read.length = len;
3120 read.data = data;
3121 callback (&read, user_data, NULL);
3123 g_free (data);
3125 else
3127 callback (NULL, user_data, NULL);
3131 void
3132 debugger_inspect_memory (Debugger *debugger, gulong address, guint length, IAnjutaDebuggerMemoryCallback callback, gpointer user_data)
3134 gchar *buff;
3136 DEBUG_PRINT ("%s", "In function: debugger_inspect_memory()");
3138 g_return_if_fail (IS_DEBUGGER (debugger));
3140 buff = g_strdup_printf ("-data-read-memory 0x%lx x 1 1 %d", address, length);
3141 debugger_queue_command (debugger, buff, 0, debugger_read_memory_finish, (IAnjutaDebuggerCallback)callback, user_data);
3142 g_free (buff);
3145 static void
3146 debugger_disassemble_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3149 const GDBMIValue *literal;
3150 const GDBMIValue *line;
3151 const GDBMIValue *mem;
3152 const gchar *value;
3153 guint i;
3154 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3155 gpointer user_data = debugger->priv->current_cmd.user_data;
3156 IAnjutaDebuggerInstructionDisassembly *read = NULL;
3158 if (error != NULL)
3160 /* Command fail */
3161 callback (NULL, user_data, error);
3163 return;
3167 mem = gdbmi_value_hash_lookup (mi_results, "asm_insns");
3168 if (mem)
3170 guint size;
3172 size = gdbmi_value_get_size (mem);
3173 read = (IAnjutaDebuggerInstructionDisassembly *)g_malloc0(sizeof (IAnjutaDebuggerInstructionDisassembly) + sizeof(IAnjutaDebuggerInstructionALine) * size);
3174 read->size = size;
3176 for (i = 0; i < size; i++)
3178 line = gdbmi_value_list_get_nth (mem, i);
3179 if (line)
3181 /* Get address */
3182 literal = gdbmi_value_hash_lookup (line, "address");
3183 if (literal)
3185 value = gdbmi_value_literal_get (literal);
3186 read->data[i].address = strtoul (value, NULL, 0);
3189 /* Get label if one exist */
3190 literal = gdbmi_value_hash_lookup (line, "offset");
3191 if (literal)
3193 value = gdbmi_value_literal_get (literal);
3194 if ((value != NULL) && (strtoul (value, NULL, 0) == 0))
3196 literal = gdbmi_value_hash_lookup (line, "func-name");
3197 if (literal)
3199 read->data[i].label = gdbmi_value_literal_get (literal);
3206 /* Get disassembly line */
3207 literal = gdbmi_value_hash_lookup (line, "inst");
3208 if (literal)
3210 read->data[i].text = gdbmi_value_literal_get (literal);
3215 /* Remove last line to mark end */
3216 read->data[i - 1].text = NULL;
3218 callback (read, user_data, NULL);
3220 g_free (read);
3222 else
3224 callback (NULL, user_data, NULL);
3228 void
3229 debugger_disassemble (Debugger *debugger, gulong address, guint length, IAnjutaDebuggerInstructionCallback callback, gpointer user_data)
3231 gchar *buff;
3232 gulong end;
3234 DEBUG_PRINT ("%s", "In function: debugger_disassemble()");
3236 g_return_if_fail (IS_DEBUGGER (debugger));
3239 /* Handle overflow */
3240 end = (address + length < address) ? G_MAXULONG : address + length;
3241 buff = g_strdup_printf ("-data-disassemble -s 0x%lx -e 0x%lx -- 0", address, end);
3242 debugger_queue_command (debugger, buff, 0, debugger_disassemble_finish, (IAnjutaDebuggerCallback)callback, user_data);
3243 g_free (buff);
3246 static void
3247 parse_frame (IAnjutaDebuggerFrame *frame, const GDBMIValue *frame_hash)
3249 const GDBMIValue *literal;
3251 literal = gdbmi_value_hash_lookup (frame_hash, "level");
3252 if (literal)
3253 frame->level = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3254 else
3255 frame->level = 0;
3258 frame->file = (gchar *)debugger_parse_filename (frame_hash);
3260 literal = gdbmi_value_hash_lookup (frame_hash, "line");
3261 if (literal)
3262 frame->line = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3263 else
3264 frame->line = 0;
3266 literal = gdbmi_value_hash_lookup (frame_hash, "func");
3267 if (literal)
3268 frame->function = (gchar *)gdbmi_value_literal_get (literal);
3269 else
3270 frame->function = NULL;
3272 literal = gdbmi_value_hash_lookup (frame_hash, "from");
3273 if (literal)
3274 frame->library = (gchar *)gdbmi_value_literal_get (literal);
3275 else
3276 frame->library = NULL;
3278 literal = gdbmi_value_hash_lookup (frame_hash, "addr");
3279 if (literal)
3280 frame->address = strtoul (gdbmi_value_literal_get (literal), NULL, 16);
3281 else
3282 frame->address = 0;
3287 static void
3288 add_frame (const GDBMIValue *frame_hash, GdbGListPacket* pack)
3290 IAnjutaDebuggerFrame* frame;
3292 frame = g_new0 (IAnjutaDebuggerFrame, 1);
3293 pack->list = g_list_prepend (pack->list, frame);
3295 frame->thread = pack->tag;
3296 parse_frame (frame, frame_hash);
3299 static void
3300 set_func_args (const GDBMIValue *frame_hash, GList** node)
3302 const gchar *level;
3303 const GDBMIValue *literal, *args_list, *arg_hash;
3304 gint i;
3305 GString *args_str;
3306 IAnjutaDebuggerFrame* frame;
3308 literal = gdbmi_value_hash_lookup (frame_hash, "level");
3309 if (!literal)
3310 return;
3312 level = gdbmi_value_literal_get (literal);
3313 if (!level)
3314 return;
3316 frame = (IAnjutaDebuggerFrame *)(*node)->data;
3318 args_list = gdbmi_value_hash_lookup (frame_hash, "args");
3319 if (args_list)
3321 args_str = g_string_new ("(");
3322 for (i = 0; i < gdbmi_value_get_size (args_list); i++)
3324 const gchar *name, *value;
3326 arg_hash = gdbmi_value_list_get_nth (args_list, i);
3327 if (!arg_hash)
3328 continue;
3330 literal = gdbmi_value_hash_lookup (arg_hash, "name");
3331 if (!literal)
3332 continue;
3333 name = gdbmi_value_literal_get (literal);
3334 if (!name)
3335 continue;
3337 literal = gdbmi_value_hash_lookup (arg_hash, "value");
3338 if (!literal)
3339 continue;
3340 value = gdbmi_value_literal_get (literal);
3341 if (!value)
3342 continue;
3343 args_str = g_string_append (args_str, name);
3344 args_str = g_string_append (args_str, "=");
3345 args_str = g_string_append (args_str, value);
3346 if (i < (gdbmi_value_get_size (args_list) - 1))
3347 args_str = g_string_append (args_str, ", ");
3349 args_str = g_string_append (args_str, ")");
3350 frame->args = args_str->str;
3351 g_string_free (args_str, FALSE);
3353 *node = g_list_next (*node);
3356 static void
3357 debugger_stack_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3360 GdbGListPacket pack = {NULL, 0};
3361 GList* node;
3362 const GDBMIValue *stack_list;
3363 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3364 gpointer user_data = debugger->priv->current_cmd.user_data;
3366 if (!mi_results)
3367 return;
3369 stack_list = gdbmi_value_hash_lookup (mi_results, "stack");
3370 if (stack_list)
3372 pack.tag = debugger->priv->current_thread;
3373 gdbmi_value_foreach (stack_list, (GFunc)add_frame, &pack);
3376 if (pack.list)
3378 pack.list = g_list_reverse (pack.list);
3379 node = g_list_first (pack.list);
3380 stack_list = gdbmi_value_hash_lookup (mi_results, "stack-args");
3381 if (stack_list)
3382 gdbmi_value_foreach (stack_list, (GFunc)set_func_args, &node);
3384 // Call call back function
3385 if (callback != NULL)
3386 callback (pack.list, user_data, NULL);
3388 // Free data
3389 for (node = g_list_first (pack.list); node != NULL; node = g_list_next (node))
3391 g_free ((gchar *)((IAnjutaDebuggerFrame *)node->data)->args);
3392 g_free (node->data);
3395 g_list_free (pack.list);
3397 else
3399 // Call call back function
3400 if (callback != NULL)
3401 callback (NULL, user_data, NULL);
3405 void
3406 debugger_list_frame (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3408 DEBUG_PRINT ("%s", "In function: debugger_list_frame()");
3410 g_return_if_fail (IS_DEBUGGER (debugger));
3412 debugger_queue_command (debugger, "-stack-list-frames", DEBUGGER_COMMAND_NO_ERROR | DEBUGGER_COMMAND_KEEP_RESULT, NULL, NULL, NULL);
3413 debugger_queue_command (debugger, "-stack-list-arguments 1", DEBUGGER_COMMAND_NO_ERROR, debugger_stack_finish, (IAnjutaDebuggerCallback)callback, user_data);
3416 static void
3417 debugger_dump_stack_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3419 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3420 gpointer user_data = debugger->priv->current_cmd.user_data;
3422 if (callback != NULL)
3424 GString *result;
3425 GList *item;
3427 result = g_string_new (NULL);
3429 for (item = g_list_first ((GList *)cli_results); item != NULL; item = g_list_next (item))
3431 const gchar *line = (const gchar *)item->data;
3433 /* Keep only data outputed by CLI command */
3434 if (*line == '~')
3436 g_string_append (result, line + 1);
3440 callback (result->str, user_data, NULL);
3442 g_string_free (result, TRUE);
3446 void debugger_dump_stack_trace (Debugger *debugger, IAnjutaDebuggerGListCallback func, gpointer user_data)
3448 DEBUG_PRINT ("%s", "In function: debugger_dump_stack_frame()");
3450 g_return_if_fail (IS_DEBUGGER (debugger));
3452 debugger_queue_command (debugger, "thread apply all backtrace", DEBUGGER_COMMAND_NO_ERROR, debugger_dump_stack_finish, (IAnjutaDebuggerCallback)func, user_data);
3455 /* Thread functions
3456 *---------------------------------------------------------------------------*/
3458 static void
3459 debugger_set_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3461 const GDBMIValue *literal;
3462 guint id;
3464 if (mi_results == NULL) return;
3466 literal = gdbmi_value_hash_lookup (mi_results, "new-thread-id");
3467 if (literal == NULL) return;
3469 id = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3470 if (id == 0) return;
3472 debugger->priv->current_thread = id;
3473 g_signal_emit_by_name (debugger->priv->instance, "frame-changed", 0, debugger->priv->current_thread);
3475 return;
3478 void
3479 debugger_set_thread (Debugger *debugger, gint thread)
3481 gchar *buff;
3483 DEBUG_PRINT ("%s", "In function: debugger_set_thread()");
3485 g_return_if_fail (IS_DEBUGGER (debugger));
3487 buff = g_strdup_printf ("-thread-select %d", thread);
3489 debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_set_thread_finish, NULL, NULL);
3490 g_free (buff);
3493 static void
3494 add_thread_id (const GDBMIValue *thread_hash, GList** list)
3496 IAnjutaDebuggerFrame* frame;
3497 gint thread;
3499 thread = strtoul (gdbmi_value_literal_get (thread_hash), NULL, 10);
3500 if (thread == 0) return;
3502 frame = g_new0 (IAnjutaDebuggerFrame, 1);
3503 *list = g_list_prepend (*list, frame);
3505 frame->thread = thread;
3508 static void
3509 debugger_list_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3512 const GDBMIValue *id_list;
3513 gpointer user_data = debugger->priv->current_cmd.user_data;
3514 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3515 GList* thread_list = NULL;
3517 for (;;)
3519 if (mi_results == NULL) break;
3521 id_list = gdbmi_value_hash_lookup (mi_results, "thread-ids");
3522 if (id_list == NULL) break;
3524 gdbmi_value_foreach (id_list, (GFunc)add_thread_id, &thread_list);
3525 thread_list = g_list_reverse (thread_list);
3526 break;
3529 if (callback != NULL)
3530 callback (thread_list, user_data, error);
3532 if (thread_list != NULL)
3534 g_list_foreach (thread_list, (GFunc)g_free, NULL);
3535 g_list_free (thread_list);
3539 void
3540 debugger_list_thread (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3542 DEBUG_PRINT ("%s", "In function: debugger_list_thread()");
3544 g_return_if_fail (IS_DEBUGGER (debugger));
3546 debugger_queue_command (debugger, "-thread-list-ids", DEBUGGER_COMMAND_NO_ERROR, debugger_list_thread_finish, (IAnjutaDebuggerCallback)callback, user_data);
3549 static void
3550 debugger_info_set_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3552 const GDBMIValue *literal;
3553 guint id;
3555 if (mi_results == NULL) return;
3557 literal = gdbmi_value_hash_lookup (mi_results, "new-thread-id");
3558 if (literal == NULL) return;
3560 id = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3561 if (id == 0) return;
3563 debugger->priv->current_thread = id;
3564 /* Do not emit a signal notification as the current thread will
3565 * be restored when needed */
3567 return;
3570 static void
3571 debugger_info_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3573 const GDBMIValue *frame;
3574 IAnjutaDebuggerFrame top_frame;
3575 IAnjutaDebuggerFrame *top;
3576 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3577 gpointer user_data = debugger->priv->current_cmd.user_data;
3579 for (top = NULL;;)
3581 DEBUG_PRINT("look for stack %p", mi_results);
3582 if (mi_results == NULL) break;
3584 frame = gdbmi_value_hash_lookup (mi_results, "stack");
3585 if (frame == NULL) break;
3587 DEBUG_PRINT("%s", "get stack");
3589 frame = gdbmi_value_list_get_nth (frame, 0);
3590 if (frame == NULL) break;
3592 DEBUG_PRINT("%s", "get nth element");
3594 /*frame = gdbmi_value_hash_lookup (frame, "frame");
3595 DEBUG_PRINT("get frame %p", frame);
3596 if (frame == NULL) break;*/
3598 DEBUG_PRINT("%s", "get frame");
3600 top = &top_frame;
3601 top->thread = debugger->priv->current_thread;
3603 parse_frame (top, frame);
3604 break;
3607 if (callback != NULL)
3608 callback (top, user_data, error);
3610 return;
3613 void
3614 debugger_info_thread (Debugger *debugger, gint thread, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3616 gchar *buff;
3617 guint orig_thread;
3619 DEBUG_PRINT ("%s", "In function: debugger_info_thread()");
3621 g_return_if_fail (IS_DEBUGGER (debugger));
3623 orig_thread = debugger->priv->current_thread;
3624 buff = g_strdup_printf ("-thread-select %d", thread);
3625 debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_info_set_thread_finish, NULL, NULL);
3626 g_free (buff);
3627 debugger_queue_command (debugger, "-stack-list-frames 0 0", 0, (DebuggerParserFunc)debugger_info_thread_finish, (IAnjutaDebuggerCallback)callback, user_data);
3629 buff = g_strdup_printf ("-thread-select %d", orig_thread);
3630 debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_info_set_thread_finish, NULL, NULL);
3631 g_free (buff);
3634 static void
3635 add_register_name (const GDBMIValue *reg_literal, GList** list)
3637 IAnjutaDebuggerRegisterData* reg;
3638 GList *prev = *list;
3640 reg = g_new0 (IAnjutaDebuggerRegisterData, 1);
3641 *list = g_list_prepend (prev, reg);
3642 reg->name = (gchar *)gdbmi_value_literal_get (reg_literal);
3643 reg->num = prev == NULL ? 0 : ((IAnjutaDebuggerRegisterData *)prev->data)->num + 1;
3646 static void
3647 add_register_value (const GDBMIValue *reg_hash, GList** list)
3649 const GDBMIValue *literal;
3650 const gchar *val;
3651 IAnjutaDebuggerRegisterData* reg;
3652 guint num;
3653 GList* prev = *list;
3655 literal = gdbmi_value_hash_lookup (reg_hash, "number");
3656 if (!literal)
3657 return;
3658 val = gdbmi_value_literal_get (literal);
3659 num = strtoul (val, NULL, 10);
3661 literal = gdbmi_value_hash_lookup (reg_hash, "value");
3662 if (!literal)
3663 return;
3665 reg = g_new0 (IAnjutaDebuggerRegisterData, 1);
3666 *list = g_list_prepend (prev, reg);
3667 reg->num = num;
3668 reg->value = (gchar *)gdbmi_value_literal_get (literal);
3671 static void
3672 debugger_register_name_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3675 GList* list = NULL;
3676 GList* node;
3677 const GDBMIValue *reg_list;
3678 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3679 gpointer user_data = debugger->priv->current_cmd.user_data;
3681 if (!mi_results)
3682 return;
3684 reg_list = gdbmi_value_hash_lookup (mi_results, "register-names");
3685 if (reg_list)
3686 gdbmi_value_foreach (reg_list, (GFunc)add_register_name, &list);
3687 list = g_list_reverse (list);
3689 // Call call back function
3690 if (callback != NULL)
3691 callback (list, user_data, NULL);
3693 // Free data
3694 for (node = g_list_first (list); node != NULL; node = g_list_next (node))
3696 g_free (node->data);
3698 g_list_free (list);
3701 static void
3702 debugger_register_value_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3705 GList* list = NULL;
3706 GList* node;
3707 const GDBMIValue *reg_list;
3708 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3709 gpointer user_data = debugger->priv->current_cmd.user_data;
3711 if (!mi_results)
3712 return;
3714 reg_list = gdbmi_value_hash_lookup (mi_results, "register-values");
3715 if (reg_list)
3716 gdbmi_value_foreach (reg_list, (GFunc)add_register_value, &list);
3717 list = g_list_reverse (list);
3719 // Call call back function
3720 if (callback != NULL)
3721 callback (list, user_data, NULL);
3723 // Free data
3724 for (node = g_list_first (list); node != NULL; node = g_list_next (node))
3726 g_free (node->data);
3728 g_list_free (list);
3731 void
3732 debugger_list_register (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3734 DEBUG_PRINT ("%s", "In function: debugger_list_register()");
3736 g_return_if_fail (IS_DEBUGGER (debugger));
3738 debugger_queue_command (debugger, "-data-list-register-names", DEBUGGER_COMMAND_NO_ERROR, debugger_register_name_finish, (IAnjutaDebuggerCallback)callback, user_data);
3741 void
3742 debugger_update_register (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3744 DEBUG_PRINT ("%s", "In function: debugger_update_register()");
3746 g_return_if_fail (IS_DEBUGGER (debugger));
3748 debugger_queue_command (debugger, "-data-list-register-values r", DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_register_value_finish, (IAnjutaDebuggerCallback)callback, user_data);
3751 void
3752 debugger_write_register (Debugger *debugger, const gchar *name, const gchar *value)
3754 gchar *buf;
3756 DEBUG_PRINT ("%s", "In function: debugger_write_register()");
3758 g_return_if_fail (IS_DEBUGGER (debugger));
3760 buf = g_strdup_printf ("-data-evaluate-expression \"$%s=%s\"", name, value);
3761 debugger_queue_command (debugger, buf, DEBUGGER_COMMAND_NO_ERROR, NULL, NULL, NULL);
3762 g_free (buf);
3765 static void
3766 debugger_set_frame_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3769 gsize frame = (gsize)debugger->priv->current_cmd.user_data;
3770 debugger->priv->current_frame = frame;
3772 g_signal_emit_by_name (debugger->priv->instance, "frame-changed", frame, debugger->priv->current_thread);
3775 void
3776 debugger_set_frame (Debugger *debugger, gsize frame)
3778 gchar *buff;
3780 DEBUG_PRINT ("%s", "In function: debugger_set_frame()");
3782 g_return_if_fail (IS_DEBUGGER (debugger));
3784 buff = g_strdup_printf ("-stack-select-frame %" G_GSIZE_FORMAT, frame);
3786 debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_set_frame_finish, NULL, (gpointer)frame);
3787 g_free (buff);
3790 void
3791 debugger_set_log (Debugger *debugger, IAnjutaMessageView *log)
3793 debugger->priv->log = log;
3796 /* Variable objects functions
3797 *---------------------------------------------------------------------------*/
3799 void
3800 debugger_delete_variable (Debugger *debugger, const gchar* name)
3802 gchar *buff;
3804 DEBUG_PRINT ("%s", "In function: delete_variable()");
3806 g_return_if_fail (IS_DEBUGGER (debugger));
3808 buff = g_strdup_printf ("-var-delete %s", name);
3809 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
3810 g_free (buff);
3813 static void
3814 gdb_var_evaluate_expression (Debugger *debugger,
3815 const GDBMIValue *mi_results, const GList *cli_results,
3816 GError *error)
3818 const gchar *value = NULL;
3819 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3820 gpointer user_data = debugger->priv->current_cmd.user_data;
3822 if (mi_results != NULL)
3824 const GDBMIValue *const gdbmi_value =
3825 gdbmi_value_hash_lookup (mi_results, "value");
3827 if (gdbmi_value != NULL)
3828 value = gdbmi_value_literal_get (gdbmi_value);
3830 callback ((const gpointer)value, user_data, NULL);
3833 void
3834 debugger_evaluate_variable (Debugger *debugger, const gchar* name, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
3836 gchar *buff;
3838 DEBUG_PRINT ("%s", "In function: evaluate_variable()");
3840 g_return_if_fail (IS_DEBUGGER (debugger));
3842 buff = g_strdup_printf ("-var-evaluate-expression %s", name);
3843 debugger_queue_command (debugger, buff, 0, gdb_var_evaluate_expression, (IAnjutaDebuggerCallback)callback, user_data);
3844 g_free (buff);
3847 void
3848 debugger_assign_variable (Debugger *debugger, const gchar* name, const gchar *value)
3850 gchar *buff;
3852 DEBUG_PRINT ("%s", "In function: assign_variable()");
3854 g_return_if_fail (IS_DEBUGGER (debugger));
3856 buff = g_strdup_printf ("-var-assign %s %s", name, value);
3857 debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
3858 g_free (buff);
3861 static void
3862 gdb_var_list_children (Debugger *debugger,
3863 const GDBMIValue *mi_results, const GList *cli_results,
3864 GError *error)
3866 GList* list = NULL;
3867 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3868 gpointer user_data = debugger->priv->current_cmd.user_data;
3870 if (mi_results != NULL)
3872 const GDBMIValue *literal;
3873 const GDBMIValue *children;
3874 glong numchild = 0;
3875 glong i = 0;
3877 literal = gdbmi_value_hash_lookup (mi_results, "numchild");
3879 if (literal)
3880 numchild = strtoul(gdbmi_value_literal_get (literal), NULL, 0);
3881 children = gdbmi_value_hash_lookup (mi_results, "children");
3883 for(i = 0 ; i < numchild; ++i)
3885 const GDBMIValue *const gdbmi_chl =
3886 gdbmi_value_list_get_nth (children, i);
3887 IAnjutaDebuggerVariableObject *var;
3889 var = g_new0 (IAnjutaDebuggerVariableObject, 1);
3891 literal = gdbmi_value_hash_lookup (gdbmi_chl, "name");
3892 if (literal)
3893 var->name = (gchar *)gdbmi_value_literal_get (literal);
3895 literal = gdbmi_value_hash_lookup (gdbmi_chl, "exp");
3896 if (literal)
3897 var->expression = (gchar *)gdbmi_value_literal_get(literal);
3899 literal = gdbmi_value_hash_lookup (gdbmi_chl, "type");
3900 if (literal)
3901 var->type = (gchar *)gdbmi_value_literal_get(literal);
3903 literal = gdbmi_value_hash_lookup (gdbmi_chl, "value");
3904 if (literal)
3905 var->value = (gchar *)gdbmi_value_literal_get(literal);
3907 literal = gdbmi_value_hash_lookup (gdbmi_chl, "numchild");
3908 if (literal)
3909 var->children = strtoul(gdbmi_value_literal_get(literal), NULL, 10);
3911 literal = gdbmi_value_hash_lookup (gdbmi_chl, "has_more");
3912 if (literal)
3913 var->has_more = *gdbmi_value_literal_get(literal) == '1' ? TRUE : FALSE;
3915 list = g_list_prepend (list, var);
3918 literal = gdbmi_value_hash_lookup (mi_results, "has_more");
3919 if (literal && (*gdbmi_value_literal_get(literal) == '1'))
3921 /* Add a dummy children to represent additional children */
3922 IAnjutaDebuggerVariableObject *var;
3924 var = g_new0 (IAnjutaDebuggerVariableObject, 1);
3925 var->expression = _("more children");
3926 var->type = "";
3927 var->value = "";
3928 var->has_more = TRUE;
3929 list = g_list_prepend (list, var);
3932 list = g_list_reverse (list);
3935 callback (list, user_data, NULL);
3936 g_list_foreach (list, (GFunc)g_free, NULL);
3937 g_list_free (list);
3940 void debugger_list_variable_children (Debugger *debugger, const gchar* name, guint from, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3942 gchar *buff;
3944 DEBUG_PRINT ("%s", "In function: list_variable_children()");
3946 g_return_if_fail (IS_DEBUGGER (debugger));
3948 buff = g_strdup_printf ("-var-list-children --all-values %s %d %d", name, from, from + MAX_CHILDREN);
3949 debugger_queue_command (debugger, buff, 0, gdb_var_list_children, (IAnjutaDebuggerCallback)callback, user_data);
3950 g_free (buff);
3953 static void
3954 gdb_var_create (Debugger *debugger,
3955 const GDBMIValue *mi_results, const GList *cli_results,
3956 GError *error)
3958 const GDBMIValue * result;
3959 IAnjutaDebuggerVariableObject var = {0,};
3960 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3961 gpointer user_data = debugger->priv->current_cmd.user_data;
3963 if ((error == NULL) && (mi_results != NULL))
3965 result = gdbmi_value_hash_lookup (mi_results, "name");
3966 var.name = (gchar *)gdbmi_value_literal_get(result);
3968 result = gdbmi_value_hash_lookup (mi_results, "type");
3969 var.type = (gchar *)gdbmi_value_literal_get (result);
3971 result = gdbmi_value_hash_lookup (mi_results, "numchild");
3972 var.children = strtoul (gdbmi_value_literal_get(result), NULL, 10);
3974 result = gdbmi_value_hash_lookup (mi_results, "has_more");
3975 if (result != NULL)
3977 var.has_more = *gdbmi_value_literal_get(result) == '1' ? TRUE : FALSE;
3979 else
3981 var.has_more = FALSE;
3984 callback (&var, user_data, error);
3988 void debugger_create_variable (Debugger *debugger, const gchar* name, IAnjutaDebuggerVariableCallback callback, gpointer user_data)
3990 gchar *buff;
3992 DEBUG_PRINT ("%s", "In function: create_variable()");
3994 g_return_if_fail (IS_DEBUGGER (debugger));
3996 buff = g_strdup_printf ("-var-create - @ %s", name);
3997 debugger_queue_command (debugger, buff, 0, gdb_var_create, (IAnjutaDebuggerCallback)callback, user_data);
3998 g_free (buff);
4001 static void
4002 gdb_var_update (Debugger *debugger,
4003 const GDBMIValue *mi_results, const GList *cli_results,
4004 GError *error)
4006 GList* list = NULL;
4007 glong idx = 0, changed_count = 0;
4008 const GDBMIValue *const gdbmi_changelist =
4009 gdbmi_value_hash_lookup (mi_results, "changelist");
4010 IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
4011 gpointer user_data = debugger->priv->current_cmd.user_data;
4014 changed_count = gdbmi_value_get_size (gdbmi_changelist);
4015 for(; idx<changed_count; ++idx)
4017 const GDBMIValue *const gdbmi_change =
4018 gdbmi_value_list_get_nth (gdbmi_changelist, idx);
4019 const GDBMIValue * value;
4022 value = gdbmi_value_hash_lookup (gdbmi_change, "name");
4023 if (value)
4025 IAnjutaDebuggerVariableObject *var = g_new0 (IAnjutaDebuggerVariableObject, 1);
4026 var->changed = TRUE;
4027 var->name = (gchar *)gdbmi_value_literal_get(value);
4028 list = g_list_prepend (list, var);
4030 value = gdbmi_value_hash_lookup (gdbmi_change, "type_changed");
4031 if (value != NULL)
4033 const gchar *type_changed = gdbmi_value_literal_get (value);
4035 if (strcmp (type_changed, "true") == 0)
4037 var->deleted = TRUE;
4041 value = gdbmi_value_hash_lookup (gdbmi_change, "in_scope");
4042 if (value != NULL)
4044 const gchar *in_scope = gdbmi_value_literal_get(value);
4046 if (strcmp (in_scope, "false") == 0)
4048 var->exited = TRUE;
4050 else if (strcmp (in_scope, "invalid") == 0)
4052 var->deleted = TRUE;
4057 list = g_list_reverse (list);
4058 callback (list, user_data, NULL);
4059 g_list_foreach (list, (GFunc)g_free, NULL);
4060 g_list_free (list);
4063 void debugger_update_variable (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
4065 DEBUG_PRINT ("%s", "In function: update_variable()");
4067 g_return_if_fail (IS_DEBUGGER (debugger));
4069 debugger_queue_command (debugger, "-var-update *", 0, gdb_var_update, (IAnjutaDebuggerCallback)callback, user_data);
4072 GType
4073 debugger_get_type (void)
4075 static GType obj_type = 0;
4077 if (!obj_type)
4079 static const GTypeInfo obj_info =
4081 sizeof (DebuggerClass),
4082 (GBaseInitFunc) NULL,
4083 (GBaseFinalizeFunc) NULL,
4084 (GClassInitFunc) debugger_class_init,
4085 (GClassFinalizeFunc) NULL,
4086 NULL, /* class_data */
4087 sizeof (Debugger),
4088 0, /* n_preallocs */
4089 (GInstanceInitFunc) debugger_instance_init,
4090 NULL /* value_table */
4092 obj_type = g_type_register_static (G_TYPE_OBJECT,
4093 "Debugger", &obj_info, 0);
4095 return obj_type;
4098 static void
4099 debugger_dispose (GObject *obj)
4101 Debugger *debugger = DEBUGGER (obj);
4103 DEBUG_PRINT ("%s", "In function: debugger_shutdown()");
4105 /* Do not emit signal when the debugger is destroyed */
4106 debugger->priv->instance = NULL;
4107 debugger_abort (debugger);
4109 /* Good Bye message */
4110 if (debugger->priv->output_callback)
4112 debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
4113 "Debugging session completed.\n",
4114 debugger->priv->output_user_data);
4117 if (debugger->priv->launcher)
4119 anjuta_launcher_reset (debugger->priv->launcher);
4120 g_object_unref (debugger->priv->launcher);
4121 debugger->priv->launcher = NULL;
4124 G_OBJECT_CLASS (parent_class)->dispose (obj);
4127 static void
4128 debugger_finalize (GObject *obj)
4130 Debugger *debugger = DEBUGGER (obj);
4131 g_string_free (debugger->priv->stdo_line, TRUE);
4132 g_string_free (debugger->priv->stdo_acc, TRUE);
4133 g_string_free (debugger->priv->stde_line, TRUE);
4134 g_free (debugger->priv->remote_server);
4135 g_free (debugger->priv->load_pretty_printer);
4136 g_free (debugger->priv);
4137 G_OBJECT_CLASS (parent_class)->finalize (obj);
4140 static void
4141 debugger_class_init (DebuggerClass * klass)
4143 GObjectClass *object_class;
4145 g_return_if_fail (klass != NULL);
4146 object_class = G_OBJECT_CLASS (klass);
4148 DEBUG_PRINT ("%s", "Initializing debugger class");
4150 parent_class = g_type_class_peek_parent (klass);
4151 object_class->dispose = debugger_dispose;
4152 object_class->finalize = debugger_finalize;
4156 #if 0 /* FIXME */
4157 void
4158 debugger_signal (const gchar *sig, gboolean show_msg)
4160 /* eg:- "SIGTERM" */
4161 gchar *buff;
4162 gchar *cmd;
4164 DEBUG_PRINT ("%s", "In function: debugger_signal()");
4166 if (debugger_is_active () == FALSE)
4167 return;
4168 if (debugger.prog_is_running == FALSE)
4169 return;
4170 if (debugger.child_pid < 1)
4172 DEBUG_PRINT ("%s", "Not sending signal - pid not known\n");
4173 return;
4176 if (show_msg)
4178 buff = g_strdup_printf (_("Sending signal %s to the process: %d"),
4179 sig, (int) debugger.child_pid);
4180 gdb_util_append_message (ANJUTA_PLUGIN (debugger.plugin), buff);
4181 g_free (buff);
4184 if (debugger_is_ready ())
4186 cmd = g_strconcat ("signal ", sig, NULL);
4187 stack_trace_set_frame (debugger.stack, 0);
4188 debugger_put_cmd_in_queqe (cmd, DB_CMD_ALL, NULL, NULL);
4189 debugger_put_cmd_in_queqe ("info program", DB_CMD_NONE,
4190 on_debugger_update_prog_status,
4191 NULL);
4192 g_free (cmd);
4193 debugger_execute_cmd_in_queqe ();
4195 else
4197 GtkWindow *parent;
4198 int status;
4200 parent = GTK_WINDOW (ANJUTA_PLUGIN (debugger.plugin)->shell);
4201 status = gdb_util_kill_process (debugger.child_pid, sig);
4202 if (status != 0 && show_msg)
4203 anjuta_util_dialog_error (parent,
4204 _("Error whilst signaling the process."));
4208 static void
4209 query_set_cmd (const gchar *cmd, gboolean state)
4211 gchar buffer[50];
4212 gchar *tmp = g_stpcpy (buffer, cmd);
4213 strcpy (tmp, state ? "on" : "off");
4214 debugger_put_cmd_in_queqe (buffer, DB_CMD_NONE, NULL, NULL);
4217 static void
4218 query_set_verbose (gboolean state)
4220 query_set_cmd ("set verbose ", state);
4223 static void
4224 query_set_print_staticmembers (gboolean state)
4226 query_set_cmd ("set print static-members ", state);
4229 static void
4230 query_set_print_pretty (gboolean state)
4232 query_set_cmd ("set print pretty ", state);
4235 void debugger_query_evaluate_expr_tip (const gchar *expr,
4236 DebuggerCLIFunc parser, gpointer data)
4238 query_set_verbose (FALSE);
4239 query_set_print_staticmembers (FALSE);
4240 gchar *printcmd = g_strconcat ("print ", expr, NULL);
4241 debugger_put_cmd_in_queqe (printcmd, DB_CMD_NONE, parser, data);
4242 query_set_verbose (TRUE);
4243 query_set_print_staticmembers (TRUE);
4244 g_free (printcmd);
4247 void
4248 debugger_query_evaluate_expression (const gchar *expr, DebuggerFunc parser,
4249 gpointer data)
4251 query_set_print_pretty (TRUE);
4252 query_set_verbose (FALSE);
4253 gchar *printcmd = g_strconcat ("print ", expr, NULL);
4254 debugger_put_cmd_in_queqe (printcmd, DB_CMD_SE_MESG | DB_CMD_SE_DIALOG,
4255 parser, data);
4256 query_set_print_pretty (FALSE);
4257 query_set_verbose (TRUE);
4258 g_free (printcmd);
4261 #endif