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.
14  *
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
18  */
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22 
23 /*#define DEBUG*/
24 
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>
36 
37 #include <glib.h>
38 #include <glib/gi18n.h>
39 
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>
50 
51 #include "debugger.h"
52 #include "utilities.h"
53 
54 #define ANJUTA_LOG_ENV "ANJUTA_LOG"
55 #define DEBUGGER_LOG_LEVEL 1
56 
57 #define GDB_PROMPT  "(gdb)"
58 #define FILE_BUFFER_SIZE 1024
59 #define GDB_PATH "/usr/local/bin/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 */
64 
65 enum {
66 	DEBUGGER_NONE,
67 	DEBUGGER_EXIT,
68 	DEBUGGER_RERUN_PROGRAM
69 };
70 
71 enum
72 {
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
82 };
83 
84 struct _DebuggerPriv
85 {
86 	GtkWindow *parent_win;
87 
88 	IAnjutaDebuggerOutputCallback output_callback;
89 	gpointer output_user_data;
90 
91 	GList *search_dirs;
92 
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;
100 
101 	AnjutaLauncher *launcher;
102 	GString *stdo_line;
103 	GString *stdo_acc;
104 	GString *stde_line;
105 
106 	GList *cli_lines;
107 
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;
116 
117 	/* GDB command queue */
118 	GList *cmd_queqe;
119 	DebuggerCommand current_cmd;
120 	gboolean skip_next_prompt;
121 	gboolean command_output_sent;
122 
123 	pid_t inferior_pid;
124 	gint current_thread;
125 	guint current_frame;
126 
127 	GObject* instance;
128 
129 	IAnjutaMessageView *log;
130 	gboolean gdb_log;
131 
132 	/* Environment */
133 	IAnjutaEnvironment *environment;
134 
135 	/* GDB Features */
136 	gboolean has_pending_breakpoints;
137 	gboolean has_python_support;
138 	gboolean has_thread_info;
139 	gboolean has_frozen_varobjs;
140 
141 	/* Pretty printers command */
142 	gchar *load_pretty_printer;
143 };
144 
145 static gpointer parent_class;
146 
147 static void debugger_queue_clear (Debugger *debugger);
148 static void debugger_queue_execute_command (Debugger *debugger);
149 
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);
160 
161 static void debugger_class_init (DebuggerClass *klass);
162 static void debugger_instance_init (Debugger *debugger);
163 
164 typedef struct _GdbGListPacket
165 {
166 	GList* list;
167 	gint tag;
168 } GdbGListPacket;
169 
170 /* Useful functions
171  *---------------------------------------------------------------------------*/
172 
gdb_quote(const gchar * unquoted_string)173 static gchar * gdb_quote (const gchar *unquoted_string)
174 {
175 	const char *p;
176 	g_return_val_if_fail (unquoted_string != NULL, NULL);
177 
178 
179 	p = strpbrk (unquoted_string, "\"\\");
180 	if (p == NULL)
181 	{
182 		/* No need to quote anything */
183 		return g_strdup (unquoted_string);
184 	}
185 	else
186 	{
187 		GString *dest;
188 
189 		dest = g_string_new_len (unquoted_string, p - unquoted_string);
190 		for (;;)
191 		{
192 			g_string_append_c (dest, '\\');
193 			unquoted_string = p;
194 			p = strpbrk (unquoted_string + 1, "\"\\");
195 			if (p == NULL)
196 			{
197 				g_string_append (dest, unquoted_string);
198 				break;
199 			}
200 			else
201 			{
202 				g_string_append_len (dest, unquoted_string, p - unquoted_string);
203 			}
204 		}
205 		return g_string_free (dest, FALSE);
206 	}
207 }
208 
209 typedef struct _GdbMessageCode GdbMessageCode;
210 
211 struct _GdbMessageCode
212 {
213 	const gchar *msg;
214 	guint code;
215 };
216 
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}};
229 
230 static guint
gdb_match_error(const gchar * message)231 gdb_match_error(const gchar *message)
232 {
233 	const GdbMessageCode* msg;
234 
235 	for (msg = GdbErrorMessage; msg->msg != NULL; msg++)
236 	{
237 		if (g_pattern_match_simple(msg->msg, message))
238 		{
239 			return msg->code;
240 		}
241 	}
242 
243 	return IANJUTA_DEBUGGER_UNKNOWN_ERROR;
244 }
245 
246 static void
debugger_message_view_append(Debugger * debugger,IAnjutaMessageViewType type,const char * message)247 debugger_message_view_append (Debugger *debugger, IAnjutaMessageViewType type, const char *message)
248 {
249 	guint len = strlen(message);
250 	gchar buf[SUMMARY_MAX_LENGTH];
251 	const gchar* summary = message;
252 	const gchar* detail = "";
253 
254 
255 	if (len > SUMMARY_MAX_LENGTH)
256 	{
257 
258 		memcpy(buf, message, SUMMARY_MAX_LENGTH - 4);
259 		memcpy(buf + SUMMARY_MAX_LENGTH - 4, "...", 4);
260 		summary = buf;
261 		detail = message;
262 	}
263 
264 	ianjuta_message_view_append (debugger->priv->log, type, summary, detail, NULL);
265 }
266 
267 static void
debugger_initialize(Debugger * debugger)268 debugger_initialize (Debugger *debugger)
269 {
270 	const gchar* anjuta_log;
271 
272 	DEBUG_PRINT ("%s", "In function: debugger_init()");
273 
274 	debugger->priv = g_new0 (DebuggerPriv, 1);
275 
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 ();
280 
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;
290 
291 	debugger->priv->current_cmd.cmd = NULL;
292 	debugger->priv->current_cmd.parser = NULL;
293 
294 	debugger->priv->cmd_queqe = NULL;
295 	debugger->priv->cli_lines = NULL;
296 	debugger->priv->solib_event = FALSE;
297 
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 ("");
301 
302 	debugger->priv->stde_line = g_string_sized_new (FILE_BUFFER_SIZE);
303 	g_string_assign (debugger->priv->stde_line, "");
304 
305 	debugger->priv->post_execution_flag = DEBUGGER_NONE;
306 
307 	anjuta_log = g_getenv (ANJUTA_LOG_ENV);
308 	debugger->priv->gdb_log = anjuta_log && (atoi(anjuta_log) > DEBUGGER_LOG_LEVEL);
309 
310 	debugger->priv->environment = NULL;
311 
312 	debugger->priv->load_pretty_printer = NULL;
313 }
314 
315 static void
debugger_instance_init(Debugger * debugger)316 debugger_instance_init (Debugger *debugger)
317 {
318 	debugger_initialize (debugger);
319 }
320 
321 Debugger*
debugger_new(GtkWindow * parent_win,GObject * instance)322 debugger_new (GtkWindow *parent_win, GObject* instance)
323 {
324 	Debugger *debugger;
325 
326 	debugger = g_object_new (DEBUGGER_TYPE, NULL);
327 	debugger->priv->parent_win = parent_win;
328 	debugger->priv->instance = instance;
329 
330 	return debugger;
331 }
332 
333 void
debugger_free(Debugger * debugger)334 debugger_free (Debugger *debugger)
335 {
336 	g_return_if_fail (IS_DEBUGGER (debugger));
337 
338 	if (debugger->priv->environment)
339 	{
340 		g_object_unref (debugger->priv->environment);
341 		debugger->priv->environment = NULL;
342 	}
343 
344 	g_object_unref (debugger);
345 }
346 
347 gboolean
debugger_is_ready(Debugger * debugger)348 debugger_is_ready (Debugger *debugger)
349 {
350 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
351 	return !debugger->priv->debugger_is_busy;
352 }
353 
354 gboolean
debugger_program_is_running(Debugger * debugger)355 debugger_program_is_running (Debugger *debugger)
356 {
357 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
358 	return debugger->priv->prog_is_running;
359 }
360 
361 gboolean
debugger_program_is_attached(Debugger * debugger)362 debugger_program_is_attached (Debugger *debugger)
363 {
364 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
365 	return debugger->priv->prog_is_attached;
366 }
367 
368 gboolean
debugger_program_is_loaded(Debugger * debugger)369 debugger_program_is_loaded (Debugger *debugger)
370 {
371 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
372 	return debugger->priv->prog_is_loaded;
373 }
374 
375 static void
debugger_log_command(Debugger * debugger,const gchar * command)376 debugger_log_command (Debugger *debugger, const gchar *command)
377 {
378 	gchar* str;
379 	gsize len;
380 
381 	if (debugger->priv->log == NULL) return;
382 
383 	if (*command == '-')
384 	{
385 		str = g_strdup (command);
386 		len = strlen (command);
387 
388 		/* Remove trailing carriage return */
389 		if (str[len - 1] == '\n') str[len - 1] = '\0';
390 
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);
399 	}
400 }
401 
402 static void
debugger_log_output(Debugger * debugger,const gchar * line)403 debugger_log_output (Debugger *debugger, const gchar *line)
404 {
405 	gchar* str;
406 	const gchar* start;
407 	IAnjutaMessageViewType type;
408 	gsize len;
409 
410 	if (debugger->priv->log == NULL) return;
411 
412 	type = IANJUTA_MESSAGE_VIEW_TYPE_NORMAL;
413 	switch (*line)
414 	{
415 	case '~':
416 		type = IANJUTA_MESSAGE_VIEW_TYPE_INFO;
417 		/* Go through */
418 	case '&':
419 		len = strlen(line);
420 		start = line + 1;
421 
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)
427 		{
428 			str[len - 1] = '\0';
429 			len--;
430 		}
431 
432 		/* Remove trailing carriage return */
433 		if (str[len - 1] == '\n') str[len - 1] = '\0';
434 
435 		debugger_message_view_append (debugger, type, str);
436 		g_free (str);
437 		break;
438 	case '^':
439 		if (strncmp(line + 1, "error", 5) == 0)
440 		{
441 			debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_ERROR, line + 1);
442 		}
443 		else
444 		{
445 			debugger_message_view_append (debugger, IANJUTA_MESSAGE_VIEW_TYPE_WARNING, line + 1);
446 		}
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;
454 	}
455 }
456 
457 /* Emit ready signal (= command completed) for debuger manager and change the
458  * debugger state.
459  */
460 static void
debugger_emit_ready(Debugger * debugger)461 debugger_emit_ready (Debugger *debugger)
462 {
463 	if (!debugger->priv->debugger_is_busy)
464 	{
465 		if (debugger->priv->loading)
466 		{
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);
473 		}
474 		else if (debugger->priv->starting)
475 		{
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)
482 			{
483 				g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_STOPPED);
484 			}
485 			else
486 			{
487 				g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_STARTED);
488 			}
489 		}
490 		else if (debugger->priv->exiting)
491 		{
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);
496 		}
497 		else if (debugger->priv->solib_event)
498 		{
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");
503 		}
504 		else if (debugger->priv->stopping)
505 		{
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);
510 		}
511 		else
512 		{
513 			if (debugger->priv->prog_is_running || debugger->priv->prog_is_attached)
514 			{
515 				g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_STOPPED);
516 			}
517 			else if (debugger->priv->prog_is_loaded)
518 			{
519 				g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_PROGRAM_LOADED);
520 			}
521 			else
522 			{
523 				g_signal_emit_by_name (debugger->priv->instance, "debugger-ready", IANJUTA_DEBUGGER_STARTED);
524 			}
525 		}
526 	}
527 }
528 
529 IAnjutaDebuggerState
debugger_get_state(Debugger * debugger)530 debugger_get_state (Debugger *debugger)
531 {
532 	if (debugger->priv->debugger_is_busy)
533 	{
534 		return IANJUTA_DEBUGGER_BUSY;
535 	}
536 	else
537 	{
538 		if (debugger->priv->prog_is_running || debugger->priv->prog_is_attached)
539 		{
540 			return IANJUTA_DEBUGGER_PROGRAM_STOPPED;
541 		}
542 		else if (debugger->priv->prog_is_loaded)
543 		{
544 			return IANJUTA_DEBUGGER_PROGRAM_LOADED;
545 		}
546 		else if (debugger->priv->debugger_is_started)
547 		{
548 			return IANJUTA_DEBUGGER_STARTED;
549 		}
550 		else
551 		{
552 			return IANJUTA_DEBUGGER_STOPPED;
553 		}
554 	}
555 }
556 
557 static void
debugger_clear_buffers(Debugger * debugger)558 debugger_clear_buffers (Debugger *debugger)
559 {
560 	DEBUG_PRINT ("%s", "In function: debugger_clear_buffers()");
561 
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, "");
566 
567 	/* Clear the error line buffer */
568 	g_string_assign (debugger->priv->stde_line, "");
569 
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;
574 }
575 
576 static DebuggerCommand *
debugger_queue_get_next_command(Debugger * debugger)577 debugger_queue_get_next_command (Debugger *debugger)
578 {
579 	DebuggerCommand *dc;
580 
581 	DEBUG_PRINT ("%s", "In function: debugger_get_next_command()");
582 
583 	if (debugger->priv->cmd_queqe)
584 	{
585 		dc = g_list_nth_data (debugger->priv->cmd_queqe, 0);
586 		debugger->priv->cmd_queqe = g_list_remove (debugger->priv->cmd_queqe, dc);
587 	}
588 	else
589 		dc = NULL;
590 	return dc;
591 }
592 
593 static gboolean
debugger_queue_set_next_command(Debugger * debugger)594 debugger_queue_set_next_command (Debugger *debugger)
595 {
596 	DebuggerCommand *dc;
597 
598 	DEBUG_PRINT ("%s", "In function: debugger_set_next_command()");
599 
600 	dc = debugger_queue_get_next_command (debugger);
601 	if (!dc)
602 	{
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;
608 
609 		return FALSE;
610 	}
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);
618 
619 	return TRUE;
620 }
621 
622 static void
debugger_queue_command(Debugger * debugger,const gchar * cmd,gint flags,DebuggerParserFunc parser,IAnjutaDebuggerCallback callback,gpointer user_data)623 debugger_queue_command (Debugger *debugger, const gchar *cmd,
624 						gint flags,
625 						DebuggerParserFunc parser,
626 						IAnjutaDebuggerCallback callback, gpointer user_data)
627 {
628 	DebuggerCommand *dc;
629 
630 
631 	DEBUG_PRINT ("In function: debugger_queue_command (%s)", cmd);
632 
633 	dc = g_malloc (sizeof (DebuggerCommand));
634 	if (dc)
635 	{
636 		dc->cmd = g_strdup(cmd);
637 		dc->parser = parser;
638 		dc->callback = callback;
639 		dc->user_data = user_data;
640 		dc->flags = flags;
641 	}
642 	if (flags & DEBUGGER_COMMAND_PREPEND)
643 	{
644 		debugger->priv->cmd_queqe = g_list_prepend (debugger->priv->cmd_queqe, dc);
645 	}
646 	else
647 	{
648 		debugger->priv->cmd_queqe = g_list_append (debugger->priv->cmd_queqe, dc);
649 	}
650 	debugger_queue_execute_command (debugger);
651 }
652 
653 static void
debugger_queue_clear(Debugger * debugger)654 debugger_queue_clear (Debugger *debugger)
655 {
656 	GList *node;
657 
658 	DEBUG_PRINT ("%s", "In function: debugger_queue_clear()");
659 
660 	node = debugger->priv->cmd_queqe;
661 	while (node)
662 	{
663 		g_free (((DebuggerCommand *)node->data)->cmd);
664 		g_free (node->data);
665 		node = g_list_next (node);
666 	}
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);
676 }
677 
678 static void
debugger_execute_command(Debugger * debugger,const gchar * command)679 debugger_execute_command (Debugger *debugger, const gchar *command)
680 {
681 	gchar *cmd;
682 
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);
690 }
691 
692 static void
debugger_queue_execute_command(Debugger * debugger)693 debugger_queue_execute_command (Debugger *debugger)
694 {
695 	DEBUG_PRINT ("%s", "In function: debugger_queue_execute_command()");
696 
697 	if (!debugger->priv->debugger_is_busy &&
698 		g_list_length (debugger->priv->cmd_queqe) >= 1)
699 	{
700 		debugger_clear_buffers (debugger);
701 		if (debugger_queue_set_next_command (debugger))
702 		debugger_execute_command (debugger, debugger->priv->current_cmd.cmd);
703 	}
704 }
705 
706 static void
debugger_load_executable_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)707 debugger_load_executable_finish (Debugger *debugger, const GDBMIValue *mi_results,
708 								const GList *cli_results, GError *error)
709 {
710 	DEBUG_PRINT ("%s", "Program loaded");
711 	debugger->priv->prog_is_loaded = TRUE;
712 
713 	g_signal_emit_by_name (debugger->priv->instance, "program-loaded");
714 }
715 
716 void
debugger_load_executable(Debugger * debugger,const gchar * prog)717 debugger_load_executable (Debugger *debugger, const gchar *prog)
718 {
719 	gchar *command, *dir, *msg;
720 
721 	g_return_if_fail (IS_DEBUGGER (debugger));
722 	g_return_if_fail (prog != NULL);
723 
724 	DEBUG_PRINT ("In function: debugger_load_executable(%s)", prog);
725 
726 	if (debugger->priv->output_callback)
727 	{
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);
733 	}
734 
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);
739 */
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;
745 }
746 
747 void
debugger_load_core(Debugger * debugger,const gchar * core)748 debugger_load_core (Debugger *debugger, const gchar *core)
749 {
750 	gchar *command, *dir, *msg;
751 
752 	g_return_if_fail (IS_DEBUGGER (debugger));
753 	g_return_if_fail (core != NULL);
754 
755 	DEBUG_PRINT ("In function: debugger_load_core(%s)", core);
756 
757 	if (debugger->priv->output_callback)
758 	{
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);
764 	}
765 
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);
772 }
773 
774 /* Set environment
775  *---------------------------------------------------------------------------*/
776 
777 gboolean
debugger_set_working_directory(Debugger * debugger,const gchar * directory)778 debugger_set_working_directory (Debugger *debugger, const gchar *directory)
779 {
780 	gchar *buff;
781 
782 	DEBUG_PRINT ("%s", "In function: set_working_directory()");
783 
784 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
785 
786 	buff = g_strdup_printf ("-environment-cd %s", directory);
787 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
788 	g_free (buff);
789 
790 	return TRUE;
791 }
792 
793 gboolean
debugger_set_environment(Debugger * debugger,gchar ** variables)794 debugger_set_environment (Debugger *debugger, gchar **variables)
795 {
796 	gchar *buff;
797 
798 	DEBUG_PRINT ("%s", "In function: set_environment()");
799 
800 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
801 
802 	if ((variables != NULL)  && (*variables != NULL))
803 	{
804 		for (; *variables != NULL; variables++)
805 		{
806 			buff = g_strdup_printf("set environment %s", *variables);
807 			debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
808 			g_free (buff);
809 		}
810 	}
811 	else
812 	{
813 		debugger_emit_ready (debugger);
814 	}
815 
816 	return TRUE;
817 }
818 
819 gboolean
debugger_set_pretty_printers(Debugger * debugger,const GList * pretty_printers)820 debugger_set_pretty_printers (Debugger *debugger, const GList *pretty_printers)
821 {
822 	GString *load = g_string_new (NULL);
823 	GList *item;
824 	GList *directories = NULL;
825 
826 	/* Unload previous pretty printers */
827 	g_free (debugger->priv->load_pretty_printer);
828 
829 	/* Get all necessary directories */
830 	for (item = g_list_first ((GList *)pretty_printers); item != NULL; item = g_list_next (item))
831 	{
832 		GdbPrettyPrinter *printer = (GdbPrettyPrinter *)item->data;
833 		gchar *dir;
834 
835 		if (printer->enable)
836 		{
837 			dir = g_path_get_dirname (printer->path);
838 			if (g_list_find_custom (directories, dir, (GCompareFunc)strcmp) == NULL)
839 			{
840 				directories = g_list_prepend (directories, dir);
841 			}
842 			else
843 			{
844 				g_free (dir);
845 			}
846 		}
847 	}
848 	/* Add them in the command */
849 	if (directories != NULL)
850 	{
851 		g_string_append (load, "python\nimport sys\n");
852 
853 		for (item = g_list_first (directories); item != NULL; item = g_list_next (item))
854 		{
855 			g_string_append_printf (load, "sys.path.insert(0,'%s')\n", (gchar *)item->data);
856 			g_free (item->data);
857 		}
858 		g_list_free (directories);
859 
860 		/* Import all modules and call register function*/
861 		for (item = g_list_first ((GList *)pretty_printers); item != NULL; item = g_list_next (item))
862 		{
863 			GdbPrettyPrinter *printer = (GdbPrettyPrinter *)item->data;
864 			gchar *name;
865 
866 			if (printer->enable && (printer->function != NULL))
867 			{
868 				/* Remove .py extension */
869 				name = g_path_get_basename (printer->path);
870 				if (g_str_has_suffix (name, ".py"))
871 				{
872 					name[strlen (name) - 3] = '\0';
873 				}
874 
875 				if (printer->function != NULL)
876 				g_string_append_printf (load, "import %s\n%s.%s(None)\n", name, name, printer->function);
877 			}
878 		}
879 		g_string_append (load, "end");
880 	}
881 
882 	debugger->priv->load_pretty_printer = g_string_free (load, FALSE);
883 
884 	return TRUE;
885 }
886 
887 static void
debugger_list_features_completed(Debugger * debugger,const GDBMIValue * mi_result,const GList * cli_result,GError * error)888 debugger_list_features_completed (Debugger *debugger,
889 									const GDBMIValue *mi_result,
890 									const GList *cli_result,
891 									GError* error)
892 {
893 	const GDBMIValue *features;
894 	gint i;
895 
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;
900 
901 	features = gdbmi_value_hash_lookup (mi_result, "features");
902 
903 	for (i = 0; i < gdbmi_value_get_size (features); i++)
904 	{
905 		const GDBMIValue *feature;
906 		const gchar *value;
907 
908 		feature = gdbmi_value_list_get_nth (features, i);
909 		value = gdbmi_value_literal_get (feature);
910 
911 		if (g_strcmp0 (value, "frozen-varobjs") == 0)
912 		{
913 			debugger->priv->has_frozen_varobjs = TRUE;
914 		}
915 		else if (g_strcmp0 (value, "thread-info") == 0)
916 		{
917 			debugger->priv->has_thread_info = TRUE;
918 		}
919 		else if (g_strcmp0 (value, "pending-breakpoints") == 0)
920 		{
921 			debugger->priv->has_pending_breakpoints = TRUE;
922 		}
923 		else if (g_strcmp0 (value, "python") == 0)
924 		{
925 			debugger->priv->has_python_support = TRUE;
926 		}
927 	}
928 
929 	if (debugger->priv->has_pending_breakpoints)
930 	{
931 		debugger_queue_command (debugger, "set stop-on-solib-events 0", DEBUGGER_COMMAND_PREPEND, NULL, NULL, NULL);
932 	}
933 	else
934 	{
935 		debugger_queue_command (debugger, "set stop-on-solib-events 1", DEBUGGER_COMMAND_PREPEND, NULL, NULL, NULL);
936 	}
937 
938 	if (debugger->priv->has_python_support && (debugger->priv->load_pretty_printer != NULL))
939 	{
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);
942 	}
943 }
944 
945 static gboolean
debugger_list_features(Debugger * debugger)946 debugger_list_features (Debugger *debugger)
947 {
948 	DEBUG_PRINT ("%s", "In function: list_featues()");
949 
950 	g_return_val_if_fail (IS_DEBUGGER (debugger), FALSE);
951 
952 	debugger_queue_command (debugger, "-list-features", 0, debugger_list_features_completed, NULL, NULL);
953 
954 	return TRUE;
955 }
956 
957 gboolean
debugger_start(Debugger * debugger,const GList * search_dirs,const gchar * prog,gboolean is_libtool_prog)958 debugger_start (Debugger *debugger,
959 				const GList *search_dirs,
960 				const gchar *prog,
961 				gboolean is_libtool_prog)
962 {
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;
973 
974 	DEBUG_PRINT ("In function: debugger_start(%s) libtool %d", prog == NULL ? "(null)" : prog, is_libtool_prog);
975 
976 	if (anjuta_util_prog_is_installed ("gdb", TRUE) == FALSE)
977 		return FALSE;
978 
979 	debugger_queue_clear (debugger);
980 
981 	tmp = g_strconcat (PACKAGE_DATA_DIR, "/", "gdb.init", NULL);
982 	if (g_file_test (tmp, G_FILE_TEST_IS_REGULAR) == FALSE)
983 	{
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;
991 	}
992 	g_free (tmp);
993 
994 	/* Prepare source search directories */
995 	work_dir = NULL;
996 	if (prog)
997 		work_dir = g_path_get_dirname (prog);
998 
999 	dir = g_strdup (" ");
1000 	node = search_dirs;
1001 	while (node)
1002 	{
1003 		text = node->data;
1004 		if (strncmp (text, "file://", 7) == 0)
1005 		{
1006 			text += 7;
1007 		}
1008 		else
1009 		{
1010 			g_warning ("Debugger source search uri '%s' is not a local uri", text);
1011 		}
1012 
1013 		if (text[0] == '/')
1014 		{
1015 			tmp = g_strconcat (dir, " -directory=", text, NULL);
1016 			g_free (dir);
1017 			dir = tmp;
1018 
1019 			dir_list = g_list_prepend (dir_list, g_strdup (text));
1020 		}
1021 		else
1022 		{
1023 			g_warning ("Debugger source search dir '%s' is not absolute",
1024 					   text);
1025 		}
1026 		node = g_list_next (node);
1027 	}
1028 
1029 	/* Now save the dir list. Order is automatically reversed */
1030 	node = dir_list;
1031 	while (node)
1032 	{
1033 		debugger->priv->search_dirs =
1034 			g_list_prepend (debugger->priv->search_dirs, node->data);
1035 		node = g_list_next (node);
1036 	}
1037 	g_list_free (dir_list);
1038 
1039 	if (prog && strlen(prog) > 0)
1040 	{
1041 		gchar *quoted_prog = gdb_quote (prog);
1042 		if (is_libtool_prog == FALSE)
1043 		{
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);
1047 		}
1048 		else
1049 		{
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);
1054 		}
1055 		g_free (quoted_prog);
1056 	}
1057 	else
1058 	{
1059 		if (is_libtool_prog == FALSE)
1060 		{
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);
1064 		}
1065 		else
1066 		{
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);
1071 		}
1072 	}
1073 	g_shell_parse_argv (command_str, NULL, &argv, NULL);
1074 	g_free (command_str);
1075 
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;
1082 
1083 	/* Get environment */
1084 	plugin_manager = anjuta_shell_get_plugin_manager (ANJUTA_PLUGIN (debugger->priv->instance)->shell, NULL);
1085 	if (debugger->priv->environment != NULL)
1086 	{
1087 		g_object_unref (debugger->priv->environment);
1088 	}
1089 	if (anjuta_plugin_manager_is_active_plugin (plugin_manager, "IAnjutaEnvironment"))
1090 	{
1091 		IAnjutaEnvironment *env = IANJUTA_ENVIRONMENT (anjuta_shell_get_object (ANJUTA_PLUGIN (debugger->priv->instance)->shell,
1092 					"IAnjutaEnvironment", NULL));
1093 
1094 		g_object_ref (env);
1095 		debugger->priv->environment = env;
1096 		ianjuta_environment_override (debugger->priv->environment, &work_dir, &argv, &envp, NULL);
1097 	}
1098 	else
1099 	{
1100 		debugger->priv->environment = NULL;
1101 	}
1102 
1103 	/* Prepare for launch. */
1104 	launcher = debugger->priv->launcher;
1105 	anjuta_launcher_set_terminate_on_exit (launcher, TRUE);
1106 	anjuta_launcher_set_check_passwd_prompt (launcher, FALSE);
1107 	g_signal_connect (G_OBJECT (launcher), "child-exited",
1108 					  G_CALLBACK (on_gdb_terminated), debugger);
1109 	ret = anjuta_launcher_execute_v (launcher,
1110 		    						work_dir,
1111 		    						argv,
1112 		    						envp,
1113 		    						on_gdb_output_arrived, debugger);
1114 	g_strfreev (argv);
1115 	g_strfreev (envp);
1116 	g_free (work_dir);
1117 
1118 	if (ret)
1119 	{
1120 		debugger->priv->debugger_is_started = TRUE;
1121 		debugger->priv->prog_is_loaded = prog != NULL;
1122 	}
1123 	anjuta_launcher_set_encoding (launcher, "ISO-8859-1");
1124 
1125 	if (debugger->priv->output_callback != NULL)
1126 	{
1127 		if (ret == TRUE)
1128 		{
1129 			/* TODO		anjuta_update_app_status (TRUE, _("Debugger")); */
1130 			debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1131 										 _("Getting ready to start debugging "
1132 										   "session…\n"),
1133 										 debugger->priv->output_user_data);
1134 
1135 			if (prog)
1136 			{
1137 				msg = g_strconcat (_("Loading Executable: "), prog, "\n", NULL);
1138 				debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1139 											 msg,
1140 											 debugger->priv->output_user_data);
1141 				g_free (msg);
1142 			}
1143 			else
1144 			{
1145 				debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1146 									   _("No executable specified.\n"),
1147 									   debugger->priv->output_user_data);
1148 				debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1149 											 _("Open an executable or attach "
1150 											   "to a process to start "
1151 											   "debugging.\n"),
1152 											 debugger->priv->output_user_data);
1153 			}
1154 		}
1155 		else
1156 		{
1157 			debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1158 										 _("There was an error whilst "
1159 										   "launching the debugger.\n"),
1160 										 debugger->priv->output_user_data);
1161 			debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1162 										 _("Make sure 'gdb' is installed "
1163 										   "on the system.\n"),
1164 										 debugger->priv->output_user_data);
1165 		}
1166 	}
1167 
1168 	/* Check available features */
1169 	debugger_list_features (debugger);
1170 
1171 	debugger_queue_command (debugger, "handle SIGINT stop print nopass", 0, NULL, NULL, NULL);
1172 
1173 	return TRUE;
1174 }
1175 
1176 static void
gdb_stdout_line_arrived(Debugger * debugger,const gchar * chars)1177 gdb_stdout_line_arrived (Debugger *debugger, const gchar * chars)
1178 {
1179 	gint i = 0;
1180 
1181 	while (chars[i])
1182 	{
1183 		if (chars[i] == '\n')
1184 		{
1185 			debugger_stdo_flush (debugger);
1186 		}
1187 		else
1188 		{
1189 			g_string_append_c (debugger->priv->stdo_line, chars[i]);
1190 		}
1191 		i++;
1192 	}
1193 }
1194 
1195 static void
gdb_stderr_line_arrived(Debugger * debugger,const gchar * chars)1196 gdb_stderr_line_arrived (Debugger *debugger, const gchar * chars)
1197 {
1198 	gint i;
1199 
1200 	for (i = 0; i < strlen (chars); i++)
1201 	{
1202 		if (chars[i] == '\n')
1203 			debugger_stde_flush (debugger);
1204 		else
1205 			g_string_append_c (debugger->priv->stde_line, chars[i]);
1206 	}
1207 }
1208 
1209 static void
on_gdb_output_arrived(AnjutaLauncher * launcher,AnjutaLauncherOutputType output_type,const gchar * chars,gpointer data)1210 on_gdb_output_arrived (AnjutaLauncher *launcher,
1211 					   AnjutaLauncherOutputType output_type,
1212 					   const gchar *chars, gpointer data)
1213 {
1214 	Debugger *debugger = DEBUGGER (data);
1215 	DEBUG_PRINT ("%s", "on gdb output arrived");
1216 
1217 	/* Do not emit signal when the debugger is destroyed */
1218 	if (debugger->priv->instance == NULL) return;
1219 
1220 	switch (output_type)
1221 	{
1222 	case ANJUTA_LAUNCHER_OUTPUT_STDERR:
1223 		gdb_stderr_line_arrived (debugger, chars);
1224 		break;
1225 	case ANJUTA_LAUNCHER_OUTPUT_STDOUT:
1226 		gdb_stdout_line_arrived (debugger, chars);
1227 		break;
1228 	default:
1229 		break;
1230 	}
1231 }
1232 
1233 static void
debugger_handle_post_execution(Debugger * debugger)1234 debugger_handle_post_execution (Debugger *debugger)
1235 {
1236 	switch (debugger->priv->post_execution_flag)
1237 	{
1238 		case DEBUGGER_NONE:
1239 			break;
1240 		case DEBUGGER_EXIT:
1241 			DEBUG_PRINT ("%s", "debugger stop in handle post execution\n");
1242 			debugger_stop (debugger);
1243 			break;
1244 		case DEBUGGER_RERUN_PROGRAM:
1245 			DEBUG_PRINT ("%s", "debugger run in handle post execution\n");
1246 			debugger_run (debugger);
1247 			break;
1248 		default:
1249 			g_warning ("Execution should not reach here");
1250 	}
1251 }
1252 
1253 static const gchar *
debugger_parse_filename(const GDBMIValue * frame)1254 debugger_parse_filename (const GDBMIValue *frame)
1255 {
1256 	const GDBMIValue *filename, *fullname;
1257 	const gchar *file_str = NULL;
1258 
1259 	/* Get filename from file if possible to keep symbolic links */
1260 	filename = gdbmi_value_hash_lookup (frame, "file");
1261 	if (filename)
1262 	{
1263 		file_str = gdbmi_value_literal_get (filename);
1264 		if (!g_path_is_absolute (file_str))
1265 		{
1266 			/* Path is not absolute */
1267 			file_str = NULL;
1268 		}
1269 	}
1270 
1271 	/* Try fullname value to get an absolute path */
1272 	if (file_str == NULL)
1273 	{
1274 		fullname = gdbmi_value_hash_lookup (frame, "fullname");
1275 		if (fullname)
1276 		{
1277 			file_str = gdbmi_value_literal_get (fullname);
1278 		}
1279 		else
1280 		{
1281 			if (filename)
1282 			{
1283 				file_str = gdbmi_value_literal_get (filename);
1284 			}
1285 		}
1286 	}
1287 
1288 	if ((file_str != NULL) && (*file_str == '\0')) file_str = NULL;
1289 
1290 	return file_str;
1291 }
1292 
1293 static void
debugger_process_frame(Debugger * debugger,const GDBMIValue * val)1294 debugger_process_frame (Debugger *debugger, const GDBMIValue *val)
1295 {
1296 	const GDBMIValue *line, *frame, *addr, *thread;
1297 	const gchar *file_str = NULL;
1298 	guint line_num = 0;
1299 	gulong addr_num = 0;
1300 
1301 	g_return_if_fail (val != NULL);
1302 
1303 	thread = gdbmi_value_hash_lookup (val, "thread-id");
1304 	if (thread)
1305 	{
1306 		debugger->priv->current_thread = strtoul (gdbmi_value_literal_get (thread), NULL, 0);
1307 	}
1308 	debugger->priv->current_frame = 0;
1309 
1310 	frame = gdbmi_value_hash_lookup (val, "frame");
1311 	if (frame)
1312 	{
1313 		file_str = debugger_parse_filename (frame);
1314 
1315 		if (file_str != NULL)
1316 		{
1317 			line = gdbmi_value_hash_lookup (frame, "line");
1318 			if (line)
1319 			{
1320 				line_num = strtoul (gdbmi_value_literal_get (line), NULL, 0);
1321 			}
1322 		}
1323 
1324 		addr = gdbmi_value_hash_lookup (frame, "addr");
1325 		if (addr)
1326 		{
1327 			addr_num = strtoul (gdbmi_value_literal_get (addr), NULL, 0);
1328 		}
1329 		debugger_program_moved (debugger, file_str, line_num, addr_num);
1330 	}
1331 }
1332 
1333 static GError*
gdb_parse_error(Debugger * debugger,const GDBMIValue * mi_results)1334 gdb_parse_error (Debugger *debugger, const GDBMIValue *mi_results)
1335 {
1336 	const GDBMIValue *message;
1337 	const gchar *literal;
1338 	guint code = IANJUTA_DEBUGGER_UNKNOWN_ERROR;
1339 
1340 	message = gdbmi_value_hash_lookup (mi_results, "msg");
1341 	literal = gdbmi_value_literal_get (message);
1342 
1343 	if ((mi_results != NULL)
1344 	&& ((message = gdbmi_value_hash_lookup (mi_results, "msg")) != NULL)
1345 	&& ((literal = gdbmi_value_literal_get (message)) != NULL)
1346 	&& (*literal != '\0'))
1347 	{
1348 		code = gdb_match_error (literal);
1349 		DEBUG_PRINT ("error code %d", code);
1350 	}
1351 	else
1352 	{
1353 		/* No error message */
1354 		literal = "Error without a message";
1355 	}
1356 
1357 	return g_error_new_literal (IANJUTA_DEBUGGER_ERROR, code, literal);
1358 }
1359 
1360 
1361 /* Parsing output
1362  *---------------------------------------------------------------------------*/
1363 
1364 static void
debugger_parse_output(Debugger * debugger)1365 debugger_parse_output (Debugger *debugger)
1366 {
1367 	gchar *line;
1368 
1369 	line = debugger->priv->stdo_line->str;
1370 
1371 	if (line[0] == '\032' && line[1] == '\032')
1372 	{
1373 		gchar *filename;
1374 		guint lineno;
1375 
1376 		gdb_util_parse_error_line (&(line[2]), &filename, &lineno);
1377 		if (filename)
1378 		{
1379 			debugger_program_moved (debugger, filename, lineno, 0);
1380 			g_free (filename);
1381 		}
1382 	}
1383 	else
1384 	{
1385 		gchar *proper_msg;
1386 		gsize len;
1387 
1388 		len = strlen (line);
1389 		if (line[1] == '\"' && line [strlen(line) - 1] == '\"')
1390 		{
1391 			line[1] = line[0];
1392 			/* Reserve space for an additional carriage return */
1393 			line[strlen(line) - 1] = ' ';
1394 			proper_msg = g_strcompress (line + 1);
1395 			len = strlen (proper_msg) - 1;
1396 			proper_msg[len] = '\0';
1397 		}
1398 		else
1399 		{
1400 			/* Reserve space for an additional carriage return */
1401 			proper_msg = g_strndup (line, len + 1);
1402 		}
1403 
1404 		if (strcmp(proper_msg, "~Stopped due to shared library event\n") == 0)
1405 		{
1406 			/* Recognize a solib event */
1407 			debugger->priv->solib_event = TRUE;
1408 			g_free (proper_msg);
1409 		}
1410 		else if (debugger->priv->current_cmd.parser)
1411 		{
1412 			/* Save GDB CLI output */
1413 			debugger->priv->cli_lines = g_list_prepend (debugger->priv->cli_lines,
1414 													   proper_msg);
1415 		}
1416 		else
1417 		{
1418 			/* Discard CLI output */
1419 			g_free (proper_msg);
1420 		}
1421 	}
1422 }
1423 
1424 static void
debugger_parse_stopped(Debugger * debugger)1425 debugger_parse_stopped (Debugger *debugger)
1426 {
1427 	gchar *line = debugger->priv->stdo_line->str;
1428 
1429 
1430 	if (!debugger->priv->solib_event)
1431 	{
1432 		gboolean program_exited = FALSE;
1433 		GDBMIValue *val;
1434 
1435 		/* Check if program has exited */
1436 		val = gdbmi_value_parse (line);
1437 		if (val)
1438 		{
1439 			const GDBMIValue *reason;
1440 			const gchar *str = NULL;
1441 
1442 			debugger_process_frame (debugger, val);
1443 
1444 			reason = gdbmi_value_hash_lookup (val, "reason");
1445 			if (reason)
1446 				str = gdbmi_value_literal_get (reason);
1447 
1448 			if (str && (strncmp (str, "exited", 6) == 0))
1449 			{
1450 				program_exited = TRUE;
1451 			}
1452 
1453 			/* Emit signal received if necessary */
1454 			if (str && strcmp (str, "exited-signalled") == 0)
1455 			{
1456 				const GDBMIValue *signal_name, *signal_meaning;
1457 				const gchar *signal_str, *signal_meaning_str;
1458 
1459 				signal_name = gdbmi_value_hash_lookup (val, "signal-name");
1460 				signal_str = gdbmi_value_literal_get (signal_name);
1461 				signal_meaning = gdbmi_value_hash_lookup (val, "signal-meaning");
1462 				signal_meaning_str = gdbmi_value_literal_get (signal_meaning);
1463 				g_signal_emit_by_name (debugger->priv->instance, "signal-received", signal_str, signal_meaning_str);
1464 			}
1465 			else if (str && strcmp (str, "signal-received") == 0)
1466 			{
1467 				const GDBMIValue *signal_name, *signal_meaning;
1468 				const gchar *signal_str, *signal_meaning_str;
1469 
1470 				signal_name = gdbmi_value_hash_lookup (val, "signal-name");
1471 				signal_str = gdbmi_value_literal_get (signal_name);
1472 				signal_meaning = gdbmi_value_hash_lookup (val, "signal-meaning");
1473 				signal_meaning_str = gdbmi_value_literal_get (signal_meaning);
1474 
1475 				g_signal_emit_by_name (debugger->priv->instance, "signal-received", signal_str, signal_meaning_str);
1476 			}
1477 
1478 			if (debugger->priv->output_callback)
1479 			{
1480 				if (str && strcmp (str, "exited-normally") == 0)
1481 				{
1482 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1483 										   _("Program exited normally\n"),
1484 										   debugger->priv->output_user_data);
1485 				}
1486 				else if (str && strcmp (str, "exited") == 0)
1487 				{
1488 					const GDBMIValue *errcode;
1489 					const gchar *errcode_str;
1490 					gchar *msg;
1491 
1492 					errcode = gdbmi_value_hash_lookup (val, "exit-code");
1493 					errcode_str = gdbmi_value_literal_get (errcode);
1494 					msg = g_strdup_printf (_("Program exited with error code %s\n"),
1495 									   errcode_str);
1496 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1497 										   msg, debugger->priv->output_user_data);
1498 					g_free (msg);
1499 				}
1500 				else if (str && strcmp (str, "breakpoint-hit") == 0)
1501 				{
1502 					const GDBMIValue *bkptno;
1503 					const gchar *bkptno_str;
1504 					gchar *msg;
1505 
1506 					bkptno = gdbmi_value_hash_lookup (val, "bkptno");
1507 					bkptno_str = gdbmi_value_literal_get (bkptno);
1508 					/* The program has reached one breakpoint and will stop */
1509 					msg = g_strdup_printf (_("Breakpoint number %s hit\n"),
1510 									   bkptno_str);
1511 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1512 										   msg, debugger->priv->output_user_data);
1513 					g_free (msg);
1514 				}
1515 				else if (str && strcmp (str, "function-finished") == 0)
1516 				{
1517 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1518 										   _("Function finished\n"),
1519 											   debugger->priv->output_user_data);
1520 				}
1521 				else if (str && strcmp (str, "end-stepping-range") == 0)
1522 				{
1523 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1524 										   _("Stepping finished\n"),
1525 										   debugger->priv->output_user_data);
1526 				}
1527 				else if (str && strcmp (str, "location-reached") == 0)
1528 				{
1529 					debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
1530 										   _("Location reached\n"),
1531 											   debugger->priv->output_user_data);
1532 				}
1533 			}
1534 		}
1535 
1536 		if (program_exited)
1537 		{
1538 			debugger->priv->prog_is_running = FALSE;
1539 			debugger->priv->prog_is_attached = FALSE;
1540 			debugger_handle_post_execution (debugger);
1541 			debugger->priv->exiting = TRUE;
1542 		}
1543 		else
1544 		{
1545 //			g_signal_emit_by_name (debugger->priv->instance, "program-stopped");
1546 			debugger->priv->stopping = TRUE;
1547 		}
1548 
1549 		debugger->priv->cli_lines = g_list_reverse (debugger->priv->cli_lines);
1550 		if ((debugger->priv->current_cmd.cmd != NULL) &&
1551 			(debugger->priv->current_cmd.parser != NULL))
1552 		{
1553 			debugger->priv->current_cmd.parser (debugger, val,
1554 												debugger->priv->cli_lines, FALSE);
1555 			debugger->priv->command_output_sent = TRUE;
1556 			DEBUG_PRINT ("%s", "In function: Sending output…");
1557 		}
1558 
1559 		if (val)
1560 			gdbmi_value_free (val);
1561 	}
1562 }
1563 
1564 static void
debugger_parse_prompt(Debugger * debugger)1565 debugger_parse_prompt (Debugger *debugger)
1566 {
1567 	/* If the parser has not yet been called, call it now. */
1568 	if (debugger->priv->command_output_sent == FALSE &&
1569 		debugger->priv->current_cmd.parser)
1570 	{
1571 		debugger->priv->current_cmd.parser (debugger, NULL,
1572 											debugger->priv->cli_lines, FALSE);
1573 		debugger->priv->command_output_sent = TRUE;
1574 	}
1575 
1576 	debugger->priv->debugger_is_busy--;
1577 	debugger_queue_execute_command (debugger);	/* Next command. Go. */
1578 	debugger_emit_ready (debugger);
1579 }
1580 
1581 static gboolean
parse_breakpoint(IAnjutaDebuggerBreakpointItem * bp,const GDBMIValue * brkpnt)1582 parse_breakpoint (IAnjutaDebuggerBreakpointItem* bp, const GDBMIValue *brkpnt)
1583 {
1584 	const GDBMIValue *literal;
1585 	const gchar* value;
1586 
1587 	memset (bp, 0, sizeof (*bp));
1588 
1589 	literal = gdbmi_value_hash_lookup (brkpnt, "number");
1590 	if (literal)
1591 	{
1592 		value = gdbmi_value_literal_get (literal);
1593 		bp->id = strtoul (value, NULL, 10);
1594 	}
1595 
1596 	bp->file = (gchar *)debugger_parse_filename (brkpnt);
1597 
1598 	literal = gdbmi_value_hash_lookup (brkpnt, "line");
1599 	if (literal)
1600 	{
1601 		value = gdbmi_value_literal_get (literal);
1602 		bp->line = strtoul (value, NULL, 10);
1603 		bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_LINE;
1604 	}
1605 
1606 	literal = gdbmi_value_hash_lookup (brkpnt, "type");
1607 	if (literal)
1608 	{
1609 		value = gdbmi_value_literal_get (literal);
1610 	}
1611 
1612 	literal = gdbmi_value_hash_lookup (brkpnt, "disp");
1613 	if (literal)
1614 	{
1615 		value = gdbmi_value_literal_get (literal);
1616 		if (strcmp (value, "keep") == 0)
1617 		{
1618 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TEMPORARY;
1619 			bp->temporary = FALSE;
1620 		}
1621 		else if ((strcmp (value, "nokeep") == 0) || (strcmp (value, "del") == 0))
1622 		{
1623 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TEMPORARY;
1624 			bp->temporary = TRUE;
1625 		}
1626 	}
1627 
1628 	literal = gdbmi_value_hash_lookup (brkpnt, "enabled");
1629 	if (literal)
1630 	{
1631 		value = gdbmi_value_literal_get (literal);
1632 		if (strcmp (value, "n") == 0)
1633 		{
1634 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_ENABLE;
1635 			bp->enable = FALSE;
1636 		}
1637 		else if (strcmp (value, "y") == 0)
1638 		{
1639 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_ENABLE;
1640 			bp->enable = TRUE;
1641 		}
1642 	}
1643 
1644 	literal = gdbmi_value_hash_lookup (brkpnt, "addr");
1645 	if (literal)
1646 	{
1647 		value = gdbmi_value_literal_get (literal);
1648 		if (strcmp (value, "<PENDING>") == 0)
1649 		{
1650 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_PENDING;
1651 			bp->pending = TRUE;
1652 		}
1653 		else
1654 		{
1655 			bp->address = strtoul (value, NULL, 16);
1656 			bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_ADDRESS;
1657 			bp->pending = FALSE;
1658 		}
1659 	}
1660 
1661 	literal = gdbmi_value_hash_lookup (brkpnt, "func");
1662 	if (literal)
1663 	{
1664 		value = gdbmi_value_literal_get (literal);
1665 		bp->function = (gchar *)value;
1666 		bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_ON_FUNCTION;
1667 	}
1668 
1669 	literal = gdbmi_value_hash_lookup (brkpnt, "times");
1670 	if (literal)
1671 	{
1672 		value = gdbmi_value_literal_get (literal);
1673 		bp->times = strtoul (value, NULL, 10);
1674 		bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_TIME;
1675 	}
1676 	DEBUG_PRINT("parse time %d", bp->times);
1677 
1678 	literal = gdbmi_value_hash_lookup (brkpnt, "ignore");
1679 	if (literal)
1680 	{
1681 		value = gdbmi_value_literal_get (literal);
1682 		bp->ignore = strtoul (value, NULL, 10);
1683 		bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_IGNORE;
1684 	}
1685 
1686 	literal = gdbmi_value_hash_lookup (brkpnt, "cond");
1687 	if (literal)
1688 	{
1689 		value = gdbmi_value_literal_get (literal);
1690 		bp->condition = (gchar *)value;
1691 		bp->type |= IANJUTA_DEBUGGER_BREAKPOINT_WITH_CONDITION;
1692 	}
1693 
1694 	return TRUE;
1695 }
1696 
1697 static void
debugger_stdo_flush(Debugger * debugger)1698 debugger_stdo_flush (Debugger *debugger)
1699 {
1700 	gchar *line;
1701 
1702 	line = debugger->priv->stdo_line->str;
1703 
1704 	#ifdef DEBUG
1705 		DEBUG_PRINT ("GDB:< %s", line);
1706 	#else
1707 		if (debugger->priv->gdb_log) g_message ("GDB:< %s", line);
1708 	#endif
1709 	debugger_log_output (debugger, line);
1710 	if (strlen (line) == 0)
1711 	{
1712 		return;
1713 	}
1714 	if (strncasecmp (line, "^error", 6) == 0)
1715 	{
1716 		/* GDB reported error */
1717 		if ((debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT)  || (debugger->priv->stdo_acc->len != 0))
1718 		{
1719 			/* Keep result for next command */
1720 
1721 			if (debugger->priv->stdo_acc->len == 0)
1722 			{
1723 				g_string_append (debugger->priv->stdo_acc, line);
1724 			}
1725 			else
1726 			{
1727 				line = strchr (line, ',');
1728 				if (line != NULL)
1729 				{
1730 					g_string_append (debugger->priv->stdo_acc, line);
1731 				}
1732 			}
1733 			line = debugger->priv->stdo_acc->str;
1734 		}
1735 
1736 		GDBMIValue *val = gdbmi_value_parse (line);
1737 		GError *error;
1738 
1739 		error = gdb_parse_error (debugger, val);
1740 
1741 		/* Trap state error */
1742 		if ((error != NULL) && ((error->code == IANJUTA_DEBUGGER_PROGRAM_NOT_FOUND) ||
1743 								(error->code == IANJUTA_DEBUGGER_UNABLE_TO_CONNECT)))
1744 		{
1745 			debugger->priv->prog_is_running = FALSE;
1746 			debugger->priv->prog_is_attached = FALSE;
1747 			debugger->priv->prog_is_remote = FALSE;
1748 			debugger->priv->prog_is_loaded = FALSE;
1749 		}
1750 
1751 		if (debugger->priv->current_cmd.parser != NULL)
1752 		{
1753 			debugger->priv->current_cmd.parser (debugger, val, debugger->priv->cli_lines, error);
1754 			debugger->priv->command_output_sent = TRUE;				}
1755 		DEBUG_PRINT("GDB: error %s", error->message);
1756 		/*else
1757 		{
1758 			anjuta_util_dialog_error (debugger->priv->parent_win, "%s", error->message);
1759 		}*/
1760 		g_error_free (error);
1761 		gdbmi_value_free (val);
1762 	}
1763 	else if (strncasecmp(line, "^running", 8) == 0)
1764 	{
1765 		/* Program started running */
1766 		debugger->priv->prog_is_running = TRUE;
1767 		/* debugger->priv->skip_next_prompt = TRUE; Replaced by debugger_is_busy++ */
1768 		debugger->priv->debugger_is_busy++;
1769 		g_signal_emit_by_name (debugger->priv->instance, "program-running");
1770 	}
1771 	else if (strncasecmp (line, "*stopped", 8) == 0)
1772 	{
1773 		/* Process has stopped */
1774 		debugger_parse_stopped (debugger);
1775 	}
1776 	else if (strncasecmp (line, "^done", 5) == 0)
1777 	{
1778 		if ((debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT)  || (debugger->priv->stdo_acc->len != 0))
1779 		{
1780 			/* Keep result for next command */
1781 
1782 			if (debugger->priv->stdo_acc->len == 0)
1783 			{
1784 				g_string_append (debugger->priv->stdo_acc, line);
1785 			}
1786 			else
1787 			{
1788 				line = strchr (line, ',');
1789 				if (line != NULL)
1790 				{
1791 					g_string_append (debugger->priv->stdo_acc, line);
1792 				}
1793 			}
1794 			line = debugger->priv->stdo_acc->str;
1795 		}
1796 
1797 	  	if (!(debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT))
1798 		{
1799 			/* GDB command has reported output */
1800 			GDBMIValue *val = gdbmi_value_parse (line);
1801 
1802 			debugger->priv->cli_lines = g_list_reverse (debugger->priv->cli_lines);
1803 			if ((debugger->priv->current_cmd.cmd != NULL) &&
1804 				(debugger->priv->current_cmd.parser != NULL))
1805 			{
1806 				debugger->priv->current_cmd.parser (debugger, val,
1807 										  debugger->priv->cli_lines, FALSE);
1808 				debugger->priv->command_output_sent = TRUE;
1809 				DEBUG_PRINT ("%s", "In function: Sending output…");
1810 			}
1811 			else /* if (val) */
1812 			{
1813 				/*g_signal_emit_by_name (debugger, "results-arrived",
1814 								   debugger->priv->current_cmd.cmd, val);*/
1815 			}
1816 
1817 			if (val)
1818 			{
1819 				/*debugger_process_frame (debugger, val);*/
1820 				gdbmi_value_free (val);
1821 			}
1822 		}
1823 
1824 		if (!(debugger->priv->current_cmd.flags & DEBUGGER_COMMAND_KEEP_RESULT))
1825 		{
1826 			g_string_assign (debugger->priv->stdo_acc, "");
1827 		}
1828 	}
1829 	else if (strncasecmp (line, GDB_PROMPT, strlen (GDB_PROMPT)) == 0)
1830 	{
1831 		debugger_parse_prompt (debugger);
1832 	}
1833 	else
1834 	{
1835 		debugger_parse_output (debugger);
1836 	}
1837 
1838 	/* Clear the line buffer */
1839 	g_string_assign (debugger->priv->stdo_line, "");
1840 }
1841 
1842 void
debugger_stde_flush(Debugger * debugger)1843 debugger_stde_flush (Debugger *debugger)
1844 {
1845 	if ((debugger->priv->output_callback) && (strlen (debugger->priv->stde_line->str) > 0))
1846 	{
1847 		debugger->priv->output_callback (IANJUTA_DEBUGGER_ERROR_OUTPUT,
1848 								   debugger->priv->stde_line->str,
1849 								   debugger->priv->output_user_data);
1850 	}
1851 	/* Clear the line buffer */
1852 	g_string_assign (debugger->priv->stde_line, "");
1853 }
1854 
1855 static void
on_gdb_terminated(AnjutaLauncher * launcher,gint child_pid,gint status,gulong t,gpointer data)1856 on_gdb_terminated (AnjutaLauncher *launcher,
1857 				   gint child_pid, gint status, gulong t,
1858 				   gpointer data)
1859 {
1860 	Debugger *debugger = DEBUGGER (data);
1861 	GError *err = NULL;
1862 
1863 	g_signal_handlers_disconnect_by_func (G_OBJECT (launcher),
1864 										  G_CALLBACK (on_gdb_terminated),
1865 										  debugger);
1866 
1867 	DEBUG_PRINT ("%s", "In function: gdb_terminated()");
1868 
1869 	/* Clear the command queue & Buffer */
1870 	debugger_clear_buffers (debugger);
1871 
1872 	/* Good Bye message */
1873 	/*if (!debugger->priv->terminating)
1874 	{
1875 		anjuta_util_dialog_error (debugger->priv->parent_win,
1876 		_("gdb terminated unexpectedly with status %d\n"), status);
1877 	}*/
1878 	debugger->priv->prog_is_running = FALSE;
1879 	debugger->priv->prog_is_attached = FALSE;
1880 	debugger->priv->prog_is_loaded = FALSE;
1881 	debugger->priv->prog_is_remote = FALSE;
1882 	debugger->priv->debugger_is_busy = 0;
1883 	debugger->priv->skip_next_prompt = FALSE;
1884 
1885 	if (!debugger->priv->terminating)
1886 	{
1887 		err = g_error_new  (IANJUTA_DEBUGGER_ERROR,
1888 				IANJUTA_DEBUGGER_OTHER_ERROR,
1889 				"gdb terminated with status %d", status);
1890 	}
1891 	debugger->priv->terminating = FALSE;
1892 	debugger->priv->debugger_is_started = FALSE;
1893 	if (debugger->priv->instance)
1894 	{
1895 		g_signal_emit_by_name (debugger->priv->instance, "debugger-stopped", err);
1896 	}
1897 	if (err != NULL) g_error_free (err);
1898 }
1899 
1900 static void
debugger_stop_real(Debugger * debugger)1901 debugger_stop_real (Debugger *debugger)
1902 {
1903 	DEBUG_PRINT ("%s", "In function: debugger_stop_real()");
1904 
1905 	/* if program is attached - detach from it before quiting */
1906 	if (debugger->priv->prog_is_attached == TRUE)
1907 	{
1908 		debugger_detach_process(debugger);
1909 	}
1910 
1911 	debugger->priv->terminating = TRUE;
1912 	debugger_queue_command (debugger, "-gdb-exit", 0, NULL, NULL, NULL);
1913 }
1914 
1915 gboolean
debugger_stop(Debugger * debugger)1916 debugger_stop (Debugger *debugger)
1917 {
1918 #if 0
1919 	gboolean ret = TRUE;
1920 
1921 	if (debugger->priv->prog_is_running == TRUE)
1922 	{
1923 		GtkWidget *dialog;
1924 		gchar *mesg;
1925 
1926 		if (debugger->priv->prog_is_attached == TRUE)
1927 			mesg = _("The program is attached.\n"
1928 				   "Do you still want to stop the debugger?");
1929 		else
1930 			mesg = _("The program is running.\n"
1931 				   "Do you still want to stop the debugger?");
1932 		dialog = gtk_message_dialog_new (debugger->priv->parent_win,
1933 										 GTK_DIALOG_DESTROY_WITH_PARENT,
1934 										 GTK_MESSAGE_QUESTION,
1935 										 GTK_BUTTONS_NONE, mesg);
1936 		gtk_dialog_add_buttons (GTK_DIALOG (dialog),
1937 								GTK_STOCK_CANCEL,	GTK_RESPONSE_NO,
1938 								GTK_STOCK_STOP,		GTK_RESPONSE_YES,
1939 								NULL);
1940 		if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
1941 			debugger_stop_real (debugger);
1942 		else
1943 			ret = FALSE;
1944 		gtk_widget_destroy (dialog);
1945 	}
1946 	else
1947 		debugger_stop_real (debugger);
1948 	return ret;
1949 #endif
1950 	debugger_stop_real (debugger);
1951 
1952 	return TRUE;
1953 }
1954 
1955 gboolean
debugger_abort(Debugger * debugger)1956 debugger_abort (Debugger *debugger)
1957 {
1958 	DEBUG_PRINT ("%s", "In function: debugger_abort()");
1959 
1960 	/* Stop inferior */
1961 	if ((debugger->priv->prog_is_attached == FALSE) && (debugger->priv->inferior_pid != 0))
1962 	{
1963 		kill (debugger->priv->inferior_pid, SIGTERM);
1964 		debugger->priv->inferior_pid = 0;
1965 	}
1966 
1967 	/* Stop gdb */
1968 	debugger->priv->terminating = TRUE;
1969 	g_signal_handlers_disconnect_by_func (G_OBJECT (debugger->priv->launcher), G_CALLBACK (on_gdb_terminated), debugger);
1970 	anjuta_launcher_reset (debugger->priv->launcher);
1971 
1972 	/* Free memory */
1973 	debugger_queue_clear (debugger);
1974 	g_list_foreach (debugger->priv->search_dirs, (GFunc)g_free, NULL);
1975 	g_list_free (debugger->priv->search_dirs);
1976 	debugger->priv->search_dirs = NULL;
1977 
1978 	/* Emit signal, state of the debugger must be DEBUGGER_STOPPED */
1979 	debugger->priv->prog_is_running = FALSE;
1980 	debugger->priv->prog_is_attached = FALSE;
1981 	debugger->priv->inferior_pid = 0;
1982 	debugger->priv->prog_is_loaded = FALSE;
1983 	debugger->priv->prog_is_remote = FALSE;
1984 	debugger->priv->debugger_is_busy = 0;
1985 	debugger->priv->debugger_is_started = FALSE;
1986 
1987 	if (debugger->priv->instance != NULL)
1988 	{
1989 		/* debugger-stopped triggers a call to debugger_free that
1990 		 * will free the debugger instance, so no access to it is
1991 		 * allowed after the following line */
1992 		g_signal_emit_by_name (debugger->priv->instance, "debugger-stopped", NULL);
1993 	}
1994 
1995 	return TRUE;
1996 }
1997 
1998 gchar*
debugger_get_source_path(Debugger * debugger,const gchar * file)1999 debugger_get_source_path (Debugger *debugger, const gchar *file)
2000 {
2001 	GList *node;
2002 	gchar *path = NULL;
2003 
2004 	if (g_path_is_absolute (file))
2005 		return g_strdup (file);
2006 
2007 	node = debugger->priv->search_dirs;
2008 	while (node)
2009 	{
2010 		path = g_build_filename (node->data, file, NULL);
2011 		if (g_file_test (path, G_FILE_TEST_EXISTS))
2012 			break;
2013 		g_free (path);
2014 		path = NULL;
2015 		node = g_list_next (node);
2016 	}
2017 
2018 	if (path == NULL)
2019 	{
2020 		/* The file could be found nowhere. Use current directory */
2021 		gchar *cwd;
2022 		cwd = anjuta_util_get_current_dir ();
2023 		path = g_build_filename (cwd, file, NULL);
2024 		g_free (cwd);
2025 	}
2026 	return path;
2027 }
2028 
2029 void
debugger_set_output_callback(Debugger * debugger,IAnjutaDebuggerOutputCallback callback,gpointer user_data)2030 debugger_set_output_callback (Debugger *debugger, IAnjutaDebuggerOutputCallback callback, gpointer user_data)
2031 {
2032 	debugger->priv->output_callback = callback;
2033 	debugger->priv->output_user_data = user_data;
2034 }
2035 
2036 void
debugger_program_moved(Debugger * debugger,const gchar * file,gint line,gulong address)2037 debugger_program_moved (Debugger *debugger, const gchar *file,
2038 						  gint line, gulong address)
2039 {
2040 	gchar *src_path;
2041 
2042 	if ((file != NULL) && (*file != G_DIR_SEPARATOR))
2043 	{
2044 		src_path = debugger_get_source_path (debugger, file);
2045 		g_signal_emit_by_name (debugger->priv->instance, "program-moved", debugger->priv->inferior_pid, debugger->priv->current_thread, address, src_path, line);
2046 		g_free (src_path);
2047 	}
2048 	else
2049 	{
2050 		g_signal_emit_by_name (debugger->priv->instance, "program-moved", debugger->priv->inferior_pid, debugger->priv->current_thread, address, file, line);
2051 	}
2052 }
2053 
2054 static void
debugger_info_program_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2055 debugger_info_program_finish (Debugger *debugger, const GDBMIValue *mi_results,
2056 								const GList *cli_results, GError *error)
2057 {
2058 	DEBUG_PRINT ("%s", "In function: debugger_info_program()");
2059 
2060 	/* Hack: find message string giving inferior pid */
2061 	while (cli_results != NULL)
2062 	{
2063 		gchar* child_proc;
2064 
2065 		child_proc = strstr(cli_results->data, " child process ");
2066 		if (child_proc != NULL)
2067 		{
2068 			debugger->priv->inferior_pid = strtoul (child_proc + 15, NULL, 10);
2069 			break;
2070 		}
2071 		cli_results = g_list_next (cli_results);
2072 	}
2073 }
2074 
2075 static void
debugger_is_connected(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2076 debugger_is_connected (Debugger *debugger, const GDBMIValue *mi_results,
2077 								const GList *cli_results, GError *error)
2078 {
2079 	g_return_if_fail (debugger->priv->remote_server != NULL);
2080 
2081 	if (error != NULL)
2082 	{
2083 		gchar *msg;
2084 		gboolean retry;
2085 
2086 		/* The %s argument is an error message returned by gdb.
2087 		 * It is something like, "No such file or directory" */
2088 		msg = g_strdup_printf(_("Unable to connect to remote target, %s\nDo you want to try again?"),
2089 							  error->message);
2090 		retry = anjuta_util_dialog_boolean_question (debugger->priv->parent_win, FALSE, msg);
2091 		g_free (msg);
2092 		if (retry)
2093 		{
2094 			gchar *cmd;
2095 
2096 			cmd = g_strconcat ("-target-select remote ", debugger->priv->remote_server, NULL);
2097 			debugger_queue_command (debugger, cmd, 0, debugger_is_connected, NULL, NULL);
2098 			g_free (cmd);
2099 		}
2100 	}
2101 	else
2102 	{
2103 		if (debugger->priv->output_callback)
2104 		{
2105 			debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2106 										 _("Debugger connected\n"),
2107 										 debugger->priv->output_user_data);
2108 		}
2109 		debugger->priv->prog_is_remote = TRUE;
2110 		debugger->priv->prog_is_running = TRUE;
2111 		/* It is not really a shared lib event, but it allows to restart
2112 	 	* the program after setting breakpoints. It is better to restart
2113 	 	* it because we don't have the normal stop frame that tell where
2114 	 	* the program is stopped */
2115 		debugger->priv->solib_event = TRUE;
2116 	}
2117 }
2118 
2119 void
debugger_start_program(Debugger * debugger,const gchar * remote,const gchar * args,const gchar * tty,gboolean stop)2120 debugger_start_program (Debugger *debugger, const gchar *remote, const gchar* args, const gchar* tty, gboolean stop)
2121 {
2122 	gchar *cmd;
2123 
2124 	DEBUG_PRINT ("%s", "In function: debugger_start_program()");
2125 
2126 	g_return_if_fail (IS_DEBUGGER (debugger));
2127 	g_return_if_fail (debugger->priv->prog_is_running == FALSE);
2128 
2129 
2130 	/* Without a terminal, the output of the debugged program
2131 	 * are lost */
2132 	if (tty)
2133 	{
2134 		cmd = g_strdup_printf ("-inferior-tty-set %s", tty);
2135 		debugger_queue_command (debugger, cmd, 0, NULL, NULL, NULL);
2136 		g_free (cmd);
2137 	}
2138 
2139 	debugger->priv->inferior_pid = 0;
2140 	if (stop)
2141 	{
2142 		debugger_queue_command (debugger, "-break-insert -t main", 0, NULL, NULL, NULL);
2143 	}
2144 	if (args && (*args))
2145 	{
2146 		cmd = g_strconcat ("-exec-arguments ", args, NULL);
2147 		debugger_queue_command (debugger, cmd, 0, NULL, NULL, NULL);
2148 		g_free (cmd);
2149 	}
2150 
2151 	/* If we are remote then we have to just continue here since we always
2152 	 * get stopped as part of the remote target setup.
2153 	 */
2154 	g_free (debugger->priv->remote_server);
2155 	if (remote != NULL)
2156 	{
2157 		debugger->priv->remote_server = g_strdup (remote);
2158 		cmd = g_strconcat ("-target-select remote ", remote, NULL);
2159 		debugger_queue_command (debugger, cmd, 0, debugger_is_connected, NULL, NULL);
2160 		g_free (cmd);
2161 	}
2162 	else
2163 	{
2164 		debugger_queue_command (debugger, "-exec-run", 0, NULL, NULL, NULL);
2165 
2166 		/* Get pid of program on next stop */
2167 		debugger_queue_command (debugger, "info program", 0, debugger_info_program_finish, NULL, NULL);
2168 		debugger->priv->post_execution_flag = DEBUGGER_NONE;
2169 	}
2170 }
2171 
2172 static void
debugger_attach_process_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2173 debugger_attach_process_finish (Debugger *debugger, const GDBMIValue *mi_results,
2174 								const GList *cli_results, GError *error)
2175 {
2176 	DEBUG_PRINT ("%s", "Program attach finished");
2177 	if (debugger->priv->output_callback)
2178 	{
2179 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2180 									 _("Program attached\n"),
2181 									 debugger->priv->output_user_data);
2182 	}
2183 	debugger->priv->prog_is_attached = TRUE;
2184 	debugger->priv->prog_is_running = TRUE;
2185 	/* It is not really a shared lib event, but it allows to restart
2186 	 * the program after setting breakpoints. It is better to restart
2187 	 * it because we don't have the normal stop frame that tell where
2188 	 * the program is stopped */
2189 	debugger->priv->solib_event = TRUE;
2190 }
2191 
2192 static void
debugger_attach_process_real(Debugger * debugger,pid_t pid)2193 debugger_attach_process_real (Debugger *debugger, pid_t pid)
2194 {
2195 	gchar *buff;
2196 
2197 	DEBUG_PRINT ("%s", "In function: debugger_attach_process_real()");
2198 
2199 	if (debugger->priv->output_callback)
2200 	{
2201 		buff = g_strdup_printf (_("Attaching to process: %d…\n"), pid);
2202 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2203 							   buff, debugger->priv->output_user_data);
2204 		g_free (buff);
2205 	}
2206 
2207 	debugger->priv->inferior_pid = pid;
2208 	buff = g_strdup_printf ("attach %d", pid);
2209 	debugger_queue_command (debugger, buff, 0,
2210 							debugger_attach_process_finish, NULL, NULL);
2211 	g_free (buff);
2212 }
2213 
2214 void
debugger_attach_process(Debugger * debugger,pid_t pid)2215 debugger_attach_process (Debugger *debugger, pid_t pid)
2216 {
2217 	DEBUG_PRINT ("%s", "In function: debugger_attach_process()");
2218 
2219 	g_return_if_fail (IS_DEBUGGER (debugger));
2220 
2221 	if (debugger->priv->prog_is_running == TRUE)
2222 	{
2223 		// TODO: Dialog to be made HIG compliant.
2224 		gchar *mesg;
2225 		GtkWidget *dialog;
2226 
2227 		mesg = _("A process is already running.\n"
2228 				 "Would you like to terminate it and attach the new process?"),
2229 		dialog = gtk_message_dialog_new (debugger->priv->parent_win,
2230 										 GTK_DIALOG_DESTROY_WITH_PARENT,
2231 										 GTK_MESSAGE_QUESTION,
2232 										 GTK_BUTTONS_YES_NO, "%s", mesg);
2233 		if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
2234 		{
2235 			debugger_stop_program (debugger);
2236 			debugger_attach_process_real (debugger, pid);
2237 		}
2238 		gtk_widget_destroy (dialog);
2239 	}
2240 	else if (getpid () == pid ||
2241 			 anjuta_launcher_get_child_pid (debugger->priv->launcher) == pid)
2242 	{
2243 		anjuta_util_dialog_error (debugger->priv->parent_win,
2244 								  _("Anjuta is unable to attach to itself."));
2245 		return;
2246 	}
2247 	else
2248 		debugger_attach_process_real (debugger, pid);
2249 }
2250 
2251 void
debugger_restart_program(Debugger * debugger)2252 debugger_restart_program (Debugger *debugger)
2253 {
2254 	DEBUG_PRINT ("%s", "In function: debugger_restart_program()");
2255 
2256 	g_return_if_fail (debugger->priv->prog_is_attached == FALSE);
2257 
2258 	/*
2259 	debugger->priv->post_execution_flag = DEBUGGER_RERUN_PROGRAM;
2260 	debugger_stop_program (debugger);
2261 
2262 	debugger_put_cmd_in_queqe ("tbreak main", DB_CMD_NONE, NULL, NULL);
2263 	debugger_put_cmd_in_queqe ("run >/dev/null 2>/dev/null", DB_CMD_ALL,
2264 				   NULL, NULL);
2265 	debugger_put_cmd_in_queqe ("info program", DB_CMD_NONE,
2266 				   on_debugger_update_prog_status, NULL);
2267 	debugger_put_cmd_in_queqe ("continue", DB_CMD_NONE, NULL, NULL);
2268 	debugger_execute_cmd_in_queqe ();
2269 	*/
2270 }
2271 
2272 void
debugger_stop_program(Debugger * debugger)2273 debugger_stop_program (Debugger *debugger)
2274 {
2275 	DEBUG_PRINT ("%s", "In function: debugger_stop_program()");
2276 
2277 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2278 
2279 	if (debugger->priv->prog_is_attached == TRUE)
2280 	{
2281 		debugger_detach_process (debugger);
2282 	}
2283 	else
2284 	{
2285 		/* FIXME: Why doesn't -exec-abort work??? */
2286 		/* debugger_queue_command (debugger, "-exec-abort", NULL, NULL); */
2287 		debugger_queue_command (debugger, "kill", 0, NULL, NULL, NULL);
2288 		debugger->priv->prog_is_running = FALSE;
2289 		debugger->priv->prog_is_attached = FALSE;
2290 		g_signal_emit_by_name (debugger->priv->instance, "program-exited");
2291 		if (debugger->priv->output_callback)
2292 		{
2293 			debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2294 								   _("Program terminated\n"),
2295 								   debugger->priv->output_user_data);
2296 		}
2297 		debugger_handle_post_execution (debugger);
2298 	}
2299 }
2300 
2301 static void
debugger_detach_process_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2302 debugger_detach_process_finish (Debugger *debugger, const GDBMIValue *mi_results,
2303 								const GList *cli_results, GError *error)
2304 {
2305 	DEBUG_PRINT ("%s", "Program detach finished");
2306 	if (debugger->priv->output_callback)
2307 	{
2308 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2309 									 _("Program detached\n"),
2310 									 debugger->priv->output_user_data);
2311 	}
2312 	debugger->priv->inferior_pid = 0;
2313 	debugger->priv->prog_is_attached = FALSE;
2314 	debugger->priv->prog_is_running = FALSE;
2315 	g_signal_emit_by_name (debugger->priv->instance, "program-exited");
2316 }
2317 
2318 void
debugger_detach_process(Debugger * debugger)2319 debugger_detach_process (Debugger *debugger)
2320 {
2321 	gchar *buff;
2322 
2323 	DEBUG_PRINT ("%s", "In function: debugger_detach_process()");
2324 
2325 	g_return_if_fail (debugger->priv->prog_is_attached == TRUE);
2326 
2327 	if (debugger->priv->output_callback)
2328 	{
2329 		buff = g_strdup_printf (_("Detaching the process…\n"));
2330 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2331 							   buff, debugger->priv->output_user_data);
2332 		g_free (buff);
2333 	}
2334 
2335 	debugger_queue_command (debugger, "detach", 0,
2336 							debugger_detach_process_finish, NULL, NULL);
2337 }
2338 
2339 void
debugger_interrupt(Debugger * debugger)2340 debugger_interrupt (Debugger *debugger)
2341 {
2342 	DEBUG_PRINT ("%s", "In function: debugger_interrupt()");
2343 
2344 	g_message ("debugger_interrupt inferiod_pid %d", debugger->priv->inferior_pid);
2345 
2346 	g_return_if_fail (IS_DEBUGGER (debugger));
2347 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2348 
2349 	if (debugger->priv->output_callback)
2350 	{
2351 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
2352 							   _("Interrupting the process\n"),
2353 							   debugger->priv->output_user_data);
2354 	}
2355 
2356 	if (debugger->priv->inferior_pid == 0)
2357 	{
2358 		/* In case we do not have the inferior pid, send signal to gdb */
2359 		anjuta_launcher_signal (debugger->priv->launcher, SIGINT);
2360 	}
2361 	else
2362 	{
2363 		/* Send signal directly to inferior */
2364 		kill (debugger->priv->inferior_pid, SIGINT);
2365 	}
2366 	//g_signal_emit_by_name (debugger->priv->instance, "program-running");
2367 }
2368 
2369 void
debugger_run(Debugger * debugger)2370 debugger_run (Debugger *debugger)
2371 {
2372 	DEBUG_PRINT ("%s", "In function: debugger_run()");
2373 
2374 	g_return_if_fail (IS_DEBUGGER (debugger));
2375 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2376 
2377 	/* Program running - continue */
2378 	debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2379 }
2380 
2381 void
debugger_step_in(Debugger * debugger)2382 debugger_step_in (Debugger *debugger)
2383 {
2384 	DEBUG_PRINT ("%s", "In function: debugger_step_in()");
2385 
2386 	g_return_if_fail (IS_DEBUGGER (debugger));
2387 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2388 
2389 	debugger_queue_command (debugger, "-exec-step", 0, NULL, NULL, NULL);
2390 }
2391 
2392 void
debugger_step_over(Debugger * debugger)2393 debugger_step_over (Debugger *debugger)
2394 {
2395 	DEBUG_PRINT ("%s", "In function: debugger_step_over()");
2396 
2397 	g_return_if_fail (IS_DEBUGGER (debugger));
2398 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2399 
2400 	debugger_queue_command (debugger, "-exec-next", 0, NULL, NULL, NULL);
2401 }
2402 
2403 void
debugger_step_out(Debugger * debugger)2404 debugger_step_out (Debugger *debugger)
2405 {
2406 	DEBUG_PRINT ("%s", "In function: debugger_step_out()");
2407 
2408 	g_return_if_fail (IS_DEBUGGER (debugger));
2409 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2410 
2411 	debugger_queue_command (debugger, "-exec-finish", 0, NULL, NULL, NULL);
2412 }
2413 
2414 void
debugger_stepi_in(Debugger * debugger)2415 debugger_stepi_in (Debugger *debugger)
2416 {
2417 	DEBUG_PRINT ("%s", "In function: debugger_step_in()");
2418 
2419 	g_return_if_fail (IS_DEBUGGER (debugger));
2420 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2421 
2422 	debugger_queue_command (debugger, "-exec-step-instruction", 0, NULL, NULL, NULL);
2423 }
2424 
2425 void
debugger_stepi_over(Debugger * debugger)2426 debugger_stepi_over (Debugger *debugger)
2427 {
2428 	DEBUG_PRINT ("%s", "In function: debugger_step_over()");
2429 
2430 	g_return_if_fail (IS_DEBUGGER (debugger));
2431 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2432 
2433 	debugger_queue_command (debugger, "-exec-next-instruction", 0, NULL, NULL, NULL);
2434 }
2435 
2436 void
debugger_run_to_location(Debugger * debugger,const gchar * loc)2437 debugger_run_to_location (Debugger *debugger, const gchar *loc)
2438 {
2439 	gchar *buff;
2440 
2441 	DEBUG_PRINT ("%s", "In function: debugger_run_to_location()");
2442 
2443 	g_return_if_fail (IS_DEBUGGER (debugger));
2444 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2445 
2446 	buff = g_strdup_printf ("-exec-until %s", loc);
2447 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2448 	g_free (buff);
2449 }
2450 
2451 void
debugger_run_to_position(Debugger * debugger,const gchar * file,guint line)2452 debugger_run_to_position (Debugger *debugger, const gchar *file, guint line)
2453 {
2454 	gchar *buff;
2455 	gchar *quoted_file;
2456 
2457 	DEBUG_PRINT ("%s", "In function: debugger_run_to_position()");
2458 
2459 	g_return_if_fail (IS_DEBUGGER (debugger));
2460 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2461 
2462 	quoted_file = gdb_quote (file);
2463 	buff = g_strdup_printf ("-break-insert -t %s \"\\\"%s\\\":%u\"",
2464 							debugger->priv->has_pending_breakpoints ? "-f" : "",
2465 							quoted_file, line);
2466 	g_free (quoted_file);
2467 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2468 	g_free (buff);
2469 	debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2470 }
2471 
2472 void
debugger_run_from_position(Debugger * debugger,const gchar * file,guint line)2473 debugger_run_from_position (Debugger *debugger, const gchar *file, guint line)
2474 {
2475 	gchar *buff;
2476 	gchar *quoted_file;
2477 
2478 	DEBUG_PRINT ("%s", "In function: debugger_run_from_position()");
2479 
2480 	g_return_if_fail (IS_DEBUGGER (debugger));
2481 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2482 
2483 	quoted_file = gdb_quote (file);
2484 	buff = g_strdup_printf ("-exec-jump \"\\\"%s\\\":%u\"",
2485 							quoted_file, line);
2486 	g_free (quoted_file);
2487 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2488 	g_free (buff);
2489 }
2490 
2491 void
debugger_run_to_address(Debugger * debugger,gulong address)2492 debugger_run_to_address (Debugger *debugger, gulong address)
2493 {
2494 	gchar *buff;
2495 
2496 	DEBUG_PRINT ("%s", "In function: debugger_run_to_address()");
2497 
2498 	g_return_if_fail (IS_DEBUGGER (debugger));
2499 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2500 
2501 	buff = g_strdup_printf ("-break-insert -t %s *0x%lx",
2502 							debugger->priv->has_pending_breakpoints ? "-f" : "",
2503 							address);
2504 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2505 	g_free (buff);
2506 	debugger_queue_command (debugger, "-exec-continue", 0, NULL, NULL, NULL);
2507 }
2508 
2509 void
debugger_run_from_address(Debugger * debugger,gulong address)2510 debugger_run_from_address (Debugger *debugger, gulong address)
2511 {
2512 	gchar *buff;
2513 
2514 	DEBUG_PRINT ("%s", "In function: debugger_run_from_address()");
2515 
2516 	g_return_if_fail (IS_DEBUGGER (debugger));
2517 	g_return_if_fail (debugger->priv->prog_is_running == TRUE);
2518 
2519 	buff = g_strdup_printf ("-exec-jump *0x%lx", address);
2520 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
2521 	g_free (buff);
2522 }
2523 
2524 void
debugger_command(Debugger * debugger,const gchar * command,gboolean suppress_error,DebuggerParserFunc parser,gpointer user_data)2525 debugger_command (Debugger *debugger, const gchar *command,
2526 				  gboolean suppress_error, DebuggerParserFunc parser,
2527 				  gpointer user_data)
2528 {
2529 	if (strncasecmp (command, "-exec-run",
2530 					 strlen ("-exec-run")) == 0 ||
2531 		strncasecmp (command, "run", strlen ("run")) == 0)
2532 	{
2533 		/* FIXME: The user might have passed args to the command */
2534 		debugger_run (debugger);
2535 	}
2536 	else if (strncasecmp (command, "-exec-step",
2537 						  strlen ("-exec-step")) == 0 ||
2538 			 strncasecmp (command, "step", strlen ("step")) == 0)
2539 	{
2540 		debugger_step_in (debugger);
2541 	}
2542 	else if (strncasecmp (command, "-exec-next",
2543 						  strlen ("-exec-next")) == 0 ||
2544 			 strncasecmp (command, "next", strlen ("next")) == 0)
2545 	{
2546 		debugger_step_over (debugger);
2547 	}
2548 	else if (strncasecmp (command, "-exec-finish",
2549 						  strlen ("-exec-finish")) == 0 ||
2550 			 strncasecmp (command, "finish", strlen ("finish")) == 0)
2551 	{
2552 		debugger_step_out (debugger);
2553 	}
2554 	else if (strncasecmp (command, "-exec-continue",
2555 						  strlen ("-exec-continue")) == 0 ||
2556 			 strncasecmp (command, "continue", strlen ("continue")) == 0)
2557 	{
2558 		debugger_run (debugger);
2559 	}
2560 	else if (strncasecmp (command, "-exec-until",
2561 						  strlen ("-exec-until")) == 0 ||
2562 			 strncasecmp (command, "until", strlen ("until")) == 0)
2563 	{
2564 		debugger_run_to_location (debugger, strchr (command, ' '));
2565 	}
2566 	else if (strncasecmp (command, "-exec-abort",
2567 						  strlen ("-exec-abort")) == 0 ||
2568 			 strncasecmp (command, "kill", strlen ("kill")) == 0)
2569 	{
2570 		debugger_stop_program (debugger);
2571 	}
2572 	else if (strncasecmp (command, "-target-attach",
2573 						  strlen ("-target-attach")) == 0 ||
2574 			 strncasecmp (command, "attach", strlen ("attach")) == 0)
2575 	{
2576 		pid_t pid = 0;
2577 		gchar *pid_str = strchr (command, ' ');
2578 		if (pid_str)
2579 			pid = atoi (pid_str);
2580 		debugger_attach_process (debugger, pid);
2581 	}
2582 	else if (strncasecmp (command, "-target-detach",
2583 						  strlen ("-target-detach")) == 0 ||
2584 			 strncasecmp (command, "detach", strlen ("detach")) == 0)
2585 	{
2586 		debugger_detach_process (debugger);
2587 	}
2588 	else if (strncasecmp (command, "-file-exec-and-symbols",
2589 						  strlen ("-file-exec-and-symbols")) == 0 ||
2590 			 strncasecmp (command, "file", strlen ("file")) == 0)
2591 	{
2592 		debugger_load_executable (debugger, strchr (command, ' '));
2593 	}
2594 	else if (strncasecmp (command, "core", strlen ("core")) == 0)
2595 	{
2596 		debugger_load_core (debugger, strchr (command, ' '));
2597 	}
2598 	else
2599 	{
2600 		debugger_queue_command (debugger, command, suppress_error ? DEBUGGER_COMMAND_NO_ERROR : 0,
2601 								parser, user_data, NULL);
2602 	}
2603 }
2604 
2605 static void
debugger_add_breakpoint_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2606 debugger_add_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2607 {
2608 	IAnjutaDebuggerBreakpointItem bp;
2609 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2610 	gpointer user_data = debugger->priv->current_cmd.user_data;
2611 
2612 	if ((error != NULL) || (mi_results == NULL))
2613 	{
2614 		/* Call callback in all case (useful for enable that doesn't return
2615  		* anything */
2616 		if (callback != NULL)
2617 			callback (NULL, user_data, error);
2618 	}
2619 	else if (callback != NULL)
2620 	{
2621 		const GDBMIValue *brkpnt;
2622 
2623 		brkpnt = gdbmi_value_hash_lookup (mi_results, "bkpt");
2624 		parse_breakpoint (&bp, brkpnt);
2625 
2626 		/* Call callback in all case (useful for enable that doesn't return
2627  		* anything */
2628 		callback (&bp, user_data, error);
2629 	}
2630 
2631 }
2632 
2633 void
debugger_add_breakpoint_at_line(Debugger * debugger,const gchar * file,guint line,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2634 debugger_add_breakpoint_at_line (Debugger *debugger, const gchar *file, guint line, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2635 {
2636 	gchar *buff;
2637 	gchar *quoted_file;
2638 
2639 	DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2640 
2641 	g_return_if_fail (IS_DEBUGGER (debugger));
2642 
2643 	quoted_file = gdb_quote (file);
2644 	buff = g_strdup_printf ("-break-insert %s \"\\\"%s\\\":%u\"",
2645 							debugger->priv->has_pending_breakpoints ? "-f" : "",
2646 							quoted_file, line);
2647 	g_free (quoted_file);
2648 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2649 	g_free (buff);
2650 }
2651 
2652 void
debugger_add_breakpoint_at_function(Debugger * debugger,const gchar * file,const gchar * function,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2653 debugger_add_breakpoint_at_function (Debugger *debugger, const gchar *file, const gchar *function, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2654 {
2655 	gchar *buff;
2656 	gchar *quoted_file;
2657 
2658 	DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2659 
2660 	g_return_if_fail (IS_DEBUGGER (debugger));
2661 
2662 	quoted_file = file == NULL ? NULL : gdb_quote (file);
2663 	buff = g_strdup_printf ("-break-insert %s %s%s%s%s%s",
2664 							debugger->priv->has_pending_breakpoints ? "-f" : "",
2665 							file == NULL ? "" : "\"\\\"",
2666 							file == NULL ? "" : quoted_file,
2667 							file == NULL ? "" : "\\\":" ,
2668 							function,
2669 							file == NULL ? "" : "\"");
2670 	g_free (quoted_file);
2671 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2672 	g_free (buff);
2673 }
2674 
2675 void
debugger_add_breakpoint_at_address(Debugger * debugger,gulong address,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2676 debugger_add_breakpoint_at_address (Debugger *debugger, gulong address, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2677 {
2678 	gchar *buff;
2679 
2680 	DEBUG_PRINT ("%s", "In function: debugger_add_breakpoint()");
2681 
2682 	g_return_if_fail (IS_DEBUGGER (debugger));
2683 
2684 	buff = g_strdup_printf ("-break-insert %s *0x%lx",
2685 							debugger->priv->has_pending_breakpoints ? "-f" : "",
2686 							address);
2687 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2688 	g_free (buff);
2689 }
2690 
2691 void
debugger_enable_breakpoint(Debugger * debugger,guint id,gboolean enable,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2692 debugger_enable_breakpoint (Debugger *debugger, guint id, gboolean enable, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2693 
2694 {
2695 	gchar *buff;
2696 
2697 	DEBUG_PRINT ("%s", "In function: debugger_enable_breakpoint()");
2698 
2699 	g_return_if_fail (IS_DEBUGGER (debugger));
2700 
2701 	buff = g_strdup_printf (enable ? "-break-enable %d" : "-break-disable %d",id);
2702 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2703 	g_free (buff);
2704 }
2705 
2706 void
debugger_ignore_breakpoint(Debugger * debugger,guint id,guint ignore,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2707 debugger_ignore_breakpoint (Debugger *debugger, guint id, guint ignore, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2708 {
2709 	gchar *buff;
2710 
2711 	DEBUG_PRINT ("%s", "In function: debugger_ignore_breakpoint()");
2712 
2713 	g_return_if_fail (IS_DEBUGGER (debugger));
2714 
2715 	buff = g_strdup_printf ("-break-after %d %d", id, ignore);
2716 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2717 	g_free (buff);
2718 }
2719 
2720 void
debugger_condition_breakpoint(Debugger * debugger,guint id,const gchar * condition,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2721 debugger_condition_breakpoint (Debugger *debugger, guint id, const gchar *condition, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2722 {
2723 	gchar *buff;
2724 
2725 	DEBUG_PRINT ("%s", "In function: debugger_ignore_breakpoint()");
2726 
2727 	g_return_if_fail (IS_DEBUGGER (debugger));
2728 
2729 	buff = g_strdup_printf ("-break-condition %d %s", id, condition == NULL ? "" : condition);
2730 	debugger_queue_command (debugger, buff, 0, debugger_add_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2731 	g_free (buff);
2732 }
2733 
2734 static void
debugger_remove_breakpoint_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2735 debugger_remove_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2736 {
2737 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2738 	gpointer user_data = debugger->priv->current_cmd.user_data;
2739 	IAnjutaDebuggerBreakpointItem bp;
2740 
2741 	bp.type = IANJUTA_DEBUGGER_BREAKPOINT_REMOVED;
2742 	bp.id = atoi (debugger->priv->current_cmd.cmd + 14);
2743 	if (callback != NULL)
2744 		callback (&bp, user_data, NULL);
2745 }
2746 
2747 void
debugger_remove_breakpoint(Debugger * debugger,guint id,IAnjutaDebuggerBreakpointCallback callback,gpointer user_data)2748 debugger_remove_breakpoint (Debugger *debugger, guint id, IAnjutaDebuggerBreakpointCallback callback, gpointer user_data)
2749 {
2750 	gchar *buff;
2751 
2752 	DEBUG_PRINT ("%s", "In function: debugger_delete_breakpoint()");
2753 
2754 	g_return_if_fail (IS_DEBUGGER (debugger));
2755 
2756 	buff = g_strdup_printf ("-break-delete %d", id);
2757 	debugger_queue_command (debugger, buff, 0, debugger_remove_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2758 	g_free (buff);
2759 }
2760 
2761 static void
debugger_list_breakpoint_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2762 debugger_list_breakpoint_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2763 {
2764 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2765 	gpointer user_data = debugger->priv->current_cmd.user_data;
2766 	IAnjutaDebuggerBreakpointItem* bp;
2767 	const GDBMIValue *table;
2768 	GList *list = NULL;
2769 
2770 	if ((error != NULL) || (mi_results == NULL))
2771 	{
2772 		/* Call callback in all case (useful for enable that doesn't return
2773  		* anything */
2774 		if (callback != NULL)
2775 			callback (NULL, user_data, error);
2776 	}
2777 
2778 	table = gdbmi_value_hash_lookup (mi_results, "BreakpointTable");
2779 	if (table)
2780 	{
2781 		table = gdbmi_value_hash_lookup (table, "body");
2782 
2783 		if (table)
2784 		{
2785 			int i;
2786 
2787 			for (i = 0; i < gdbmi_value_get_size (table); i++)
2788 			{
2789 				const GDBMIValue *brkpnt;
2790 
2791 				bp = g_new0 (IAnjutaDebuggerBreakpointItem, 1);
2792 
2793 				brkpnt = gdbmi_value_list_get_nth (table, i);
2794 				parse_breakpoint(bp, brkpnt);
2795 				list = g_list_prepend (list, bp);
2796 			}
2797 		}
2798 	}
2799 
2800 	/* Call callback in all case (useful for enable that doesn't return
2801 	* anything */
2802 	if (callback != NULL)
2803 	{
2804 		list = g_list_reverse (list);
2805 		callback (list, user_data, error);
2806 	}
2807 
2808 	g_list_foreach (list, (GFunc)g_free, NULL);
2809 	g_list_free (list);
2810 }
2811 
2812 void
debugger_list_breakpoint(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)2813 debugger_list_breakpoint (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
2814 {
2815 	DEBUG_PRINT ("%s", "In function: debugger_list_breakpoint()");
2816 
2817 	g_return_if_fail (IS_DEBUGGER (debugger));
2818 
2819 	debugger_queue_command (debugger, "-break-list", 0, debugger_list_breakpoint_finish, (IAnjutaDebuggerCallback)callback, user_data);
2820 }
2821 
2822 static void
debugger_print_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2823 debugger_print_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2824 {
2825 	gchar *ptr = NULL;
2826 	gchar *tmp;
2827 	GList *list, *node;
2828 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2829 	gpointer user_data = debugger->priv->current_cmd.user_data;
2830 
2831 
2832 	list = gdb_util_remove_blank_lines (cli_results);
2833 	if (g_list_length (list) < 1)
2834 	{
2835 		tmp = NULL;
2836 	}
2837 	else
2838 	{
2839 		tmp = strchr ((gchar *) list->data, '=');
2840 	}
2841 	if (tmp != NULL)
2842 	{
2843 		ptr = g_strdup (tmp);
2844 		for (node = list ? list->next : NULL; node != NULL; node = node->next)
2845 		{
2846 			tmp = ptr;
2847 			ptr = g_strconcat (tmp, (gchar *) node->data, NULL);
2848 			g_free (tmp);
2849 		}
2850 	}
2851 
2852 	callback (ptr, user_data, NULL);
2853 	g_free (ptr);
2854 }
2855 
2856 void
debugger_print(Debugger * debugger,const gchar * variable,IAnjutaDebuggerGCharCallback callback,gpointer user_data)2857 debugger_print (Debugger *debugger, const gchar* variable, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
2858 {
2859 	gchar *buff;
2860 
2861 	DEBUG_PRINT ("%s", "In function: debugger_print()");
2862 
2863 	g_return_if_fail (IS_DEBUGGER (debugger));
2864 
2865 	buff = g_strdup_printf ("print %s", variable);
2866 	debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_print_finish, (IAnjutaDebuggerCallback)callback, user_data);
2867 	g_free (buff);
2868 }
2869 
2870 static void
debugger_evaluate_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2871 debugger_evaluate_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2872 
2873 {
2874 	const GDBMIValue *value = NULL;
2875 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2876 	gpointer user_data = debugger->priv->current_cmd.user_data;
2877 
2878 	if (mi_results)
2879 		value = gdbmi_value_hash_lookup (mi_results, "value");
2880 
2881 	/* Call user function */
2882 	if (callback != NULL)
2883 		callback (value == NULL ? "?" : (char *)gdbmi_value_literal_get (value), user_data, NULL);
2884 }
2885 
2886 void
debugger_evaluate(Debugger * debugger,const gchar * name,IAnjutaDebuggerGCharCallback callback,gpointer user_data)2887 debugger_evaluate (Debugger *debugger, const gchar* name, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
2888 {
2889 	gchar *buff;
2890 	DEBUG_PRINT ("%s", "In function: debugger_add_watch()");
2891 
2892 	g_return_if_fail (IS_DEBUGGER (debugger));
2893 
2894 	buff = g_strdup_printf ("-data-evaluate-expression %s", name);
2895 	debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_evaluate_finish, (IAnjutaDebuggerCallback)callback, user_data);
2896 	g_free (buff);
2897 }
2898 
2899 static void
debugger_list_local_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2900 debugger_list_local_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2901 
2902 {
2903 	const GDBMIValue *local, *var, *frame, *args, *stack;
2904 	const gchar * name;
2905 	GList* list;
2906 	guint i;
2907 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2908 	gpointer user_data = debugger->priv->current_cmd.user_data;
2909 
2910 
2911 	list = NULL;
2912 	/* Add arguments */
2913 	stack = gdbmi_value_hash_lookup (mi_results, "stack-args");
2914 	if (stack)
2915 	{
2916 		frame = gdbmi_value_list_get_nth (stack, 0);
2917 		if (frame)
2918 		{
2919 			args = gdbmi_value_hash_lookup (frame, "args");
2920 			if (args)
2921 			{
2922 				for (i = 0; i < gdbmi_value_get_size (args); i++)
2923 				{
2924 					var = gdbmi_value_list_get_nth (args, i);
2925 					if (var)
2926 					{
2927 						name = gdbmi_value_literal_get (var);
2928 						list = g_list_prepend (list, (gchar *)name);
2929 					}
2930 				}
2931 
2932 			}
2933 		}
2934 	}
2935 
2936 	/* List local variables */
2937 	local = gdbmi_value_hash_lookup (mi_results, "locals");
2938 	if (local)
2939 	{
2940 		for (i = 0; i < gdbmi_value_get_size (local); i++)
2941 		{
2942 			var = gdbmi_value_list_get_nth (local, i);
2943 			if (var)
2944 			{
2945 				name = gdbmi_value_literal_get (var);
2946 				list = g_list_prepend (list, (gchar *)name);
2947 			}
2948 		}
2949 	}
2950 	list = g_list_reverse (list);
2951 	callback (list, user_data, NULL);
2952 	g_list_free (list);
2953 }
2954 
2955 void
debugger_list_local(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)2956 debugger_list_local (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
2957 {
2958 	gchar *buff;
2959 	DEBUG_PRINT ("%s", "In function: debugger_list_local()");
2960 
2961 	g_return_if_fail (IS_DEBUGGER (debugger));
2962 
2963 	buff = g_strdup_printf("-stack-list-arguments 0 %d %d", debugger->priv->current_frame, debugger->priv->current_frame);
2964 	debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR | DEBUGGER_COMMAND_KEEP_RESULT, NULL, NULL, NULL);
2965 	g_free (buff);
2966 	debugger_queue_command (debugger, "-stack-list-locals 0", DEBUGGER_COMMAND_NO_ERROR, debugger_list_local_finish, (IAnjutaDebuggerCallback)callback, user_data);
2967 }
2968 
2969 static void
debugger_list_argument_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)2970 debugger_list_argument_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
2971 
2972 {
2973 	const GDBMIValue *frame, *var, *args, *stack;
2974 	const gchar * name;
2975 	GList* list;
2976 	guint i;
2977 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
2978 	gpointer user_data = debugger->priv->current_cmd.user_data;
2979 
2980 
2981 	list = NULL;
2982 	args = NULL;
2983 	stack = gdbmi_value_hash_lookup (mi_results, "stack-args");
2984 	if (stack)
2985 	{
2986 		frame = gdbmi_value_list_get_nth (stack, 0);
2987 		if (frame)
2988 		{
2989 			args = gdbmi_value_hash_lookup (frame, "args");
2990 		}
2991 	}
2992 
2993 	if (args)
2994 	{
2995 		for (i = 0; i < gdbmi_value_get_size (args); i++)
2996 		{
2997 			var = gdbmi_value_list_get_nth (args, i);
2998 			if (var)
2999 			{
3000 				name = gdbmi_value_literal_get (var);
3001 				list = g_list_prepend (list, (gchar *)name);
3002 			}
3003 		}
3004 	}
3005 	list = g_list_reverse (list);
3006 	callback (list, user_data, NULL);
3007 	g_list_free (list);
3008 }
3009 
3010 void
debugger_list_argument(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3011 debugger_list_argument (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3012 {
3013 	gchar *buff;
3014 
3015 	DEBUG_PRINT ("%s", "In function: debugger_list_argument()");
3016 
3017 	g_return_if_fail (IS_DEBUGGER (debugger));
3018 
3019 	buff = g_strdup_printf("-stack-list-arguments 0 %d %d", debugger->priv->current_frame, debugger->priv->current_frame);
3020 	debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, debugger_list_argument_finish, (IAnjutaDebuggerCallback)callback, user_data);
3021 	g_free (buff);
3022 }
3023 
3024 static void
debugger_info_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3025 debugger_info_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3026 
3027 {
3028 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3029 	gpointer user_data = debugger->priv->current_cmd.user_data;
3030 
3031 	if (callback != NULL)
3032 		callback ((GList *)cli_results, user_data, NULL);
3033 }
3034 
3035 void
debugger_info_signal(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3036 debugger_info_signal (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3037 {
3038 	DEBUG_PRINT ("%s", "In function: debugger_info_signal()");
3039 
3040 	g_return_if_fail (IS_DEBUGGER (debugger));
3041 
3042 	debugger_queue_command (debugger, "info signals", DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_info_finish, (IAnjutaDebuggerCallback)callback, user_data);
3043 }
3044 
3045 void
debugger_info_sharedlib(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3046 debugger_info_sharedlib (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3047 {
3048 	gchar *buff;
3049 
3050 	DEBUG_PRINT ("%s", "In function: debugger_info_sharedlib()");
3051 
3052 	g_return_if_fail (IS_DEBUGGER (debugger));
3053 
3054 	buff = g_strdup_printf ("info sharedlib");
3055 	debugger_queue_command (debugger, buff, DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_info_finish, (IAnjutaDebuggerCallback)callback, user_data);	g_free (buff);
3056 }
3057 
3058 static void
debugger_read_memory_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3059 debugger_read_memory_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3060 
3061 {
3062 	const GDBMIValue *literal;
3063 	const GDBMIValue *mem;
3064 	const gchar *value;
3065 	gchar *data;
3066 	gchar *ptr;
3067 	gulong address;
3068 	guint len;
3069 	guint i;
3070 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3071 	gpointer user_data = debugger->priv->current_cmd.user_data;
3072 	IAnjutaDebuggerMemoryBlock read = {0,};
3073 
3074 	literal = gdbmi_value_hash_lookup (mi_results, "total-bytes");
3075 	if (literal)
3076 	{
3077 		guint size;
3078 
3079 		len = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3080 		data = g_new (gchar, len * 2);
3081 		memset (data + len, 0, len);
3082 
3083 		literal = gdbmi_value_hash_lookup (mi_results, "addr");
3084 		address = strtoul (gdbmi_value_literal_get (literal), NULL, 0);
3085 
3086 		ptr = data;
3087 		size = 0;
3088 		mem = gdbmi_value_hash_lookup (mi_results, "memory");
3089 		if (mem)
3090 		{
3091 			mem = gdbmi_value_list_get_nth (mem, 0);
3092 			if (mem)
3093 			{
3094 				mem = gdbmi_value_hash_lookup (mem, "data");
3095 				if (mem)
3096 				{
3097 					size = gdbmi_value_get_size (mem);
3098 				}
3099 			}
3100 		}
3101 
3102 		if (size < len) len = size;
3103 		for (i = 0; i < len; i++)
3104 		{
3105 			literal = gdbmi_value_list_get_nth (mem, i);
3106 			if (literal)
3107 			{
3108 				gchar *endptr;
3109 				value = gdbmi_value_literal_get (literal);
3110 				*ptr = strtoul (value, &endptr, 16);
3111 				if ((*value != '\0') && (*endptr == '\0'))
3112 				{
3113 					/* valid data */
3114 					ptr[len] = 1;
3115 				}
3116 				ptr++;
3117 			}
3118 		}
3119 		read.address = address;
3120 		read.length = len;
3121 		read.data = data;
3122 		callback (&read, user_data, NULL);
3123 
3124 		g_free (data);
3125 	}
3126 	else
3127 	{
3128 		callback (NULL, user_data, NULL);
3129 	}
3130 }
3131 
3132 void
debugger_inspect_memory(Debugger * debugger,gulong address,guint length,IAnjutaDebuggerMemoryCallback callback,gpointer user_data)3133 debugger_inspect_memory (Debugger *debugger, gulong address, guint length, IAnjutaDebuggerMemoryCallback callback, gpointer user_data)
3134 {
3135 	gchar *buff;
3136 
3137 	DEBUG_PRINT ("%s", "In function: debugger_inspect_memory()");
3138 
3139 	g_return_if_fail (IS_DEBUGGER (debugger));
3140 
3141 	buff = g_strdup_printf ("-data-read-memory 0x%lx x 1 1 %d", address, length);
3142 	debugger_queue_command (debugger, buff, 0, debugger_read_memory_finish, (IAnjutaDebuggerCallback)callback, user_data);
3143 	g_free (buff);
3144 }
3145 
3146 static void
debugger_disassemble_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3147 debugger_disassemble_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3148 
3149 {
3150 	const GDBMIValue *literal;
3151 	const GDBMIValue *line;
3152 	const GDBMIValue *mem;
3153 	const gchar *value;
3154 	guint i;
3155 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3156 	gpointer user_data = debugger->priv->current_cmd.user_data;
3157 	IAnjutaDebuggerInstructionDisassembly *read = NULL;
3158 
3159 	if (error != NULL)
3160 	{
3161 		/* Command fail */
3162 		callback (NULL, user_data, error);
3163 
3164 		return;
3165 	}
3166 
3167 
3168 	mem = gdbmi_value_hash_lookup (mi_results, "asm_insns");
3169 	if (mem)
3170 	{
3171 		guint size;
3172 
3173 		size = gdbmi_value_get_size (mem);
3174 		read = (IAnjutaDebuggerInstructionDisassembly *)g_malloc0(sizeof (IAnjutaDebuggerInstructionDisassembly) + sizeof(IAnjutaDebuggerInstructionALine) * size);
3175 		read->size = size;
3176 
3177 		for (i = 0; i < size; i++)
3178 		{
3179 			line = gdbmi_value_list_get_nth (mem, i);
3180 			if (line)
3181 			{
3182 				/* Get address */
3183 				literal = gdbmi_value_hash_lookup (line, "address");
3184 				if (literal)
3185 				{
3186 					value = gdbmi_value_literal_get (literal);
3187 					read->data[i].address = strtoul (value, NULL, 0);
3188 				}
3189 
3190 				/* Get label if one exist */
3191 				literal = gdbmi_value_hash_lookup (line, "offset");
3192 				if (literal)
3193 				{
3194 					value = gdbmi_value_literal_get (literal);
3195 					if ((value != NULL) && (strtoul (value, NULL, 0) == 0))
3196 					{
3197 						literal = gdbmi_value_hash_lookup (line, "func-name");
3198 						if (literal)
3199 						{
3200 							read->data[i].label = gdbmi_value_literal_get (literal);
3201 						}
3202 					}
3203 
3204 				}
3205 
3206 
3207 				/* Get disassembly line */
3208 				literal = gdbmi_value_hash_lookup (line, "inst");
3209 				if (literal)
3210 				{
3211 					read->data[i].text = gdbmi_value_literal_get (literal);
3212 				}
3213 			}
3214 		}
3215 
3216 		/* Remove last line to mark end */
3217 		read->data[i - 1].text = NULL;
3218 
3219 		callback (read, user_data, NULL);
3220 
3221 		g_free (read);
3222 	}
3223 	else
3224 	{
3225 		callback (NULL, user_data, NULL);
3226 	}
3227 }
3228 
3229 void
debugger_disassemble(Debugger * debugger,gulong address,guint length,IAnjutaDebuggerInstructionCallback callback,gpointer user_data)3230 debugger_disassemble (Debugger *debugger, gulong address, guint length, IAnjutaDebuggerInstructionCallback callback, gpointer user_data)
3231 {
3232 	gchar *buff;
3233 	gulong end;
3234 
3235 	DEBUG_PRINT ("%s", "In function: debugger_disassemble()");
3236 
3237 	g_return_if_fail (IS_DEBUGGER (debugger));
3238 
3239 
3240 	/* Handle overflow */
3241 	end = (address + length < address) ? G_MAXULONG : address + length;
3242 	buff = g_strdup_printf ("-data-disassemble -s 0x%lx -e 0x%lx  -- 0", address, end);
3243 	debugger_queue_command (debugger, buff, 0, debugger_disassemble_finish, (IAnjutaDebuggerCallback)callback, user_data);
3244 	g_free (buff);
3245 }
3246 
3247 static void
parse_frame(IAnjutaDebuggerFrame * frame,const GDBMIValue * frame_hash)3248 parse_frame (IAnjutaDebuggerFrame *frame, const GDBMIValue *frame_hash)
3249 {
3250 	const GDBMIValue *literal;
3251 
3252 	literal = gdbmi_value_hash_lookup (frame_hash, "level");
3253 	if (literal)
3254 		frame->level = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3255 	else
3256 		frame->level = 0;
3257 
3258 
3259 	frame->file = (gchar *)debugger_parse_filename (frame_hash);
3260 
3261 	literal = gdbmi_value_hash_lookup (frame_hash, "line");
3262 	if (literal)
3263 		frame->line = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3264 	else
3265 		frame->line = 0;
3266 
3267 	literal = gdbmi_value_hash_lookup (frame_hash, "func");
3268 	if (literal)
3269 		frame->function = (gchar *)gdbmi_value_literal_get (literal);
3270 	else
3271 		frame->function = NULL;
3272 
3273 	literal = gdbmi_value_hash_lookup (frame_hash, "from");
3274 	if (literal)
3275 		frame->library = (gchar *)gdbmi_value_literal_get (literal);
3276 	else
3277 		frame->library = NULL;
3278 
3279 	literal = gdbmi_value_hash_lookup (frame_hash, "addr");
3280 	if (literal)
3281 		frame->address = strtoul (gdbmi_value_literal_get (literal), NULL, 16);
3282 	else
3283 		frame->address = 0;
3284 
3285 }
3286 
3287 
3288 static void
add_frame(const GDBMIValue * frame_hash,GdbGListPacket * pack)3289 add_frame (const GDBMIValue *frame_hash, GdbGListPacket* pack)
3290 {
3291 	IAnjutaDebuggerFrame* frame;
3292 
3293 	frame = g_new0 (IAnjutaDebuggerFrame, 1);
3294 	pack->list = g_list_prepend (pack->list, frame);
3295 
3296 	frame->thread = pack->tag;
3297 	parse_frame (frame, frame_hash);
3298 }
3299 
3300 static void
set_func_args(const GDBMIValue * frame_hash,GList ** node)3301 set_func_args (const GDBMIValue *frame_hash, GList** node)
3302 {
3303 	const gchar *level;
3304 	const GDBMIValue *literal, *args_list, *arg_hash;
3305 	gint i;
3306 	GString *args_str;
3307 	IAnjutaDebuggerFrame* frame;
3308 
3309 	literal = gdbmi_value_hash_lookup (frame_hash, "level");
3310 	if (!literal)
3311 		return;
3312 
3313 	level = gdbmi_value_literal_get (literal);
3314 	if (!level)
3315 		return;
3316 
3317 	frame = (IAnjutaDebuggerFrame *)(*node)->data;
3318 
3319 	args_list = gdbmi_value_hash_lookup (frame_hash, "args");
3320 	if (args_list)
3321 	{
3322 		args_str = g_string_new ("(");
3323 		for (i = 0; i < gdbmi_value_get_size (args_list); i++)
3324 		{
3325 			const gchar *name, *value;
3326 
3327 			arg_hash = gdbmi_value_list_get_nth (args_list, i);
3328 			if (!arg_hash)
3329 				continue;
3330 
3331 			literal = gdbmi_value_hash_lookup (arg_hash, "name");
3332 			if (!literal)
3333 				continue;
3334 			name = gdbmi_value_literal_get (literal);
3335 			if (!name)
3336 				continue;
3337 
3338 			literal = gdbmi_value_hash_lookup (arg_hash, "value");
3339 			if (!literal)
3340 				continue;
3341 			value = gdbmi_value_literal_get (literal);
3342 			if (!value)
3343 				continue;
3344 			args_str = g_string_append (args_str, name);
3345 			args_str = g_string_append (args_str, "=");
3346 			args_str = g_string_append (args_str, value);
3347 			if (i < (gdbmi_value_get_size (args_list) - 1))
3348 				args_str = g_string_append (args_str, ", ");
3349 		}
3350 		args_str = g_string_append (args_str, ")");
3351 		frame->args = args_str->str;
3352 		g_string_free (args_str, FALSE);
3353 	}
3354 	*node = g_list_next (*node);
3355 }
3356 
3357 static void
debugger_stack_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3358 debugger_stack_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3359 
3360 {
3361 	GdbGListPacket pack = {NULL, 0};
3362 	GList* node;
3363 	const GDBMIValue *stack_list;
3364 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3365 	gpointer user_data = debugger->priv->current_cmd.user_data;
3366 
3367 	if (!mi_results)
3368 		return;
3369 
3370 	stack_list = gdbmi_value_hash_lookup (mi_results, "stack");
3371 	if (stack_list)
3372 	{
3373 		pack.tag = debugger->priv->current_thread;
3374 		gdbmi_value_foreach (stack_list, (GFunc)add_frame, &pack);
3375 	}
3376 
3377 	if (pack.list)
3378 	{
3379 		pack.list = g_list_reverse (pack.list);
3380 		node = g_list_first (pack.list);
3381 		stack_list = gdbmi_value_hash_lookup (mi_results, "stack-args");
3382 		if (stack_list)
3383 			gdbmi_value_foreach (stack_list, (GFunc)set_func_args, &node);
3384 
3385 		// Call call back function
3386 		if (callback != NULL)
3387 			callback (pack.list, user_data, NULL);
3388 
3389 		// Free data
3390 		for (node = g_list_first (pack.list); node != NULL; node = g_list_next (node))
3391 		{
3392 			g_free ((gchar *)((IAnjutaDebuggerFrame *)node->data)->args);
3393 			g_free (node->data);
3394 		}
3395 
3396 		g_list_free (pack.list);
3397 	}
3398 	else
3399 	{
3400 		// Call call back function
3401 		if (callback != NULL)
3402 			callback (NULL, user_data, NULL);
3403 	}
3404 }
3405 
3406 void
debugger_list_frame(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3407 debugger_list_frame (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3408 {
3409 	DEBUG_PRINT ("%s", "In function: debugger_list_frame()");
3410 
3411 	g_return_if_fail (IS_DEBUGGER (debugger));
3412 
3413 	debugger_queue_command (debugger, "-stack-list-frames", DEBUGGER_COMMAND_NO_ERROR | DEBUGGER_COMMAND_KEEP_RESULT, NULL, NULL, NULL);
3414 	debugger_queue_command (debugger, "-stack-list-arguments 1", DEBUGGER_COMMAND_NO_ERROR, debugger_stack_finish, (IAnjutaDebuggerCallback)callback, user_data);
3415 }
3416 
3417 static void
debugger_dump_stack_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3418 debugger_dump_stack_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3419 {
3420 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3421 	gpointer user_data = debugger->priv->current_cmd.user_data;
3422 
3423 	if (callback != NULL)
3424 	{
3425 		GString *result;
3426 		GList *item;
3427 
3428 		result = g_string_new (NULL);
3429 
3430 		for (item = g_list_first ((GList *)cli_results); item != NULL; item = g_list_next (item))
3431 		{
3432 			const gchar *line = (const gchar *)item->data;
3433 
3434 			/* Keep only data outputed by CLI command */
3435 			if (*line == '~')
3436 			{
3437 				g_string_append (result, line + 1);
3438 			}
3439 		}
3440 
3441 		callback (result->str, user_data, NULL);
3442 
3443 		g_string_free (result, TRUE);
3444 	}
3445 }
3446 
debugger_dump_stack_trace(Debugger * debugger,IAnjutaDebuggerGListCallback func,gpointer user_data)3447 void debugger_dump_stack_trace (Debugger *debugger, IAnjutaDebuggerGListCallback func, gpointer user_data)
3448 {
3449 	DEBUG_PRINT ("%s", "In function: debugger_dump_stack_frame()");
3450 
3451 	g_return_if_fail (IS_DEBUGGER (debugger));
3452 
3453 	debugger_queue_command (debugger, "thread apply all backtrace", DEBUGGER_COMMAND_NO_ERROR, debugger_dump_stack_finish, (IAnjutaDebuggerCallback)func, user_data);
3454 }
3455 
3456 /* Thread functions
3457  *---------------------------------------------------------------------------*/
3458 
3459 static void
debugger_set_thread_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3460 debugger_set_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3461 {
3462 	const GDBMIValue *literal;
3463 	guint id;
3464 
3465 	if (mi_results == NULL) return;
3466 
3467 	literal = gdbmi_value_hash_lookup (mi_results, "new-thread-id");
3468 	if (literal == NULL) return;
3469 
3470 	id = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3471 	if (id == 0) return;
3472 
3473 	debugger->priv->current_thread = id;
3474 	g_signal_emit_by_name (debugger->priv->instance, "frame-changed", 0, debugger->priv->current_thread);
3475 
3476 	return;
3477 }
3478 
3479 void
debugger_set_thread(Debugger * debugger,gint thread)3480 debugger_set_thread (Debugger *debugger, gint thread)
3481 {
3482 	gchar *buff;
3483 
3484 	DEBUG_PRINT ("%s", "In function: debugger_set_thread()");
3485 
3486 	g_return_if_fail (IS_DEBUGGER (debugger));
3487 
3488 	buff = g_strdup_printf ("-thread-select %d", thread);
3489 
3490 	debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_set_thread_finish, NULL, NULL);
3491 	g_free (buff);
3492 }
3493 
3494 static void
add_thread_id(const GDBMIValue * thread_hash,GList ** list)3495 add_thread_id (const GDBMIValue *thread_hash, GList** list)
3496 {
3497 	IAnjutaDebuggerFrame* frame;
3498 	gint thread;
3499 
3500 	thread = strtoul (gdbmi_value_literal_get (thread_hash), NULL, 10);
3501 	if (thread == 0) return;
3502 
3503 	frame = g_new0 (IAnjutaDebuggerFrame, 1);
3504 	*list = g_list_prepend (*list, frame);
3505 
3506 	frame->thread = thread;
3507 }
3508 
3509 static void
debugger_list_thread_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3510 debugger_list_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3511 
3512 {
3513 	const GDBMIValue *id_list;
3514 	gpointer user_data = debugger->priv->current_cmd.user_data;
3515 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3516 	GList* thread_list = NULL;
3517 
3518 	for (;;)
3519 	{
3520 		if (mi_results == NULL) break;
3521 
3522 		id_list = gdbmi_value_hash_lookup (mi_results, "thread-ids");
3523 		if (id_list == NULL) break;
3524 
3525 		gdbmi_value_foreach (id_list, (GFunc)add_thread_id, &thread_list);
3526 		thread_list = g_list_reverse (thread_list);
3527 		break;
3528 	}
3529 
3530 	if (callback != NULL)
3531 		callback (thread_list, user_data, error);
3532 
3533 	if (thread_list != NULL)
3534 	{
3535 		g_list_foreach (thread_list, (GFunc)g_free, NULL);
3536 		g_list_free (thread_list);
3537 	}
3538 }
3539 
3540 void
debugger_list_thread(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3541 debugger_list_thread (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3542 {
3543 	DEBUG_PRINT ("%s", "In function: debugger_list_thread()");
3544 
3545 	g_return_if_fail (IS_DEBUGGER (debugger));
3546 
3547 	debugger_queue_command (debugger, "-thread-list-ids", DEBUGGER_COMMAND_NO_ERROR, debugger_list_thread_finish, (IAnjutaDebuggerCallback)callback, user_data);
3548 }
3549 
3550 static void
debugger_info_set_thread_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3551 debugger_info_set_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3552 {
3553 	const GDBMIValue *literal;
3554 	guint id;
3555 
3556 	if (mi_results == NULL) return;
3557 
3558 	literal = gdbmi_value_hash_lookup (mi_results, "new-thread-id");
3559 	if (literal == NULL) return;
3560 
3561 	id = strtoul (gdbmi_value_literal_get (literal), NULL, 10);
3562 	if (id == 0) return;
3563 
3564 	debugger->priv->current_thread = id;
3565 	/* Do not emit a signal notification as the current thread will
3566 	 * be restored when needed */
3567 
3568 	return;
3569 }
3570 
3571 static void
debugger_info_thread_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3572 debugger_info_thread_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3573 {
3574 	const GDBMIValue *frame;
3575 	IAnjutaDebuggerFrame top_frame;
3576 	IAnjutaDebuggerFrame *top;
3577 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3578 	gpointer user_data = debugger->priv->current_cmd.user_data;
3579 
3580 	for (top = NULL;;)
3581 	{
3582 		DEBUG_PRINT("look for stack %p", mi_results);
3583 		if (mi_results == NULL) break;
3584 
3585 		frame = gdbmi_value_hash_lookup (mi_results, "stack");
3586 		if (frame == NULL) break;
3587 
3588 		DEBUG_PRINT("%s", "get stack");
3589 
3590 		frame = gdbmi_value_list_get_nth (frame, 0);
3591 		if (frame == NULL) break;
3592 
3593 		DEBUG_PRINT("%s", "get nth element");
3594 
3595 		/*frame = gdbmi_value_hash_lookup (frame, "frame");
3596 		DEBUG_PRINT("get frame %p", frame);
3597 		if (frame == NULL) break;*/
3598 
3599 		DEBUG_PRINT("%s", "get frame");
3600 
3601 		top = &top_frame;
3602 		top->thread = debugger->priv->current_thread;
3603 
3604 		parse_frame (top, frame);
3605 		break;
3606 	}
3607 
3608 	if (callback != NULL)
3609 		callback (top, user_data, error);
3610 
3611 	return;
3612 }
3613 
3614 void
debugger_info_thread(Debugger * debugger,gint thread,IAnjutaDebuggerGListCallback callback,gpointer user_data)3615 debugger_info_thread (Debugger *debugger, gint thread, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3616 {
3617 	gchar *buff;
3618 	guint orig_thread;
3619 
3620 	DEBUG_PRINT ("%s", "In function: debugger_info_thread()");
3621 
3622 	g_return_if_fail (IS_DEBUGGER (debugger));
3623 
3624 	orig_thread = debugger->priv->current_thread;
3625 	buff = g_strdup_printf ("-thread-select %d", thread);
3626 	debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_info_set_thread_finish, NULL, NULL);
3627 	g_free (buff);
3628 	debugger_queue_command (debugger, "-stack-list-frames 0 0", 0, (DebuggerParserFunc)debugger_info_thread_finish, (IAnjutaDebuggerCallback)callback, user_data);
3629 
3630 	buff = g_strdup_printf ("-thread-select %d", orig_thread);
3631 	debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_info_set_thread_finish, NULL, NULL);
3632 	g_free (buff);
3633 }
3634 
3635 static void
add_register_name(const GDBMIValue * reg_literal,GList ** list)3636 add_register_name (const GDBMIValue *reg_literal, GList** list)
3637 {
3638 	IAnjutaDebuggerRegisterData* reg;
3639 	GList *prev = *list;
3640 
3641 	reg = g_new0 (IAnjutaDebuggerRegisterData, 1);
3642 	*list = g_list_prepend (prev, reg);
3643 	reg->name = (gchar *)gdbmi_value_literal_get (reg_literal);
3644 	reg->num = prev == NULL ? 0 : ((IAnjutaDebuggerRegisterData *)prev->data)->num + 1;
3645 }
3646 
3647 static void
add_register_value(const GDBMIValue * reg_hash,GList ** list)3648 add_register_value (const GDBMIValue *reg_hash, GList** list)
3649 {
3650 	const GDBMIValue *literal;
3651 	const gchar *val;
3652 	IAnjutaDebuggerRegisterData* reg;
3653 	guint num;
3654 	GList* prev = *list;
3655 
3656 	literal = gdbmi_value_hash_lookup (reg_hash, "number");
3657 	if (!literal)
3658 		return;
3659 	val = gdbmi_value_literal_get (literal);
3660 	num = strtoul (val, NULL, 10);
3661 
3662 	literal = gdbmi_value_hash_lookup (reg_hash, "value");
3663 	if (!literal)
3664 		return;
3665 
3666 	reg = g_new0 (IAnjutaDebuggerRegisterData, 1);
3667 	*list = g_list_prepend (prev, reg);
3668 	reg->num = num;
3669 	reg->value = (gchar *)gdbmi_value_literal_get (literal);
3670 }
3671 
3672 static void
debugger_register_name_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3673 debugger_register_name_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3674 
3675 {
3676 	GList* list = NULL;
3677 	GList* node;
3678 	const GDBMIValue *reg_list;
3679 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3680 	gpointer user_data = debugger->priv->current_cmd.user_data;
3681 
3682 	if (!mi_results)
3683 		return;
3684 
3685 	reg_list = gdbmi_value_hash_lookup (mi_results, "register-names");
3686 	if (reg_list)
3687 		gdbmi_value_foreach (reg_list, (GFunc)add_register_name, &list);
3688 	list = g_list_reverse (list);
3689 
3690 	// Call call back function
3691 	if (callback != NULL)
3692 		callback (list, user_data, NULL);
3693 
3694 	// Free data
3695 	for (node = g_list_first (list); node != NULL; node = g_list_next (node))
3696 	{
3697 		g_free (node->data);
3698 	}
3699 	g_list_free (list);
3700 }
3701 
3702 static void
debugger_register_value_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3703 debugger_register_value_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3704 
3705 {
3706 	GList* list = NULL;
3707 	GList* node;
3708 	const GDBMIValue *reg_list;
3709 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3710 	gpointer user_data = debugger->priv->current_cmd.user_data;
3711 
3712 	if (!mi_results)
3713 		return;
3714 
3715 	reg_list = gdbmi_value_hash_lookup (mi_results, "register-values");
3716 	if (reg_list)
3717 		gdbmi_value_foreach (reg_list, (GFunc)add_register_value, &list);
3718 	list = g_list_reverse (list);
3719 
3720 	// Call call back function
3721 	if (callback != NULL)
3722 		callback (list, user_data, NULL);
3723 
3724 	// Free data
3725 	for (node = g_list_first (list); node != NULL; node = g_list_next (node))
3726 	{
3727 		g_free (node->data);
3728 	}
3729 	g_list_free (list);
3730 }
3731 
3732 void
debugger_list_register(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3733 debugger_list_register (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3734 {
3735 	DEBUG_PRINT ("%s", "In function: debugger_list_register()");
3736 
3737 	g_return_if_fail (IS_DEBUGGER (debugger));
3738 
3739 	debugger_queue_command (debugger, "-data-list-register-names", DEBUGGER_COMMAND_NO_ERROR, debugger_register_name_finish, (IAnjutaDebuggerCallback)callback, user_data);
3740 }
3741 
3742 void
debugger_update_register(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)3743 debugger_update_register (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3744 {
3745 	DEBUG_PRINT ("%s", "In function: debugger_update_register()");
3746 
3747 	g_return_if_fail (IS_DEBUGGER (debugger));
3748 
3749 	debugger_queue_command (debugger, "-data-list-register-values r", DEBUGGER_COMMAND_NO_ERROR, (DebuggerParserFunc)debugger_register_value_finish, (IAnjutaDebuggerCallback)callback, user_data);
3750 }
3751 
3752 void
debugger_write_register(Debugger * debugger,const gchar * name,const gchar * value)3753 debugger_write_register (Debugger *debugger, const gchar *name, const gchar *value)
3754 {
3755 	gchar *buf;
3756 
3757 	DEBUG_PRINT ("%s", "In function: debugger_write_register()");
3758 
3759 	g_return_if_fail (IS_DEBUGGER (debugger));
3760 
3761 	buf = g_strdup_printf ("-data-evaluate-expression \"$%s=%s\"", name, value);
3762 	debugger_queue_command (debugger, buf, DEBUGGER_COMMAND_NO_ERROR, NULL, NULL, NULL);
3763 	g_free (buf);
3764 }
3765 
3766 static void
debugger_set_frame_finish(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3767 debugger_set_frame_finish (Debugger *debugger, const GDBMIValue *mi_results, const GList *cli_results, GError *error)
3768 
3769 {
3770 	gsize frame  = (gsize)debugger->priv->current_cmd.user_data;
3771 	debugger->priv->current_frame = frame;
3772 
3773 	g_signal_emit_by_name (debugger->priv->instance, "frame-changed", frame, debugger->priv->current_thread);
3774 }
3775 
3776 void
debugger_set_frame(Debugger * debugger,gsize frame)3777 debugger_set_frame (Debugger *debugger, gsize frame)
3778 {
3779 	gchar *buff;
3780 
3781 	DEBUG_PRINT ("%s", "In function: debugger_set_frame()");
3782 
3783 	g_return_if_fail (IS_DEBUGGER (debugger));
3784 
3785 	buff = g_strdup_printf ("-stack-select-frame %" G_GSIZE_FORMAT, frame);
3786 
3787 	debugger_queue_command (debugger, buff, 0, (DebuggerParserFunc)debugger_set_frame_finish, NULL, (gpointer)frame);
3788 	g_free (buff);
3789 }
3790 
3791 void
debugger_set_log(Debugger * debugger,IAnjutaMessageView * log)3792 debugger_set_log (Debugger *debugger, IAnjutaMessageView *log)
3793 {
3794 	debugger->priv->log = log;
3795 }
3796 
3797 /* Variable objects functions
3798  *---------------------------------------------------------------------------*/
3799 
3800 void
debugger_delete_variable(Debugger * debugger,const gchar * name)3801 debugger_delete_variable (Debugger *debugger, const gchar* name)
3802 {
3803 	gchar *buff;
3804 
3805 	DEBUG_PRINT ("%s", "In function: delete_variable()");
3806 
3807 	g_return_if_fail (IS_DEBUGGER (debugger));
3808 
3809 	buff = g_strdup_printf ("-var-delete %s", name);
3810 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
3811 	g_free (buff);
3812 }
3813 
3814 static void
gdb_var_evaluate_expression(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3815 gdb_var_evaluate_expression (Debugger *debugger,
3816                         const GDBMIValue *mi_results, const GList *cli_results,
3817 			GError *error)
3818 {
3819 	const gchar *value = NULL;
3820 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3821 	gpointer user_data = debugger->priv->current_cmd.user_data;
3822 
3823 	if (mi_results != NULL)
3824 	{
3825 		const GDBMIValue *const gdbmi_value =
3826 	                        gdbmi_value_hash_lookup (mi_results, "value");
3827 
3828 		if (gdbmi_value != NULL)
3829 			value = gdbmi_value_literal_get (gdbmi_value);
3830 	}
3831 	callback ((const gpointer)value, user_data, NULL);
3832 }
3833 
3834 void
debugger_evaluate_variable(Debugger * debugger,const gchar * name,IAnjutaDebuggerGCharCallback callback,gpointer user_data)3835 debugger_evaluate_variable (Debugger *debugger, const gchar* name, IAnjutaDebuggerGCharCallback callback, gpointer user_data)
3836 {
3837 	gchar *buff;
3838 
3839 	DEBUG_PRINT ("%s", "In function: evaluate_variable()");
3840 
3841 	g_return_if_fail (IS_DEBUGGER (debugger));
3842 
3843 	buff = g_strdup_printf ("-var-evaluate-expression %s", name);
3844 	debugger_queue_command (debugger, buff, 0, gdb_var_evaluate_expression, (IAnjutaDebuggerCallback)callback, user_data);
3845 	g_free (buff);
3846 }
3847 
3848 void
debugger_assign_variable(Debugger * debugger,const gchar * name,const gchar * value)3849 debugger_assign_variable (Debugger *debugger, const gchar* name, const gchar *value)
3850 {
3851 	gchar *buff;
3852 
3853 	DEBUG_PRINT ("%s", "In function: assign_variable()");
3854 
3855 	g_return_if_fail (IS_DEBUGGER (debugger));
3856 
3857 	buff = g_strdup_printf ("-var-assign %s %s", name, value);
3858 	debugger_queue_command (debugger, buff, 0, NULL, NULL, NULL);
3859 	g_free (buff);
3860 }
3861 
3862 static void
gdb_var_list_children(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3863 gdb_var_list_children (Debugger *debugger,
3864                         const GDBMIValue *mi_results, const GList *cli_results,
3865 			GError *error)
3866 {
3867 	GList* list = NULL;
3868 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3869 	gpointer user_data = debugger->priv->current_cmd.user_data;
3870 
3871 	if (mi_results != NULL)
3872 	{
3873 		const GDBMIValue *literal;
3874 		const GDBMIValue *children;
3875 		glong numchild = 0;
3876 		glong i = 0;
3877 
3878 		literal = gdbmi_value_hash_lookup (mi_results, "numchild");
3879 
3880 		if (literal)
3881 			numchild = strtoul(gdbmi_value_literal_get (literal), NULL, 0);
3882 		children = gdbmi_value_hash_lookup (mi_results, "children");
3883 
3884 		for(i = 0 ; i < numchild; ++i)
3885 		{
3886 			const GDBMIValue *const gdbmi_chl =
3887 							gdbmi_value_list_get_nth (children, i);
3888 			IAnjutaDebuggerVariableObject *var;
3889 
3890 			var = g_new0 (IAnjutaDebuggerVariableObject, 1);
3891 
3892 			literal  = gdbmi_value_hash_lookup (gdbmi_chl, "name");
3893 			if (literal)
3894 				var->name = (gchar *)gdbmi_value_literal_get (literal);
3895 
3896 			literal = gdbmi_value_hash_lookup (gdbmi_chl, "exp");
3897 			if (literal)
3898 			var->expression = (gchar *)gdbmi_value_literal_get(literal);
3899 
3900 			literal = gdbmi_value_hash_lookup (gdbmi_chl, "type");
3901 			if (literal)
3902 				var->type = (gchar *)gdbmi_value_literal_get(literal);
3903 
3904 			literal = gdbmi_value_hash_lookup (gdbmi_chl, "value");
3905 			if (literal)
3906 				var->value = (gchar *)gdbmi_value_literal_get(literal);
3907 
3908 			literal = gdbmi_value_hash_lookup (gdbmi_chl, "numchild");
3909 			if (literal)
3910 				var->children = strtoul(gdbmi_value_literal_get(literal), NULL, 10);
3911 
3912 			literal = gdbmi_value_hash_lookup (gdbmi_chl, "has_more");
3913 			if (literal)
3914 				var->has_more = *gdbmi_value_literal_get(literal) == '1' ? TRUE : FALSE;
3915 
3916 			list = g_list_prepend (list, var);
3917 		}
3918 
3919 		literal = gdbmi_value_hash_lookup (mi_results, "has_more");
3920 		if (literal && (*gdbmi_value_literal_get(literal) == '1'))
3921 		{
3922 			/* Add a dummy children to represent additional children */
3923 			IAnjutaDebuggerVariableObject *var;
3924 
3925 			var = g_new0 (IAnjutaDebuggerVariableObject, 1);
3926 			var->expression = _("more children");
3927 			var->type = "";
3928 			var->value = "";
3929 			var->has_more = TRUE;
3930 			list = g_list_prepend (list, var);
3931 		}
3932 
3933 		list = g_list_reverse (list);
3934 	}
3935 
3936 	callback (list, user_data, NULL);
3937 	g_list_foreach (list, (GFunc)g_free, NULL);
3938 	g_list_free (list);
3939 }
3940 
debugger_list_variable_children(Debugger * debugger,const gchar * name,guint from,IAnjutaDebuggerGListCallback callback,gpointer user_data)3941 void debugger_list_variable_children (Debugger *debugger, const gchar* name, guint from, IAnjutaDebuggerGListCallback callback, gpointer user_data)
3942 {
3943 	gchar *buff;
3944 
3945 	DEBUG_PRINT ("%s", "In function: list_variable_children()");
3946 
3947 	g_return_if_fail (IS_DEBUGGER (debugger));
3948 
3949 	buff = g_strdup_printf ("-var-list-children --all-values %s %d %d", name, from, from + MAX_CHILDREN);
3950 	debugger_queue_command (debugger, buff, 0, gdb_var_list_children, (IAnjutaDebuggerCallback)callback, user_data);
3951 	g_free (buff);
3952 }
3953 
3954 static void
gdb_var_create(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)3955 gdb_var_create (Debugger *debugger,
3956                 const GDBMIValue *mi_results, const GList *cli_results,
3957 		GError *error)
3958 {
3959 	const GDBMIValue * result;
3960 	IAnjutaDebuggerVariableObject var = {0,};
3961 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
3962 	gpointer user_data = debugger->priv->current_cmd.user_data;
3963 
3964 	if ((error == NULL) && (mi_results != NULL))
3965 	{
3966 		result = gdbmi_value_hash_lookup (mi_results, "name");
3967 		var.name = (gchar *)gdbmi_value_literal_get(result);
3968 
3969 		result = gdbmi_value_hash_lookup (mi_results, "type");
3970 		var.type = (gchar *)gdbmi_value_literal_get (result);
3971 
3972 		result = gdbmi_value_hash_lookup (mi_results, "numchild");
3973 		var.children = strtoul (gdbmi_value_literal_get(result), NULL, 10);
3974 
3975 		result = gdbmi_value_hash_lookup (mi_results, "has_more");
3976 		if (result != NULL)
3977 		{
3978 			var.has_more = *gdbmi_value_literal_get(result) == '1' ? TRUE : FALSE;
3979 		}
3980 		else
3981 		{
3982 			var.has_more = FALSE;
3983 		}
3984 	}
3985 	callback (&var, user_data, error);
3986 
3987 }
3988 
debugger_create_variable(Debugger * debugger,const gchar * name,IAnjutaDebuggerVariableCallback callback,gpointer user_data)3989 void debugger_create_variable (Debugger *debugger, const gchar* name, IAnjutaDebuggerVariableCallback callback, gpointer user_data)
3990 {
3991 	gchar *buff;
3992 
3993 	DEBUG_PRINT ("%s", "In function: create_variable()");
3994 
3995 	g_return_if_fail (IS_DEBUGGER (debugger));
3996 
3997 	buff = g_strdup_printf ("-var-create - @ %s", name);
3998 	debugger_queue_command (debugger, buff, 0, gdb_var_create, (IAnjutaDebuggerCallback)callback, user_data);
3999 	g_free (buff);
4000 }
4001 
4002 static void
gdb_var_update(Debugger * debugger,const GDBMIValue * mi_results,const GList * cli_results,GError * error)4003 gdb_var_update (Debugger *debugger,
4004                 const GDBMIValue *mi_results, const GList *cli_results,
4005 		GError *error)
4006 {
4007 	GList* list = NULL;
4008 	glong idx = 0, changed_count = 0;
4009 	const GDBMIValue *const gdbmi_changelist =
4010                      gdbmi_value_hash_lookup (mi_results, "changelist");
4011 	IAnjutaDebuggerCallback callback = debugger->priv->current_cmd.callback;
4012 	gpointer user_data = debugger->priv->current_cmd.user_data;
4013 
4014 
4015 	changed_count = gdbmi_value_get_size (gdbmi_changelist);
4016 	for(; idx<changed_count; ++idx)
4017     {
4018 		const GDBMIValue *const gdbmi_change =
4019                          gdbmi_value_list_get_nth (gdbmi_changelist, idx);
4020 		const GDBMIValue * value;
4021 
4022 
4023 		value = gdbmi_value_hash_lookup (gdbmi_change, "name");
4024 		if (value)
4025 		{
4026 			IAnjutaDebuggerVariableObject *var = g_new0 (IAnjutaDebuggerVariableObject, 1);
4027 			var->changed = TRUE;
4028 			var->name = (gchar *)gdbmi_value_literal_get(value);
4029 			list = g_list_prepend (list, var);
4030 
4031 			value = gdbmi_value_hash_lookup (gdbmi_change, "type_changed");
4032 			if (value != NULL)
4033 			{
4034 				const gchar *type_changed = gdbmi_value_literal_get (value);
4035 
4036 				if (strcmp (type_changed, "true") == 0)
4037 				{
4038 					var->deleted = TRUE;
4039 				}
4040 			}
4041 
4042 			value = gdbmi_value_hash_lookup (gdbmi_change, "in_scope");
4043 			if (value != NULL)
4044 			{
4045 				const gchar *in_scope = gdbmi_value_literal_get(value);
4046 
4047 				if (strcmp (in_scope, "false") == 0)
4048 				{
4049 					var->exited = TRUE;
4050 				}
4051 				else if (strcmp (in_scope, "invalid") == 0)
4052 				{
4053 					var->deleted = TRUE;
4054 				}
4055 			}
4056 		}
4057 	}
4058 	list = g_list_reverse (list);
4059 	callback (list, user_data, NULL);
4060 	g_list_foreach (list, (GFunc)g_free, NULL);
4061 	g_list_free (list);
4062 }
4063 
debugger_update_variable(Debugger * debugger,IAnjutaDebuggerGListCallback callback,gpointer user_data)4064 void debugger_update_variable (Debugger *debugger, IAnjutaDebuggerGListCallback callback, gpointer user_data)
4065 {
4066 	DEBUG_PRINT ("%s", "In function: update_variable()");
4067 
4068 	g_return_if_fail (IS_DEBUGGER (debugger));
4069 
4070 	debugger_queue_command (debugger, "-var-update *", 0, gdb_var_update, (IAnjutaDebuggerCallback)callback, user_data);
4071 }
4072 
4073 GType
debugger_get_type(void)4074 debugger_get_type (void)
4075 {
4076 	static GType obj_type = 0;
4077 
4078 	if (!obj_type)
4079 	{
4080 		static const GTypeInfo obj_info =
4081 		{
4082 			sizeof (DebuggerClass),
4083 			(GBaseInitFunc) NULL,
4084 			(GBaseFinalizeFunc) NULL,
4085 			(GClassInitFunc) debugger_class_init,
4086 			(GClassFinalizeFunc) NULL,
4087 			NULL,           /* class_data */
4088 			sizeof (Debugger),
4089 			0,              /* n_preallocs */
4090 			(GInstanceInitFunc) debugger_instance_init,
4091 			NULL            /* value_table */
4092 		};
4093 		obj_type = g_type_register_static (G_TYPE_OBJECT,
4094 		                                   "Debugger", &obj_info, 0);
4095 	}
4096 	return obj_type;
4097 }
4098 
4099 static void
debugger_dispose(GObject * obj)4100 debugger_dispose (GObject *obj)
4101 {
4102 	Debugger *debugger = DEBUGGER (obj);
4103 
4104 	DEBUG_PRINT ("%s", "In function: debugger_shutdown()");
4105 
4106 	/* Do not emit signal when the debugger is destroyed */
4107 	debugger->priv->instance = NULL;
4108 	debugger_abort (debugger);
4109 
4110 	/* Good Bye message */
4111 	if (debugger->priv->output_callback)
4112 	{
4113 		debugger->priv->output_callback (IANJUTA_DEBUGGER_OUTPUT,
4114 							   "Debugging session completed.\n",
4115 							   debugger->priv->output_user_data);
4116 	}
4117 
4118 	if (debugger->priv->launcher)
4119 	{
4120  		anjuta_launcher_reset (debugger->priv->launcher);
4121 		g_object_unref (debugger->priv->launcher);
4122 		debugger->priv->launcher = NULL;
4123 	}
4124 
4125 	G_OBJECT_CLASS (parent_class)->dispose (obj);
4126 }
4127 
4128 static void
debugger_finalize(GObject * obj)4129 debugger_finalize (GObject *obj)
4130 {
4131 	Debugger *debugger = DEBUGGER (obj);
4132 	g_string_free (debugger->priv->stdo_line, TRUE);
4133 	g_string_free (debugger->priv->stdo_acc, TRUE);
4134 	g_string_free (debugger->priv->stde_line, TRUE);
4135 	g_free (debugger->priv->remote_server);
4136 	g_free (debugger->priv->load_pretty_printer);
4137 	g_free (debugger->priv);
4138 	G_OBJECT_CLASS (parent_class)->finalize (obj);
4139 }
4140 
4141 static void
debugger_class_init(DebuggerClass * klass)4142 debugger_class_init (DebuggerClass * klass)
4143 {
4144 	GObjectClass *object_class;
4145 
4146 	g_return_if_fail (klass != NULL);
4147 	object_class = G_OBJECT_CLASS (klass);
4148 
4149 	DEBUG_PRINT ("%s", "Initializing debugger class");
4150 
4151 	parent_class = g_type_class_peek_parent (klass);
4152 	object_class->dispose = debugger_dispose;
4153 	object_class->finalize = debugger_finalize;
4154 }
4155 
4156 
4157 #if 0 /* FIXME */
4158 void
4159 debugger_signal (const gchar *sig, gboolean show_msg)
4160 {
4161 	/* eg:- "SIGTERM" */
4162 	gchar *buff;
4163 	gchar *cmd;
4164 
4165 	DEBUG_PRINT ("%s", "In function: debugger_signal()");
4166 
4167 	if (debugger_is_active () == FALSE)
4168 		return;
4169 	if (debugger.prog_is_running == FALSE)
4170 		return;
4171 	if (debugger.child_pid < 1)
4172 	{
4173 		DEBUG_PRINT ("%s", "Not sending signal - pid not known\n");
4174 		return;
4175 	}
4176 
4177 	if (show_msg)
4178 	{
4179 		buff = g_strdup_printf (_("Sending signal %s to the process: %d"),
4180 								sig, (int) debugger.child_pid);
4181 		gdb_util_append_message (ANJUTA_PLUGIN (debugger.plugin), buff);
4182 		g_free (buff);
4183 	}
4184 
4185 	if (debugger_is_ready ())
4186 	{
4187 		cmd = g_strconcat ("signal ", sig, NULL);
4188 		stack_trace_set_frame (debugger.stack, 0);
4189 		debugger_put_cmd_in_queqe (cmd, DB_CMD_ALL, NULL, NULL);
4190 		debugger_put_cmd_in_queqe ("info program", DB_CMD_NONE,
4191 								   on_debugger_update_prog_status,
4192 								   NULL);
4193 		g_free (cmd);
4194 		debugger_execute_cmd_in_queqe ();
4195 	}
4196 	else
4197 	{
4198 		GtkWindow *parent;
4199 		int status;
4200 
4201 		parent = GTK_WINDOW (ANJUTA_PLUGIN (debugger.plugin)->shell);
4202 		status = gdb_util_kill_process (debugger.child_pid, sig);
4203 		if (status != 0 && show_msg)
4204 			anjuta_util_dialog_error (parent,
4205 									  _("Error whilst signaling the process."));
4206 	}
4207 }
4208 
4209 static void
4210 query_set_cmd (const gchar *cmd, gboolean state)
4211 {
4212 	gchar buffer[50];
4213 	gchar *tmp = g_stpcpy (buffer, cmd);
4214 	strcpy (tmp, state ? "on" : "off");
4215 	debugger_put_cmd_in_queqe (buffer, DB_CMD_NONE, NULL, NULL);
4216 }
4217 
4218 static void
4219 query_set_verbose (gboolean state)
4220 {
4221 	query_set_cmd ("set verbose ", state);
4222 }
4223 
4224 static void
4225 query_set_print_staticmembers (gboolean state)
4226 {
4227 	query_set_cmd ("set print static-members ", state);
4228 }
4229 
4230 static void
4231 query_set_print_pretty (gboolean state)
4232 {
4233 	query_set_cmd ("set print pretty ", state);
4234 }
4235 
4236 void debugger_query_evaluate_expr_tip (const gchar *expr,
4237 									   DebuggerCLIFunc parser, gpointer data)
4238 {
4239 	query_set_verbose (FALSE);
4240 	query_set_print_staticmembers (FALSE);
4241 	gchar *printcmd = g_strconcat ("print ", expr, NULL);
4242 	debugger_put_cmd_in_queqe (printcmd, DB_CMD_NONE, parser, data);
4243 	query_set_verbose (TRUE);
4244 	query_set_print_staticmembers (TRUE);
4245 	g_free (printcmd);
4246 }
4247 
4248 void
4249 debugger_query_evaluate_expression (const gchar *expr, DebuggerFunc parser,
4250 									gpointer data)
4251 {
4252 	query_set_print_pretty (TRUE);
4253 	query_set_verbose (FALSE);
4254 	gchar *printcmd = g_strconcat ("print ", expr, NULL);
4255 	debugger_put_cmd_in_queqe (printcmd, DB_CMD_SE_MESG | DB_CMD_SE_DIALOG,
4256 				parser, data);
4257 	query_set_print_pretty (FALSE);
4258 	query_set_verbose (TRUE);
4259 	g_free (printcmd);
4260 }
4261 
4262 #endif
4263