1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995 Free Software Foundation, Inc.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
38 #include <sys/ioctl.h>
45 #include <sys/stropts.h>
48 /* Handle for TCL interpreter */
49 static Tcl_Interp *interp = NULL;
51 /* Handle for TK main window */
52 static Tk_Window mainWindow = NULL;
54 static int x_fd; /* X network socket */
56 /* This variable determines where memory used for disassembly is read from.
58 If > 0, then disassembly comes from the exec file rather than the target
59 (which might be at the other end of a slow serial link). If == 0 then
60 disassembly comes from target. If < 0 disassembly is automatically switched
61 to the target if it's an inferior process, otherwise the exec file is
65 static int disassemble_from_exec = -1;
73 /* The following routines deal with stdout/stderr data, which is created by
74 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
75 lowest level of these routines and capture all output from the rest of GDB.
76 Normally they present their data to tcl via callbacks to the following tcl
77 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
78 in turn call tk routines to update the display.
80 Under some circumstances, you may want to collect the output so that it can
81 be returned as the value of a tcl procedure. This can be done by
82 surrounding the output routines with calls to start_saving_output and
83 finish_saving_output. The saved data can then be retrieved with
84 get_saved_output (but this must be done before the call to
85 finish_saving_output). */
87 /* Dynamic string header for stdout. */
89 static Tcl_DString *result_ptr;
96 /* Force immediate screen update */
98 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
103 gdbtk_fputs (ptr, stream)
108 Tcl_DStringAppend (result_ptr, ptr, -1);
113 Tcl_DStringInit (&str);
115 Tcl_DStringAppend (&str, "gdbtk_tcl_fputs", -1);
116 Tcl_DStringAppendElement (&str, ptr);
118 Tcl_Eval (interp, Tcl_DStringValue (&str));
119 Tcl_DStringFree (&str);
131 query = va_arg (args, char *);
133 vsprintf (buf, query, args);
134 Tcl_VarEval (interp, "gdbtk_tcl_query ", "{", buf, "}", NULL);
136 val = atol (interp->result);
141 dsprintf_append_element (va_alist)
151 dsp = va_arg (args, Tcl_DString *);
152 format = va_arg (args, char *);
154 vsprintf (buf, format, args);
156 Tcl_DStringAppendElement (dsp, buf);
160 gdb_get_breakpoint_list (clientData, interp, argc, argv)
161 ClientData clientData;
166 struct breakpoint *b;
167 extern struct breakpoint *breakpoint_chain;
170 error ("wrong # args");
172 for (b = breakpoint_chain; b; b = b->next)
173 if (b->type == bp_breakpoint)
174 dsprintf_append_element (result_ptr, "%d", b->number);
180 gdb_get_breakpoint_info (clientData, interp, argc, argv)
181 ClientData clientData;
186 struct symtab_and_line sal;
187 static char *bptypes[] = {"breakpoint", "hardware breakpoint", "until",
188 "finish", "watchpoint", "hardware watchpoint",
189 "read watchpoint", "access watchpoint",
190 "longjmp", "longjmp resume", "step resume",
191 "through sigtramp", "watchpoint scope",
193 static char *bpdisp[] = {"delete", "disable", "donttouch"};
194 struct command_line *cmd;
196 struct breakpoint *b;
197 extern struct breakpoint *breakpoint_chain;
200 error ("wrong # args");
202 bpnum = atoi (argv[1]);
204 for (b = breakpoint_chain; b; b = b->next)
205 if (b->number == bpnum)
208 if (!b || b->type != bp_breakpoint)
209 error ("Breakpoint #%d does not exist", bpnum);
211 sal = find_pc_line (b->address, 0);
213 Tcl_DStringAppendElement (result_ptr, symtab_to_filename (sal.symtab));
214 dsprintf_append_element (result_ptr, "%d", sal.line);
215 dsprintf_append_element (result_ptr, "0x%lx", b->address);
216 Tcl_DStringAppendElement (result_ptr, bptypes[b->type]);
217 Tcl_DStringAppendElement (result_ptr, b->enable == enabled ? "1" : "0");
218 Tcl_DStringAppendElement (result_ptr, bpdisp[b->disposition]);
219 dsprintf_append_element (result_ptr, "%d", b->silent);
220 dsprintf_append_element (result_ptr, "%d", b->ignore_count);
222 Tcl_DStringStartSublist (result_ptr);
223 for (cmd = b->commands; cmd; cmd = cmd->next)
224 Tcl_DStringAppendElement (result_ptr, cmd->line);
225 Tcl_DStringEndSublist (result_ptr);
227 Tcl_DStringAppendElement (result_ptr, b->cond_string);
229 dsprintf_append_element (result_ptr, "%d", b->thread);
230 dsprintf_append_element (result_ptr, "%d", b->hit_count);
236 breakpoint_notify(b, action)
237 struct breakpoint *b;
243 if (b->type != bp_breakpoint)
246 sprintf (buf, "gdbtk_tcl_breakpoint %s %d", action, b->number);
248 v = Tcl_Eval (interp, buf);
252 gdbtk_fputs (interp->result, gdb_stdout);
253 gdbtk_fputs ("\n", gdb_stdout);
258 gdbtk_create_breakpoint(b)
259 struct breakpoint *b;
261 breakpoint_notify (b, "create");
265 gdbtk_delete_breakpoint(b)
266 struct breakpoint *b;
268 breakpoint_notify (b, "delete");
272 gdbtk_modify_breakpoint(b)
273 struct breakpoint *b;
275 breakpoint_notify (b, "modify");
278 /* This implements the TCL command `gdb_loc', which returns a list consisting
279 of the source and line number associated with the current pc. */
282 gdb_loc (clientData, interp, argc, argv)
283 ClientData clientData;
289 struct symtab_and_line sal;
295 pc = selected_frame ? selected_frame->pc : stop_pc;
296 sal = find_pc_line (pc, 0);
300 struct symtabs_and_lines sals;
303 sals = decode_line_spec (argv[1], 1);
310 error ("Ambiguous line spec");
315 error ("wrong # args");
318 Tcl_DStringAppendElement (result_ptr, sal.symtab->filename);
320 Tcl_DStringAppendElement (result_ptr, "");
322 find_pc_partial_function (pc, &funcname, NULL, NULL);
323 Tcl_DStringAppendElement (result_ptr, funcname);
325 filename = symtab_to_filename (sal.symtab);
326 Tcl_DStringAppendElement (result_ptr, filename);
328 dsprintf_append_element (result_ptr, "%d", sal.line); /* line number */
330 dsprintf_append_element (result_ptr, "0x%lx", pc); /* PC */
335 /* This implements the TCL command `gdb_eval'. */
338 gdb_eval (clientData, interp, argc, argv)
339 ClientData clientData;
344 struct expression *expr;
345 struct cleanup *old_chain;
349 error ("wrong # args");
351 expr = parse_expression (argv[1]);
353 old_chain = make_cleanup (free_current_contents, &expr);
355 val = evaluate_expression (expr);
357 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
358 gdb_stdout, 0, 0, 0, 0);
360 do_cleanups (old_chain);
365 /* This implements the TCL command `gdb_sourcelines', which returns a list of
366 all of the lines containing executable code for the specified source file
367 (ie: lines where you can put breakpoints). */
370 gdb_sourcelines (clientData, interp, argc, argv)
371 ClientData clientData;
376 struct symtab *symtab;
377 struct linetable_entry *le;
381 error ("wrong # args");
383 symtab = lookup_symtab (argv[1]);
386 error ("No such file");
388 /* If there's no linetable, or no entries, then we are done. */
390 if (!symtab->linetable
391 || symtab->linetable->nitems == 0)
393 Tcl_DStringAppendElement (result_ptr, "");
397 le = symtab->linetable->item;
398 nlines = symtab->linetable->nitems;
400 for (;nlines > 0; nlines--, le++)
402 /* If the pc of this line is the same as the pc of the next line, then
405 && le->pc == (le + 1)->pc)
408 dsprintf_append_element (result_ptr, "%d", le->line);
415 map_arg_registers (argc, argv, func, argp)
418 void (*func) PARAMS ((int regnum, void *argp));
423 /* Note that the test for a valid register must include checking the
424 reg_names array because NUM_REGS may be allocated for the union of the
425 register sets within a family of related processors. In this case, the
426 trailing entries of reg_names will change depending upon the particular
427 processor being debugged. */
429 if (argc == 0) /* No args, just do all the regs */
433 && reg_names[regnum] != NULL
434 && *reg_names[regnum] != '\000';
441 /* Else, list of register #s, just do listed regs */
442 for (; argc > 0; argc--, argv++)
444 regnum = atoi (*argv);
448 && reg_names[regnum] != NULL
449 && *reg_names[regnum] != '\000')
452 error ("bad register number");
459 get_register_name (regnum, argp)
461 void *argp; /* Ignored */
463 Tcl_DStringAppendElement (result_ptr, reg_names[regnum]);
466 /* This implements the TCL command `gdb_regnames', which returns a list of
467 all of the register names. */
470 gdb_regnames (clientData, interp, argc, argv)
471 ClientData clientData;
479 return map_arg_registers (argc, argv, get_register_name, 0);
482 #ifndef REGISTER_CONVERTIBLE
483 #define REGISTER_CONVERTIBLE(x) (0 != 0)
486 #ifndef REGISTER_CONVERT_TO_VIRTUAL
487 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
490 #ifndef INVALID_FLOAT
491 #define INVALID_FLOAT(x, y) (0 != 0)
495 get_register (regnum, fp)
499 char raw_buffer[MAX_REGISTER_RAW_SIZE];
500 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
501 int format = (int)fp;
503 if (read_relative_register_raw_bytes (regnum, raw_buffer))
505 Tcl_DStringAppendElement (result_ptr, "Optimized out");
509 /* Convert raw data to virtual format if necessary. */
511 if (REGISTER_CONVERTIBLE (regnum))
513 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
514 raw_buffer, virtual_buffer);
517 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
519 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
520 gdb_stdout, format, 1, 0, Val_pretty_default);
522 Tcl_DStringAppend (result_ptr, " ", -1);
526 gdb_fetch_registers (clientData, interp, argc, argv)
527 ClientData clientData;
535 error ("wrong # args");
543 return map_arg_registers (argc, argv, get_register, format);
546 /* This contains the previous values of the registers, since the last call to
547 gdb_changed_register_list. */
549 static char old_regs[REGISTER_BYTES];
552 register_changed_p (regnum, argp)
554 void *argp; /* Ignored */
556 char raw_buffer[MAX_REGISTER_RAW_SIZE];
559 if (read_relative_register_raw_bytes (regnum, raw_buffer))
562 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
563 REGISTER_RAW_SIZE (regnum)) == 0)
566 /* Found a changed register. Save new value and return it's number. */
568 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
569 REGISTER_RAW_SIZE (regnum));
571 dsprintf_append_element (result_ptr, "%d", regnum);
575 gdb_changed_register_list (clientData, interp, argc, argv)
576 ClientData clientData;
584 return map_arg_registers (argc, argv, register_changed_p, NULL);
587 /* This implements the TCL command `gdb_cmd', which sends it's argument into
588 the GDB command scanner. */
591 gdb_cmd (clientData, interp, argc, argv)
592 ClientData clientData;
598 error ("wrong # args");
600 execute_command (argv[1], 1);
602 bpstat_do_actions (&stop_bpstat);
607 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
608 handles cleanups, and calls to return_to_top_level (usually via error).
609 This is necessary in order to prevent a longjmp out of the bowels of Tk,
610 possibly leaving things in a bad state. Since this routine can be called
611 recursively, it needs to save and restore the contents of the jmp_buf as
615 call_wrapper (clientData, interp, argc, argv)
616 ClientData clientData;
622 struct cleanup *saved_cleanup_chain;
624 jmp_buf saved_error_return;
625 Tcl_DString result, *old_result_ptr;
627 Tcl_DStringInit (&result);
628 old_result_ptr = result_ptr;
629 result_ptr = &result;
631 func = (Tcl_CmdProc *)clientData;
632 memcpy (saved_error_return, error_return, sizeof (jmp_buf));
634 saved_cleanup_chain = save_cleanups ();
636 if (!setjmp (error_return))
637 val = func (clientData, interp, argc, argv);
640 val = TCL_ERROR; /* Flag an error for TCL */
642 gdb_flush (gdb_stderr); /* Flush error output */
644 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
646 /* In case of an error, we may need to force the GUI into idle mode because
647 gdbtk_call_command may have bombed out while in the command routine. */
649 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
652 do_cleanups (ALL_CLEANUPS);
654 restore_cleanups (saved_cleanup_chain);
656 memcpy (error_return, saved_error_return, sizeof (jmp_buf));
658 Tcl_DStringResult (interp, &result);
659 result_ptr = old_result_ptr;
665 gdb_listfiles (clientData, interp, argc, argv)
666 ClientData clientData;
671 struct objfile *objfile;
672 struct partial_symtab *psymtab;
673 struct symtab *symtab;
675 ALL_PSYMTABS (objfile, psymtab)
676 Tcl_DStringAppendElement (result_ptr, psymtab->filename);
678 ALL_SYMTABS (objfile, symtab)
679 Tcl_DStringAppendElement (result_ptr, symtab->filename);
685 gdb_stop (clientData, interp, argc, argv)
686 ClientData clientData;
696 /* This implements the TCL command `gdb_disassemble'. */
699 gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
703 disassemble_info *info;
705 extern struct target_ops exec_ops;
709 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
720 /* We need a different sort of line table from the normal one cuz we can't
721 depend upon implicit line-end pc's for lines. This is because of the
722 reordering we are about to do. */
724 struct my_line_entry {
731 compare_lines (mle1p, mle2p)
735 struct my_line_entry *mle1, *mle2;
738 mle1 = (struct my_line_entry *) mle1p;
739 mle2 = (struct my_line_entry *) mle2p;
741 val = mle1->line - mle2->line;
746 return mle1->start_pc - mle2->start_pc;
750 gdb_disassemble (clientData, interp, argc, argv)
751 ClientData clientData;
756 CORE_ADDR pc, low, high;
757 int mixed_source_and_assembly;
758 static disassemble_info di = {
759 (fprintf_ftype) fprintf_filtered, /* fprintf_func */
760 gdb_stdout, /* stream */
761 NULL, /* application_data */
763 NULL, /* private_data */
764 NULL, /* read_memory_func */
765 dis_asm_memory_error, /* memory_error_func */
766 dis_asm_print_address /* print_address_func */
769 if (argc != 3 && argc != 4)
770 error ("wrong # args");
772 if (strcmp (argv[1], "source") == 0)
773 mixed_source_and_assembly = 1;
774 else if (strcmp (argv[1], "nosource") == 0)
775 mixed_source_and_assembly = 0;
777 error ("First arg must be 'source' or 'nosource'");
779 low = parse_and_eval_address (argv[2]);
783 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
784 error ("No function contains specified address");
787 high = parse_and_eval_address (argv[3]);
789 /* If disassemble_from_exec == -1, then we use the following heuristic to
790 determine whether or not to do disassembly from target memory or from the
793 If we're debugging a local process, read target memory, instead of the
794 exec file. This makes disassembly of functions in shared libs work
797 Else, we're debugging a remote process, and should disassemble from the
798 exec file for speed. However, this is no good if the target modifies it's
799 code (for relocation, or whatever).
802 if (disassemble_from_exec == -1)
803 if (strcmp (target_shortname, "child") == 0
804 || strcmp (target_shortname, "procfs") == 0)
805 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
807 disassemble_from_exec = 1; /* It's remote, read the exec file */
809 if (disassemble_from_exec)
810 di.read_memory_func = gdbtk_dis_asm_read_memory;
812 di.read_memory_func = dis_asm_read_memory;
814 /* If just doing straight assembly, all we need to do is disassemble
815 everything between low and high. If doing mixed source/assembly, we've
816 got a totally different path to follow. */
818 if (mixed_source_and_assembly)
819 { /* Come here for mixed source/assembly */
820 /* The idea here is to present a source-O-centric view of a function to
821 the user. This means that things are presented in source order, with
822 (possibly) out of order assembly immediately following. */
823 struct symtab *symtab;
824 struct linetable_entry *le;
827 struct my_line_entry *mle;
828 struct symtab_and_line sal;
833 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
838 /* First, convert the linetable to a bunch of my_line_entry's. */
840 le = symtab->linetable->item;
841 nlines = symtab->linetable->nitems;
846 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
850 /* Copy linetable entries for this function into our data structure, creating
851 end_pc's and setting out_of_order as appropriate. */
853 /* First, skip all the preceding functions. */
855 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
857 /* Now, copy all entries before the end of this function. */
860 for (; i < nlines - 1 && le[i].pc < high; i++)
862 if (le[i].line == le[i + 1].line
863 && le[i].pc == le[i + 1].pc)
864 continue; /* Ignore duplicates */
866 mle[newlines].line = le[i].line;
867 if (le[i].line > le[i + 1].line)
869 mle[newlines].start_pc = le[i].pc;
870 mle[newlines].end_pc = le[i + 1].pc;
874 /* If we're on the last line, and it's part of the function, then we need to
875 get the end pc in a special way. */
880 mle[newlines].line = le[i].line;
881 mle[newlines].start_pc = le[i].pc;
882 sal = find_pc_line (le[i].pc, 0);
883 mle[newlines].end_pc = sal.end;
887 /* Now, sort mle by line #s (and, then by addresses within lines). */
890 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
892 /* Now, for each line entry, emit the specified lines (unless they have been
893 emitted before), followed by the assembly code for that line. */
895 next_line = 0; /* Force out first line */
896 for (i = 0; i < newlines; i++)
898 /* Print out everything from next_line to the current line. */
900 if (mle[i].line >= next_line)
903 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
905 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
907 next_line = mle[i].line + 1;
910 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
913 fputs_unfiltered (" ", gdb_stdout);
914 print_address (pc, gdb_stdout);
915 fputs_unfiltered (":\t ", gdb_stdout);
916 pc += (*tm_print_insn) (pc, &di);
917 fputs_unfiltered ("\n", gdb_stdout);
924 for (pc = low; pc < high; )
927 fputs_unfiltered (" ", gdb_stdout);
928 print_address (pc, gdb_stdout);
929 fputs_unfiltered (":\t ", gdb_stdout);
930 pc += (*tm_print_insn) (pc, &di);
931 fputs_unfiltered ("\n", gdb_stdout);
935 gdb_flush (gdb_stdout);
941 tk_command (cmd, from_tty)
947 struct cleanup *old_chain;
949 retval = Tcl_Eval (interp, cmd);
951 result = strdup (interp->result);
953 old_chain = make_cleanup (free, result);
955 if (retval != TCL_OK)
958 printf_unfiltered ("%s\n", result);
960 do_cleanups (old_chain);
964 cleanup_init (ignored)
967 if (mainWindow != NULL)
968 Tk_DestroyWindow (mainWindow);
972 Tcl_DeleteInterp (interp);
976 /* Come here during long calculations to check for GUI events. Usually invoked
977 via the QUIT macro. */
982 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
985 /* Come here when there is activity on the X file descriptor. */
991 /* Process pending events */
993 while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
997 gdbtk_wait (pid, ourstatus)
999 struct target_waitstatus *ourstatus;
1001 struct sigaction action;
1002 static sigset_t nullsigmask = {0};
1005 /* Needed for SunOS 4.1.x */
1006 #define SA_RESTART 0
1009 action.sa_handler = x_event;
1010 action.sa_mask = nullsigmask;
1011 action.sa_flags = SA_RESTART;
1012 sigaction(SIGIO, &action, NULL);
1014 pid = target_wait (pid, ourstatus);
1016 action.sa_handler = SIG_IGN;
1017 sigaction(SIGIO, &action, NULL);
1022 /* This is called from execute_command, and provides a wrapper around
1023 various command routines in a place where both protocol messages and
1024 user input both flow through. Mostly this is used for indicating whether
1025 the target process is running or not.
1029 gdbtk_call_command (cmdblk, arg, from_tty)
1030 struct cmd_list_element *cmdblk;
1034 if (cmdblk->class == class_run)
1036 Tcl_VarEval (interp, "gdbtk_tcl_busy", NULL);
1037 (*cmdblk->function.cfunc)(arg, from_tty);
1038 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
1041 (*cmdblk->function.cfunc)(arg, from_tty);
1047 struct cleanup *old_chain;
1048 char *gdbtk_filename;
1050 struct sigaction action;
1051 static sigset_t nullsigmask = {0};
1053 old_chain = make_cleanup (cleanup_init, 0);
1055 /* First init tcl and tk. */
1057 interp = Tcl_CreateInterp ();
1060 error ("Tcl_CreateInterp failed");
1062 mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
1065 return; /* DISPLAY probably not set */
1067 if (Tcl_Init(interp) != TCL_OK)
1068 error ("Tcl_Init failed: %s", interp->result);
1070 if (Tk_Init(interp) != TCL_OK)
1071 error ("Tk_Init failed: %s", interp->result);
1073 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1074 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
1075 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1077 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
1079 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1080 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1081 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1082 gdb_fetch_registers, NULL);
1083 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1084 gdb_changed_register_list, NULL);
1085 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1086 gdb_disassemble, NULL);
1087 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
1088 Tcl_CreateCommand (interp, "gdb_get_breakpoint_list", call_wrapper,
1089 gdb_get_breakpoint_list, NULL);
1090 Tcl_CreateCommand (interp, "gdb_get_breakpoint_info", call_wrapper,
1091 gdb_get_breakpoint_info, NULL);
1093 command_loop_hook = Tk_MainLoop;
1094 print_frame_info_listing_hook = null_routine;
1095 query_hook = gdbtk_query;
1096 flush_hook = gdbtk_flush;
1097 create_breakpoint_hook = gdbtk_create_breakpoint;
1098 delete_breakpoint_hook = gdbtk_delete_breakpoint;
1099 modify_breakpoint_hook = gdbtk_modify_breakpoint;
1100 interactive_hook = gdbtk_interactive;
1101 target_wait_hook = gdbtk_wait;
1102 call_command_hook = gdbtk_call_command;
1104 /* Get the file descriptor for the X server */
1106 x_fd = ConnectionNumber (Tk_Display (mainWindow));
1108 /* Setup for I/O interrupts */
1110 action.sa_mask = nullsigmask;
1111 action.sa_flags = 0;
1112 action.sa_handler = SIG_IGN;
1113 sigaction(SIGIO, &action, NULL);
1117 if (ioctl (x_fd, FIOASYNC, &i))
1118 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1121 if (ioctl (x_fd, SIOCSPGRP, &i))
1122 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1124 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
1125 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1126 #endif /* ifndef FIOASYNC */
1128 add_com ("tk", class_obscure, tk_command,
1129 "Send a command directly into tk.");
1131 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1134 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1136 gdbtk_filename = getenv ("GDBTK_FILENAME");
1137 if (!gdbtk_filename)
1138 if (access ("gdbtk.tcl", R_OK) == 0)
1139 gdbtk_filename = "gdbtk.tcl";
1141 gdbtk_filename = GDBTK_FILENAME;
1143 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1144 prior to this point go to stdout/stderr. */
1146 fputs_unfiltered_hook = gdbtk_fputs;
1148 if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
1150 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
1152 fprintf_unfiltered (stderr, "%s:%d: %s\n", gdbtk_filename,
1153 interp->errorLine, interp->result);
1155 fputs_unfiltered ("Stack trace:\n", gdb_stderr);
1156 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1160 discard_cleanups (old_chain);
1163 /* Come here during initialze_all_files () */
1166 _initialize_gdbtk ()
1170 /* Tell the rest of the world that Gdbtk is now set up. */
1172 init_ui_hook = gdbtk_init;