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>
43 #include <sys/stropts.h>
46 /* Non-zero means that we're doing the gdbtk interface. */
49 /* Non-zero means we are reloading breakpoints, etc from the
50 Gdbtk kernel, and we should suppress various messages */
51 static int gdbtk_reloading = 0;
53 /* Handle for TCL interpreter */
54 static Tcl_Interp *interp = NULL;
56 /* Handle for TK main window */
57 static Tk_Window mainWindow = NULL;
59 static int x_fd; /* X network socket */
61 /* This variable determines where memory used for disassembly is read from.
63 If > 0, then disassembly comes from the exec file rather than the target
64 (which might be at the other end of a slow serial link). If == 0 then
65 disassembly comes from target. If < 0 disassembly is automatically switched
66 to the target if it's an inferior process, otherwise the exec file is
70 static int disassemble_from_exec = -1;
78 /* The following routines deal with stdout/stderr data, which is created by
79 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
80 lowest level of these routines and capture all output from the rest of GDB.
81 Normally they present their data to tcl via callbacks to the following tcl
82 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
83 in turn call tk routines to update the display.
85 Under some circumstances, you may want to collect the output so that it can
86 be returned as the value of a tcl procedure. This can be done by
87 surrounding the output routines with calls to start_saving_output and
88 finish_saving_output. The saved data can then be retrieved with
89 get_saved_output (but this must be done before the call to
90 finish_saving_output). */
92 /* Dynamic string header for stdout. */
94 static Tcl_DString stdout_buffer;
96 /* Use this to collect stdout output that will be returned as the result of a
99 static int saving_output = 0;
102 start_saving_output ()
107 #define get_saved_output() (Tcl_DStringValue (&stdout_buffer))
110 finish_saving_output ()
117 Tcl_DStringFree (&stdout_buffer);
120 /* This routine redirects the output of fputs_unfiltered so that
121 the user can see what's going on in his debugger window. */
128 /* We use Tcl_Merge to quote braces and funny characters as necessary. */
130 argv[0] = Tcl_DStringValue (&stdout_buffer);
131 s = Tcl_Merge (1, argv);
133 Tcl_DStringFree (&stdout_buffer);
135 Tcl_VarEval (interp, "gdbtk_tcl_fputs ", s, NULL);
144 if (stream != gdb_stdout || saving_output)
147 /* Flush output from C to tcl land. */
151 /* Force immediate screen update */
153 Tcl_VarEval (interp, "gdbtk_tcl_flush", NULL);
157 gdbtk_fputs (ptr, stream)
163 if (stream != gdb_stdout)
165 Tcl_VarEval (interp, "gdbtk_tcl_fputs_error ", "{", ptr, "}", NULL);
169 Tcl_DStringAppend (&stdout_buffer, ptr, -1);
174 if (Tcl_DStringLength (&stdout_buffer) > 1000)
186 query = va_arg (args, char *);
188 vsprintf(buf, query, args);
189 Tcl_VarEval (interp, "gdbtk_tcl_query ", "{", buf, "}", NULL);
191 val = atol (interp->result);
196 breakpoint_notify(b, action)
197 struct breakpoint *b;
201 char bpnum[50], line[50], pc[50];
202 struct symtab_and_line sal;
206 if (b->type != bp_breakpoint)
209 sal = find_pc_line (b->address, 0);
211 filename = symtab_to_filename (sal.symtab);
213 sprintf (bpnum, "%d", b->number);
214 sprintf (line, "%d", sal.line);
215 sprintf (pc, "0x%lx", b->address);
217 v = Tcl_VarEval (interp,
218 "gdbtk_tcl_breakpoint ",
221 " ", filename ? filename : "{}",
228 gdbtk_fputs (interp->result, gdb_stdout);
229 gdbtk_fputs ("\n", gdb_stdout);
234 gdbtk_create_breakpoint(b)
235 struct breakpoint *b;
237 breakpoint_notify(b, "create");
241 gdbtk_delete_breakpoint(b)
242 struct breakpoint *b;
244 breakpoint_notify(b, "delete");
248 gdbtk_enable_breakpoint(b)
249 struct breakpoint *b;
251 breakpoint_notify(b, "enable");
255 gdbtk_disable_breakpoint(b)
256 struct breakpoint *b;
258 breakpoint_notify(b, "disable");
261 /* This implements the TCL command `gdb_loc', which returns a list consisting
262 of the source and line number associated with the current pc. */
265 gdb_loc (clientData, interp, argc, argv)
266 ClientData clientData;
273 struct symtab_and_line sal;
279 pc = selected_frame ? selected_frame->pc : stop_pc;
280 sal = find_pc_line (pc, 0);
284 struct symtabs_and_lines sals;
287 sals = decode_line_spec (argv[1], 1);
295 Tcl_SetResult (interp, "Ambiguous line spec", TCL_STATIC);
303 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
308 Tcl_AppendElement (interp, sal.symtab->filename);
310 Tcl_AppendElement (interp, "");
312 find_pc_partial_function (pc, &funcname, NULL, NULL);
313 Tcl_AppendElement (interp, funcname);
315 filename = symtab_to_filename (sal.symtab);
316 Tcl_AppendElement (interp, filename);
318 sprintf (buf, "%d", sal.line);
319 Tcl_AppendElement (interp, buf); /* line number */
321 sprintf (buf, "0x%lx", pc);
322 Tcl_AppendElement (interp, buf); /* PC */
327 /* This implements the TCL command `gdb_eval'. */
330 gdb_eval (clientData, interp, argc, argv)
331 ClientData clientData;
336 struct expression *expr;
337 struct cleanup *old_chain;
342 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
346 expr = parse_expression (argv[1]);
348 old_chain = make_cleanup (free_current_contents, &expr);
350 val = evaluate_expression (expr);
352 start_saving_output (); /* Start collecting stdout */
354 val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), VALUE_ADDRESS (val),
355 gdb_stdout, 0, 0, 0, 0);
357 value_print (val, gdb_stdout, 0, 0);
360 Tcl_AppendElement (interp, get_saved_output ());
362 finish_saving_output (); /* Set stdout back to normal */
364 do_cleanups (old_chain);
369 /* This implements the TCL command `gdb_sourcelines', which returns a list of
370 all of the lines containing executable code for the specified source file
371 (ie: lines where you can put breakpoints). */
374 gdb_sourcelines (clientData, interp, argc, argv)
375 ClientData clientData;
380 struct symtab *symtab;
381 struct linetable_entry *le;
387 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
391 symtab = lookup_symtab (argv[1]);
395 Tcl_SetResult (interp, "No such file", TCL_STATIC);
399 /* If there's no linetable, or no entries, then we are done. */
401 if (!symtab->linetable
402 || symtab->linetable->nitems == 0)
404 Tcl_AppendElement (interp, "");
408 le = symtab->linetable->item;
409 nlines = symtab->linetable->nitems;
411 for (;nlines > 0; nlines--, le++)
413 /* If the pc of this line is the same as the pc of the next line, then
416 && le->pc == (le + 1)->pc)
419 sprintf (buf, "%d", le->line);
420 Tcl_AppendElement (interp, buf);
427 map_arg_registers (argc, argv, func, argp)
430 int (*func) PARAMS ((int regnum, void *argp));
435 /* Note that the test for a valid register must include checking the
436 reg_names array because NUM_REGS may be allocated for the union of the
437 register sets within a family of related processors. In this case, the
438 trailing entries of reg_names will change depending upon the particular
439 processor being debugged. */
441 if (argc == 0) /* No args, just do all the regs */
445 && reg_names[regnum] != NULL
446 && *reg_names[regnum] != '\000';
453 /* Else, list of register #s, just do listed regs */
454 for (; argc > 0; argc--, argv++)
456 regnum = atoi (*argv);
460 && reg_names[regnum] != NULL
461 && *reg_names[regnum] != '\000')
465 Tcl_SetResult (interp, "bad register number", TCL_STATIC);
475 get_register_name (regnum, argp)
477 void *argp; /* Ignored */
479 Tcl_AppendElement (interp, reg_names[regnum]);
482 /* This implements the TCL command `gdb_regnames', which returns a list of
483 all of the register names. */
486 gdb_regnames (clientData, interp, argc, argv)
487 ClientData clientData;
495 return map_arg_registers (argc, argv, get_register_name, 0);
498 #ifndef REGISTER_CONVERTIBLE
499 #define REGISTER_CONVERTIBLE(x) (0 != 0)
502 #ifndef REGISTER_CONVERT_TO_VIRTUAL
503 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
506 #ifndef INVALID_FLOAT
507 #define INVALID_FLOAT(x, y) (0 != 0)
511 get_register (regnum, fp)
514 char raw_buffer[MAX_REGISTER_RAW_SIZE];
515 char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
516 int format = (int)fp;
518 if (read_relative_register_raw_bytes (regnum, raw_buffer))
520 Tcl_AppendElement (interp, "Optimized out");
524 start_saving_output (); /* Start collecting stdout */
526 /* Convert raw data to virtual format if necessary. */
528 if (REGISTER_CONVERTIBLE (regnum))
530 REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum),
531 raw_buffer, virtual_buffer);
534 memcpy (virtual_buffer, raw_buffer, REGISTER_VIRTUAL_SIZE (regnum));
536 val_print (REGISTER_VIRTUAL_TYPE (regnum), virtual_buffer, 0,
537 gdb_stdout, format, 1, 0, Val_pretty_default);
539 Tcl_AppendElement (interp, get_saved_output ());
541 finish_saving_output (); /* Set stdout back to normal */
545 gdb_fetch_registers (clientData, interp, argc, argv)
546 ClientData clientData;
555 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
565 return map_arg_registers (argc, argv, get_register, format);
568 /* This contains the previous values of the registers, since the last call to
569 gdb_changed_register_list. */
571 static char old_regs[REGISTER_BYTES];
574 register_changed_p (regnum, argp)
575 void *argp; /* Ignored */
577 char raw_buffer[MAX_REGISTER_RAW_SIZE];
580 if (read_relative_register_raw_bytes (regnum, raw_buffer))
583 if (memcmp (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
584 REGISTER_RAW_SIZE (regnum)) == 0)
587 /* Found a changed register. Save new value and return it's number. */
589 memcpy (&old_regs[REGISTER_BYTE (regnum)], raw_buffer,
590 REGISTER_RAW_SIZE (regnum));
592 sprintf (buf, "%d", regnum);
593 Tcl_AppendElement (interp, buf);
597 gdb_changed_register_list (clientData, interp, argc, argv)
598 ClientData clientData;
608 return map_arg_registers (argc, argv, register_changed_p, NULL);
611 /* This implements the TCL command `gdb_cmd', which sends it's argument into
612 the GDB command scanner. */
615 gdb_cmd (clientData, interp, argc, argv)
616 ClientData clientData;
623 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
627 execute_command (argv[1], 1);
629 bpstat_do_actions (&stop_bpstat);
631 /* Drain all buffered command output */
633 gdb_flush (gdb_stdout);
638 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
639 handles cleanups, and calls to return_to_top_level (usually via error).
640 This is necessary in order to prevent a longjmp out of the bowels of Tk,
641 possibly leaving things in a bad state. Since this routine can be called
642 recursively, it needs to save and restore the contents of the jmp_buf as
646 call_wrapper (clientData, interp, argc, argv)
647 ClientData clientData;
653 struct cleanup *saved_cleanup_chain;
655 jmp_buf saved_error_return;
657 func = (Tcl_CmdProc *)clientData;
658 memcpy (saved_error_return, error_return, sizeof (jmp_buf));
660 saved_cleanup_chain = save_cleanups ();
662 if (!setjmp (error_return))
663 val = func (clientData, interp, argc, argv);
666 val = TCL_ERROR; /* Flag an error for TCL */
668 finish_saving_output (); /* Restore stdout to normal */
670 dis_asm_read_memory_hook = 0; /* Restore disassembly hook */
672 gdb_flush (gdb_stderr); /* Flush error output */
674 gdb_flush (gdb_stdout); /* Sometimes error output comes here as well */
676 /* In case of an error, we may need to force the GUI into idle mode because
677 gdbtk_call_command may have bombed out while in the command routine. */
679 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
682 do_cleanups (ALL_CLEANUPS);
684 restore_cleanups (saved_cleanup_chain);
686 memcpy (error_return, saved_error_return, sizeof (jmp_buf));
692 gdb_listfiles (clientData, interp, argc, argv)
693 ClientData clientData;
699 struct objfile *objfile;
700 struct partial_symtab *psymtab;
701 struct symtab *symtab;
703 ALL_PSYMTABS (objfile, psymtab)
704 Tcl_AppendElement (interp, psymtab->filename);
706 ALL_SYMTABS (objfile, symtab)
707 Tcl_AppendElement (interp, symtab->filename);
713 gdb_stop (clientData, interp, argc, argv)
714 ClientData clientData;
724 /* This implements the TCL command `gdb_disassemble'. */
727 gdbtk_dis_asm_read_memory (memaddr, myaddr, len, info)
731 disassemble_info *info;
733 extern struct target_ops exec_ops;
737 res = xfer_memory (memaddr, myaddr, len, 0, &exec_ops);
748 /* We need a different sort of line table from the normal one cuz we can't
749 depend upon implicit line-end pc's for lines. This is because of the
750 reordering we are about to do. */
752 struct my_line_entry {
759 compare_lines (mle1p, mle2p)
763 struct my_line_entry *mle1, *mle2;
766 mle1 = (struct my_line_entry *) mle1p;
767 mle2 = (struct my_line_entry *) mle2p;
769 val = mle1->line - mle2->line;
774 return mle1->start_pc - mle2->start_pc;
778 gdb_disassemble (clientData, interp, argc, argv)
779 ClientData clientData;
784 CORE_ADDR pc, low, high;
785 int mixed_source_and_assembly;
787 if (argc != 3 && argc != 4)
789 Tcl_SetResult (interp, "wrong # args", TCL_STATIC);
793 if (strcmp (argv[1], "source") == 0)
794 mixed_source_and_assembly = 1;
795 else if (strcmp (argv[1], "nosource") == 0)
796 mixed_source_and_assembly = 0;
799 Tcl_SetResult (interp, "First arg must be 'source' or 'nosource'",
804 low = parse_and_eval_address (argv[2]);
808 if (find_pc_partial_function (low, NULL, &low, &high) == 0)
810 Tcl_SetResult (interp, "No function contains specified address",
816 high = parse_and_eval_address (argv[3]);
818 /* If disassemble_from_exec == -1, then we use the following heuristic to
819 determine whether or not to do disassembly from target memory or from the
822 If we're debugging a local process, read target memory, instead of the
823 exec file. This makes disassembly of functions in shared libs work
826 Else, we're debugging a remote process, and should disassemble from the
827 exec file for speed. However, this is no good if the target modifies it's
828 code (for relocation, or whatever).
831 if (disassemble_from_exec == -1)
832 if (strcmp (target_shortname, "child") == 0
833 || strcmp (target_shortname, "procfs") == 0)
834 disassemble_from_exec = 0; /* It's a child process, read inferior mem */
836 disassemble_from_exec = 1; /* It's remote, read the exec file */
838 if (disassemble_from_exec)
839 dis_asm_read_memory_hook = gdbtk_dis_asm_read_memory;
841 /* If just doing straight assembly, all we need to do is disassemble
842 everything between low and high. If doing mixed source/assembly, we've
843 got a totally different path to follow. */
845 if (mixed_source_and_assembly)
846 { /* Come here for mixed source/assembly */
847 /* The idea here is to present a source-O-centric view of a function to
848 the user. This means that things are presented in source order, with
849 (possibly) out of order assembly immediately following. */
850 struct symtab *symtab;
851 struct linetable_entry *le;
854 struct my_line_entry *mle;
855 struct symtab_and_line sal;
860 symtab = find_pc_symtab (low); /* Assume symtab is valid for whole PC range */
865 /* First, convert the linetable to a bunch of my_line_entry's. */
867 le = symtab->linetable->item;
868 nlines = symtab->linetable->nitems;
873 mle = (struct my_line_entry *) alloca (nlines * sizeof (struct my_line_entry));
877 /* Copy linetable entries for this function into our data structure, creating
878 end_pc's and setting out_of_order as appropriate. */
880 /* First, skip all the preceding functions. */
882 for (i = 0; i < nlines - 1 && le[i].pc < low; i++) ;
884 /* Now, copy all entries before the end of this function. */
887 for (; i < nlines - 1 && le[i].pc < high; i++)
889 if (le[i].line == le[i + 1].line
890 && le[i].pc == le[i + 1].pc)
891 continue; /* Ignore duplicates */
893 mle[newlines].line = le[i].line;
894 if (le[i].line > le[i + 1].line)
896 mle[newlines].start_pc = le[i].pc;
897 mle[newlines].end_pc = le[i + 1].pc;
901 /* If we're on the last line, and it's part of the function, then we need to
902 get the end pc in a special way. */
907 mle[newlines].line = le[i].line;
908 mle[newlines].start_pc = le[i].pc;
909 sal = find_pc_line (le[i].pc, 0);
910 mle[newlines].end_pc = sal.end;
914 /* Now, sort mle by line #s (and, then by addresses within lines). */
917 qsort (mle, newlines, sizeof (struct my_line_entry), compare_lines);
919 /* Now, for each line entry, emit the specified lines (unless they have been
920 emitted before), followed by the assembly code for that line. */
922 next_line = 0; /* Force out first line */
923 for (i = 0; i < newlines; i++)
925 /* Print out everything from next_line to the current line. */
927 if (mle[i].line >= next_line)
930 print_source_lines (symtab, next_line, mle[i].line + 1, 0);
932 print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
934 next_line = mle[i].line + 1;
937 for (pc = mle[i].start_pc; pc < mle[i].end_pc; )
940 fputs_unfiltered (" ", gdb_stdout);
941 print_address (pc, gdb_stdout);
942 fputs_unfiltered (":\t ", gdb_stdout);
943 pc += print_insn (pc, gdb_stdout);
944 fputs_unfiltered ("\n", gdb_stdout);
951 for (pc = low; pc < high; )
954 fputs_unfiltered (" ", gdb_stdout);
955 print_address (pc, gdb_stdout);
956 fputs_unfiltered (":\t ", gdb_stdout);
957 pc += print_insn (pc, gdb_stdout);
958 fputs_unfiltered ("\n", gdb_stdout);
962 dis_asm_read_memory_hook = 0;
964 gdb_flush (gdb_stdout);
970 tk_command (cmd, from_tty)
976 struct cleanup *old_chain;
978 retval = Tcl_Eval (interp, cmd);
980 result = strdup (interp->result);
982 old_chain = make_cleanup (free, result);
984 if (retval != TCL_OK)
987 printf_unfiltered ("%s\n", result);
989 do_cleanups (old_chain);
993 cleanup_init (ignored)
996 if (mainWindow != NULL)
997 Tk_DestroyWindow (mainWindow);
1001 Tcl_DeleteInterp (interp);
1005 /* Come here during long calculations to check for GUI events. Usually invoked
1006 via the QUIT macro. */
1009 gdbtk_interactive ()
1011 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
1014 /* Come here when there is activity on the X file descriptor. */
1020 /* Process pending events */
1022 while (Tk_DoOneEvent (TK_DONT_WAIT|TK_ALL_EVENTS) != 0);
1026 gdbtk_wait (pid, ourstatus)
1028 struct target_waitstatus *ourstatus;
1030 struct sigaction action;
1031 static sigset_t nullsigmask = {0};
1034 /* Needed for SunOS 4.1.x */
1035 #define SA_RESTART 0
1038 action.sa_handler = x_event;
1039 action.sa_mask = nullsigmask;
1040 action.sa_flags = SA_RESTART;
1041 sigaction(SIGIO, &action, NULL);
1043 pid = target_wait (pid, ourstatus);
1045 action.sa_handler = SIG_IGN;
1046 sigaction(SIGIO, &action, NULL);
1051 /* This is called from execute_command, and provides a wrapper around
1052 various command routines in a place where both protocol messages and
1053 user input both flow through. Mostly this is used for indicating whether
1054 the target process is running or not.
1058 gdbtk_call_command (cmdblk, arg, from_tty)
1059 struct cmd_list_element *cmdblk;
1063 if (cmdblk->class == class_run)
1065 Tcl_VarEval (interp, "gdbtk_tcl_busy", NULL);
1066 (*cmdblk->function.cfunc)(arg, from_tty);
1067 Tcl_VarEval (interp, "gdbtk_tcl_idle", NULL);
1070 (*cmdblk->function.cfunc)(arg, from_tty);
1076 struct cleanup *old_chain;
1077 char *gdbtk_filename;
1079 struct sigaction action;
1080 static sigset_t nullsigmask = {0};
1081 extern struct cmd_list_element *setlist;
1082 extern struct cmd_list_element *showlist;
1084 old_chain = make_cleanup (cleanup_init, 0);
1086 /* First init tcl and tk. */
1088 interp = Tcl_CreateInterp ();
1091 error ("Tcl_CreateInterp failed");
1093 Tcl_DStringInit (&stdout_buffer); /* Setup stdout buffer */
1095 mainWindow = Tk_CreateMainWindow (interp, NULL, "gdb", "Gdb");
1098 return; /* DISPLAY probably not set */
1100 if (Tcl_Init(interp) != TCL_OK)
1101 error ("Tcl_Init failed: %s", interp->result);
1103 if (Tk_Init(interp) != TCL_OK)
1104 error ("Tk_Init failed: %s", interp->result);
1106 Tcl_CreateCommand (interp, "gdb_cmd", call_wrapper, gdb_cmd, NULL);
1107 Tcl_CreateCommand (interp, "gdb_loc", call_wrapper, gdb_loc, NULL);
1108 Tcl_CreateCommand (interp, "gdb_sourcelines", call_wrapper, gdb_sourcelines,
1110 Tcl_CreateCommand (interp, "gdb_listfiles", call_wrapper, gdb_listfiles,
1112 Tcl_CreateCommand (interp, "gdb_stop", call_wrapper, gdb_stop, NULL);
1113 Tcl_CreateCommand (interp, "gdb_regnames", call_wrapper, gdb_regnames, NULL);
1114 Tcl_CreateCommand (interp, "gdb_fetch_registers", call_wrapper,
1115 gdb_fetch_registers, NULL);
1116 Tcl_CreateCommand (interp, "gdb_changed_register_list", call_wrapper,
1117 gdb_changed_register_list, NULL);
1118 Tcl_CreateCommand (interp, "gdb_disassemble", call_wrapper,
1119 gdb_disassemble, NULL);
1120 Tcl_CreateCommand (interp, "gdb_eval", call_wrapper, gdb_eval, NULL);
1122 command_loop_hook = Tk_MainLoop;
1123 print_frame_info_listing_hook = null_routine;
1124 query_hook = gdbtk_query;
1125 flush_hook = gdbtk_flush;
1126 create_breakpoint_hook = gdbtk_create_breakpoint;
1127 delete_breakpoint_hook = gdbtk_delete_breakpoint;
1128 enable_breakpoint_hook = gdbtk_enable_breakpoint;
1129 disable_breakpoint_hook = gdbtk_disable_breakpoint;
1130 interactive_hook = gdbtk_interactive;
1131 target_wait_hook = gdbtk_wait;
1132 call_command_hook = gdbtk_call_command;
1134 /* Get the file descriptor for the X server */
1136 x_fd = ConnectionNumber (Tk_Display (mainWindow));
1138 /* Setup for I/O interrupts */
1140 action.sa_mask = nullsigmask;
1141 action.sa_flags = 0;
1142 action.sa_handler = SIG_IGN;
1143 sigaction(SIGIO, &action, NULL);
1147 if (ioctl (x_fd, FIOASYNC, &i))
1148 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1151 if (ioctl (x_fd, SIOCSPGRP, &i))
1152 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1154 if (ioctl (x_fd, I_SETSIG, S_INPUT|S_RDNORM) < 0)
1155 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1156 #endif /* ifndef FIOASYNC */
1158 add_com ("tk", class_obscure, tk_command,
1159 "Send a command directly into tk.");
1162 add_show_from_set (add_set_cmd ("disassemble-from-exec", class_support,
1163 var_boolean, (char *)&disassemble_from_exec,
1168 Tcl_LinkVar (interp, "disassemble-from-exec", (char *)&disassemble_from_exec,
1171 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1173 gdbtk_filename = getenv ("GDBTK_FILENAME");
1174 if (!gdbtk_filename)
1175 if (access ("gdbtk.tcl", R_OK) == 0)
1176 gdbtk_filename = "gdbtk.tcl";
1178 gdbtk_filename = GDBTK_FILENAME;
1180 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1181 prior to this point go to stdout/stderr. */
1183 fputs_unfiltered_hook = gdbtk_fputs;
1185 if (Tcl_EvalFile (interp, gdbtk_filename) != TCL_OK)
1189 fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
1191 fprintf_unfiltered (stderr, "%s:%d: %s\n", gdbtk_filename,
1192 interp->errorLine, interp->result);
1194 fputs_unfiltered ("Stack trace:\n", gdb_stderr);
1195 fputs_unfiltered (Tcl_GetVar (interp, "errorInfo", 0), gdb_stderr);
1199 discard_cleanups (old_chain);
1202 /* Come here during initialze_all_files () */
1205 _initialize_gdbtk ()
1209 /* Tell the rest of the world that Gdbtk is now set up. */
1211 init_ui_hook = gdbtk_init;