3
* gdb-io-run.c - Process execution and input functions for GDB wrapper library.
5
* See the file "gdb-io.h" for license information.
14
#include "gdb-io-priv.h"
18
extern gint g_unlink(const gchar * filename);
21
GdbIoSetup gdbio_setup;
24
static gchar *gdbio_args[] = { "gdb", "--interpreter=mi", "-nx", NULL };
26
static GPid gdbio_pid = 0;
27
static GPid target_pid = 0;
28
static GPid xterm_pid = 0;
30
static GSource *gdbio_src;
32
static gint gdbio_out;
33
static GIOChannel *gdbio_ch_in;
34
static GIOChannel *gdbio_ch_out;
35
static guint gdbio_id_in;
36
static guint gdbio_id_out;
38
static GString send_buf = { NULL, 0, 0 };
39
static GString recv_buf = { NULL, 0, 0 };
41
static gchar *xterm_tty_file = NULL;
44
static gint sequence = SEQ_MIN;
45
static gboolean is_running = FALSE;
46
static gint process_token = 0;
50
Hash table to associate a "tokenized" GDB command with a function call.
51
This stores a list of key-value pairs where the unique sequence-number
52
(GDB token) is the key, and a ResponseHandler function pointer is the value.
54
static GHashTable *sequencer;
58
#if !GLIB_CHECK_VERSION(2, 14, 0)
60
g_string_append_vprintf(GString *str, const gchar *fmt, va_list args)
62
gchar *tmp = g_strdup_vprintf(fmt, args);
63
g_string_append(str, tmp);
69
/* Add a handler function to the sequencer */
71
gdbio_send_seq_cmd(ResponseHandler func, const gchar * fmt, ...)
78
if (sequence >= SEQ_MAX)
88
sequencer = g_hash_table_new(g_direct_hash, g_direct_equal);
90
g_hash_table_insert(sequencer, GINT_TO_POINTER(sequence), func);
91
g_string_append_printf(&send_buf, "%d", sequence);
93
g_string_append_vprintf(&send_buf, fmt, args);
100
gdbio_seq_lookup(gint seq)
102
return g_hash_table_lookup(sequencer, GINT_TO_POINTER(seq));
107
gdbio_pop_seq(gint seq)
109
g_hash_table_remove(sequencer, GINT_TO_POINTER(seq));
113
gerror(gchar * msg, GError ** err)
119
gdbio_error_func("%s\n%s\n", msg, (*err)->message);
123
gdbio_error_func("%s\n", (*err)->message);
137
gdbio_atoi(gchar * str)
140
gint rv = strtol(str, &tail, 10);
141
return (tail && !*tail) ? rv : -1;
146
gdbio_error_func(gchar * fmt, ...)
151
msg = g_strdup_vprintf(fmt, args);
152
if (gdbio_setup.error_func)
154
gdbio_setup.error_func(g_strstrip(msg));
158
g_printerr("%s", msg);
166
gdbio_info_func(gchar * fmt, ...)
171
msg = g_strdup_vprintf(fmt, args);
172
if (gdbio_setup.info_func)
174
gdbio_setup.info_func(g_strstrip(msg));
178
g_printerr("%s", msg);
188
struct timespec req = { 0, 0 }, rem =
194
req.tv_sec = ms / 1000;
197
req.tv_nsec = rms * 1000000; /* 1 millisecond = 1,000,000 nanoseconds */
200
nanosleep(&req, &rem);
201
if ((rem.tv_sec || rem.tv_nsec))
203
memcpy(&req, &rem, sizeof(req));
204
memset(&rem, 0, sizeof(rem));
219
gdbio_send_cmd(const gchar * fmt, ...)
227
g_string_append_vprintf(&send_buf, fmt, args);
234
gdbio_set_running(gboolean running)
236
is_running = running;
246
kill(xterm_pid, SIGKILL);
254
start_xterm(gchar * term_cmd)
256
gchar *term_args[] = { "xterm", "-title", "Debug terminal", "-e", NULL, NULL, NULL };
259
gchar *tty_name = NULL;
260
const gchar *exe_name = basename(term_cmd);
262
if (!gdbio_setup.temp_dir)
264
gdbio_error_func(_("tty temporary directory not specified!\n"));
267
if (!g_file_test(gdbio_setup.temp_dir, G_FILE_TEST_IS_DIR))
269
gdbio_error_func(_("tty temporary directory not found!\n"));
274
xterm_tty_file = g_strdup_printf("%s/%d.tty", gdbio_setup.temp_dir, getpid());
276
if (g_file_set_contents(xterm_tty_file, "", -1, &err))
278
g_unlink(xterm_tty_file);
282
gerror("writing ttyname logfile", &err);
283
g_unlink(xterm_tty_file);
286
if (!gdbio_setup.tty_helper)
288
gdbio_error_func(_("tty helper program not specified!\n"));
292
(g_file_test(gdbio_setup.tty_helper, G_FILE_TEST_IS_EXECUTABLE) &&
293
g_file_test(gdbio_setup.tty_helper, G_FILE_TEST_IS_REGULAR)))
295
gdbio_error_func(_("tty helper program not found!\n"));
298
term_args[0] = term_cmd;
299
if (g_str_equal(exe_name, "xterm") || g_str_equal(exe_name, "konsole"))
305
if (g_str_equal(exe_name, "gnome-terminal"))
307
term_args[1] = "--title";
312
if (g_str_equal(exe_name, "rxvt") || g_str_equal(exe_name, "urxvt"))
314
term_args[1] = "-title";
328
term_args[i] = gdbio_setup.tty_helper;
329
term_args[i + 1] = xterm_tty_file;
330
all = g_strjoinv("\" \"", term_args);
331
gdbio_info_func("\"%s\"\n", all);
333
if (g_spawn_async(NULL, term_args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, &xterm_pid, &err))
335
gchar *contents = NULL;
340
if (g_file_test(xterm_tty_file, G_FILE_TEST_EXISTS))
342
if (g_file_get_contents(xterm_tty_file, &contents, &len, &err))
344
g_strstrip(contents);
345
if (strlen(contents))
347
tty_name = g_strdup(contents);
348
gdbio_info_func(_("Attaching to terminal %s\n"),
355
gerror("Error getting tty name:", &err);
358
ms += gdbio_wait(250);
363
gdbio_error_func(_("Timeout waiting for TTY name.\n"));
369
gerror("Error starting terminal: ", &err);
371
g_unlink(xterm_tty_file);
378
free_buf(GString * buf)
385
buf->allocated_len = 0;
390
shutdown_channel(GIOChannel ** ch)
395
gint fd = g_io_channel_unix_get_fd(*ch);
396
g_io_channel_shutdown(*ch, TRUE, &err);
397
gerror("Shutting down channel", &err);
398
g_io_channel_unref(*ch);
409
on_gdb_exit(GPid pid, gint status, gpointer data)
412
gdbio_info_func(_("GDB exited (pid=%d)\n"), pid);
413
g_spawn_close_pid(pid);
416
g_source_remove(gdbio_id_in);
417
shutdown_channel(&gdbio_ch_in);
419
g_source_remove(gdbio_id_out);
420
shutdown_channel(&gdbio_ch_out);
425
gdbio_info_func("%s\n", recv_buf.str);
431
kill(target_pid, SIGKILL);
434
gdbio_set_running(FALSE);
435
gdblx_scanner_done();
436
gdbio_do_status(GdbDead);
442
on_send_to_gdb(GIOChannel * src, GIOCondition cond, gpointer data)
451
st = g_io_channel_write_chars(src, send_buf.str, send_buf.len, &count,
453
g_string_erase(&send_buf, 0, count);
454
if (err || (st == G_IO_STATUS_ERROR) || (st == G_IO_STATUS_EOF))
456
gerror("Error sending command", &err);
460
st = g_io_channel_flush(src, &err);
461
gerror("Error pushing command", &err);
471
gdbio_target_exited(gchar * reason)
473
gdbio_info_func(_("Target process exited. (pid=%d; %s%s)\n"), target_pid,
475
&& g_ascii_isdigit(reason[0]) ? _("code=") : _("reason:"),
476
reason ? reason : "unknown");
479
gdbio_set_running(FALSE);
480
gdbio_do_status(GdbFinished);
483
gdbio_pop_seq(process_token);
488
static GdbStatus gdbio_status = GdbDead;
491
gdbio_do_status(GdbStatus s)
494
if (gdbio_setup.status_func)
496
gdbio_setup.status_func(s);
507
kill(target_pid, SIGINT);
514
target_killed(gint seq, gchar ** list, gchar * resp)
516
GHashTable *h = gdbio_get_results(resp, list);
520
g_hash_table_destroy(h);
522
if (strncmp(resp, "^done", 5) == 0)
524
gdbio_target_exited("killed by GDB");
531
gdbio_kill_target(gboolean force)
536
GPid this_pid = target_pid;
538
snprintf(pidstr, sizeof(pidstr) - 1, "/proc/%d", target_pid);
539
if (!g_file_test(pidstr, G_FILE_TEST_IS_DIR))
541
gdbio_info_func(_("Directory %s not found!\n"), pidstr);
546
gdbio_info_func(_("Shutting down target program.\n"));
547
gdbio_send_seq_cmd(target_killed, "kill SIGKILL\n");
553
gdbio_info_func(_("Killing target program.\n"));
554
kill(this_pid, SIGKILL);
561
gdbio_info_func(_("Timeout waiting for target process.\n"));
564
gdbio_info_func(_("Using a bigger hammer!\n"));
565
gdbio_kill_target(TRUE);
569
if (target_pid != this_pid)
573
if ((pidstr[0]) && !g_file_test(pidstr, G_FILE_TEST_EXISTS))
578
gdbio_info_func(_("Waiting for target process to exit.\n"));
579
ms += gdbio_wait(250);
588
return (gdbio_status == GdbLoaded) || (gdbio_status == GdbStopped)
589
|| (gdbio_status == GdbFinished);
595
gdbio_kill_target(!have_console());
598
GPid this_gdb = gdbio_pid;
601
snprintf(pidstr, sizeof(pidstr) - 1, "/proc/%d", this_gdb);
604
if (!g_file_test(pidstr, G_FILE_TEST_IS_DIR))
606
gdbio_info_func(_("Directory %s not found!\n"), pidstr);
612
if (gdbio_pid == this_gdb)
614
gdbio_info_func(_("Killing GDB (pid=%d)\n"), this_gdb);
620
kill(this_gdb, SIGKILL);
621
ms += gdbio_wait(500);
622
if (pidstr[0] && !g_file_test(pidstr, G_FILE_TEST_EXISTS))
628
gdbio_error_func(_("Timeout trying to kill GDB.\n"));
638
gdbio_info_func(_("Shutting down GDB\n"));
639
gdbio_send_cmd("-gdb-exit\n");
643
ms += gdbio_wait(250);
644
if (pidstr[0] && !g_file_test(pidstr, G_FILE_TEST_EXISTS))
648
if (gdbio_pid == this_gdb)
651
gdbio_info_func(_("Waiting for GDB to exit.\n"));
659
gdbio_info_func(_("Timeout waiting for GDB to exit.\n"));
660
gdbio_set_running(TRUE);
669
g_hash_table_destroy(sequencer);
672
g_free(xterm_tty_file);
673
xterm_tty_file = NULL;
678
void gdbio_parse_file_list(gint seq, gchar ** list, gchar * resp);
681
load_target(const gchar * exe_name)
683
gdbio_set_running(FALSE);
684
gdbio_send_cmd("-file-exec-and-symbols %s\n", exe_name);
685
gdbio_send_seq_cmd(gdbio_parse_file_list, "-file-list-exec-source-files\n");
692
on_read_from_gdb(GIOChannel * src, GIOCondition cond, gpointer data)
698
st = g_io_channel_read_chars(src, buf, sizeof(buf) - 1, &count, &err);
700
g_string_append_len(&recv_buf, buf, count);
701
gerror("Error reading response", &err);
702
gdbio_consume_response(&recv_buf);
708
#define GDB_SPAWN_FLAGS \
709
G_SPAWN_SEARCH_PATH | \
710
G_SPAWN_DO_NOT_REAP_CHILD
714
gdbio_load(const gchar * exe_name)
718
if (g_spawn_async_with_pipes(NULL, gdbio_args, NULL,
719
GDB_SPAWN_FLAGS, NULL,
720
NULL, &gdbio_pid, &gdbio_in, &gdbio_out, NULL, &err))
722
gdbio_info_func(_("Starting gdb (pid=%d)\n"), gdbio_pid);
724
g_child_watch_add(gdbio_pid, on_gdb_exit, NULL);
725
gdbio_src = g_child_watch_source_new(gdbio_pid);
727
gdbio_ch_in = g_io_channel_unix_new(gdbio_in);
728
g_io_channel_set_encoding(gdbio_ch_in, NULL, &err);
729
gerror("Error setting encoding", &err);
730
g_io_channel_set_buffered(gdbio_ch_in, FALSE);
732
gdbio_ch_out = g_io_channel_unix_new(gdbio_out);
733
g_io_channel_set_encoding(gdbio_ch_out, NULL, &err);
734
gerror("Error setting encoding", &err);
735
g_io_channel_set_buffered(gdbio_ch_out, FALSE);
737
gdbio_id_in = g_io_add_watch(gdbio_ch_in, G_IO_OUT, on_send_to_gdb, NULL);
738
gdbio_id_out = g_io_add_watch(gdbio_ch_out, G_IO_IN, on_read_from_gdb, NULL);
740
gdbio_send_cmd("-gdb-set width 0\n-gdb-set height 0\n");
743
load_target(exe_name);
748
gerror("Error starting debugger.", &err);
755
gdbio_exec_target(gchar * terminal_command)
757
if (terminal_command)
759
gchar *tty_name = start_xterm(terminal_command);
762
gdbio_send_cmd("-inferior-tty-set %s\n", tty_name);
770
gdbio_pop_seq(process_token);
772
gdbio_set_starting(TRUE);
773
gdbio_do_status(GdbStartup);
774
process_token = gdbio_send_seq_cmd(gdbio_target_started, "-exec-run\n");
780
gdbio_set_target_pid(GPid pid)
782
gdbio_info_func(_("Started target process. (pid=%d)\n"), pid);
789
gdbio_get_target_pid()