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