1 /* TK interface routines.
2 Copyright 1994 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
36 #include <sys/ioctl.h>
41 #include <sys/stropts.h>
44 /* Non-zero means that we're doing the gdbtk interface. */
47 /* Non-zero means we are reloading breakpoints, etc from the
48 Gdbtk kernel, and we should suppress various messages */
49 static int gdbtk_reloading
= 0;
51 /* Handle for TCL interpreter */
52 static Tcl_Interp
*interp
= NULL
;
54 /* Handle for TK main window */
55 static Tk_Window mainWindow
= NULL
;
57 static int x_fd
; /* X network socket */
59 /* This variable determines where memory used for disassembly is read from.
61 If > 0, then disassembly comes from the exec file rather than the target
62 (which might be at the other end of a slow serial link). If == 0 then
63 disassembly comes from target. If < 0 disassembly is automatically switched
64 to the target if it's an inferior process, otherwise the exec file is
68 static int disassemble_from_exec
= -1;
76 /* The following routines deal with stdout/stderr data, which is created by
77 {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
78 lowest level of these routines and capture all output from the rest of GDB.
79 Normally they present their data to tcl via callbacks to the following tcl
80 routines: gdbtk_tcl_fputs, gdbtk_tcl_fputs_error, and gdbtk_flush. These
81 in turn call tk routines to update the display.
83 Under some circumstances, you may want to collect the output so that it can
84 be returned as the value of a tcl procedure. This can be done by
85 surrounding the output routines with calls to start_saving_output and
86 finish_saving_output. The saved data can then be retrieved with
87 get_saved_output (but this must be done before the call to
88 finish_saving_output). */
90 /* Dynamic string header for stdout. */
92 static Tcl_DString stdout_buffer
;
94 /* Use this to collect stdout output that will be returned as the result of a
97 static int saving_output
= 0;
100 start_saving_output ()
105 #define get_saved_output() (Tcl_DStringValue (&stdout_buffer))
108 finish_saving_output ()
115 Tcl_DStringFree (&stdout_buffer
);
118 /* This routine redirects the output of fputs_unfiltered so that
119 the user can see what's going on in his debugger window. */
126 /* We use Tcl_Merge to quote braces and funny characters as necessary. */
128 argv
[0] = Tcl_DStringValue (&stdout_buffer
);
129 s
= Tcl_Merge (1, argv
);
131 Tcl_DStringFree (&stdout_buffer
);
133 Tcl_VarEval (interp
, "gdbtk_tcl_fputs ", s
, NULL
);
142 if (stream
!= gdb_stdout
|| saving_output
)
145 /* Flush output from C to tcl land. */
149 /* Force immediate screen update */
151 Tcl_VarEval (interp
, "gdbtk_tcl_flush", NULL
);
155 gdbtk_fputs (ptr
, stream
)
161 if (stream
!= gdb_stdout
)
163 Tcl_VarEval (interp
, "gdbtk_tcl_fputs_error ", "{", ptr
, "}", NULL
);
167 Tcl_DStringAppend (&stdout_buffer
, ptr
, -1);
172 if (Tcl_DStringLength (&stdout_buffer
) > 1000)
184 query
= va_arg (args
, char *);
186 vsprintf(buf
, query
, args
);
187 Tcl_VarEval (interp
, "gdbtk_tcl_query ", "{", buf
, "}", NULL
);
189 val
= atol (interp
->result
);
194 breakpoint_notify(b
, action
)
195 struct breakpoint
*b
;
199 char bpnum
[50], line
[50], pc
[50];
200 struct symtab_and_line sal
;
204 if (b
->type
!= bp_breakpoint
)
207 sal
= find_pc_line (b
->address
, 0);
209 filename
= symtab_to_filename (sal
.symtab
);
211 sprintf (bpnum
, "%d", b
->number
);
212 sprintf (line
, "%d", sal
.line
);
213 sprintf (pc
, "0x%lx", b
->address
);
215 v
= Tcl_VarEval (interp
,
216 "gdbtk_tcl_breakpoint ",
219 " ", filename
? filename
: "{}",
226 gdbtk_fputs (interp
->result
, gdb_stdout
);
227 gdbtk_fputs ("\n", gdb_stdout
);
232 gdbtk_create_breakpoint(b
)
233 struct breakpoint
*b
;
235 breakpoint_notify(b
, "create");
239 gdbtk_delete_breakpoint(b
)
240 struct breakpoint
*b
;
242 breakpoint_notify(b
, "delete");
246 gdbtk_enable_breakpoint(b
)
247 struct breakpoint
*b
;
249 breakpoint_notify(b
, "enable");
253 gdbtk_disable_breakpoint(b
)
254 struct breakpoint
*b
;
256 breakpoint_notify(b
, "disable");
259 /* This implements the TCL command `gdb_loc', which returns a list consisting
260 of the source and line number associated with the current pc. */
263 gdb_loc (clientData
, interp
, argc
, argv
)
264 ClientData clientData
;
271 struct symtab_and_line sal
;
277 pc
= selected_frame
? selected_frame
->pc
: stop_pc
;
278 sal
= find_pc_line (pc
, 0);
282 struct symtabs_and_lines sals
;
285 sals
= decode_line_spec (argv
[1], 1);
293 Tcl_SetResult (interp
, "Ambiguous line spec", TCL_STATIC
);
301 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
306 Tcl_AppendElement (interp
, sal
.symtab
->filename
);
308 Tcl_AppendElement (interp
, "");
310 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
311 Tcl_AppendElement (interp
, funcname
);
313 filename
= symtab_to_filename (sal
.symtab
);
314 Tcl_AppendElement (interp
, filename
);
316 sprintf (buf
, "%d", sal
.line
);
317 Tcl_AppendElement (interp
, buf
); /* line number */
319 sprintf (buf
, "0x%lx", pc
);
320 Tcl_AppendElement (interp
, buf
); /* PC */
325 /* This implements the TCL command `gdb_eval'. */
328 gdb_eval (clientData
, interp
, argc
, argv
)
329 ClientData clientData
;
334 struct expression
*expr
;
335 struct cleanup
*old_chain
;
340 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
344 expr
= parse_expression (argv
[1]);
346 old_chain
= make_cleanup (free_current_contents
, &expr
);
348 val
= evaluate_expression (expr
);
350 start_saving_output (); /* Start collecting stdout */
352 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
353 gdb_stdout
, 0, 0, 0, 0);
355 value_print (val
, gdb_stdout
, 0, 0);
358 Tcl_AppendElement (interp
, get_saved_output ());
360 finish_saving_output (); /* Set stdout back to normal */
362 do_cleanups (old_chain
);
367 /* This implements the TCL command `gdb_sourcelines', which returns a list of
368 all of the lines containing executable code for the specified source file
369 (ie: lines where you can put breakpoints). */
372 gdb_sourcelines (clientData
, interp
, argc
, argv
)
373 ClientData clientData
;
378 struct symtab
*symtab
;
379 struct linetable_entry
*le
;
385 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
389 symtab
= lookup_symtab (argv
[1]);
393 Tcl_SetResult (interp
, "No such file", TCL_STATIC
);
397 /* If there's no linetable, or no entries, then we are done. */
399 if (!symtab
->linetable
400 || symtab
->linetable
->nitems
== 0)
402 Tcl_AppendElement (interp
, "");
406 le
= symtab
->linetable
->item
;
407 nlines
= symtab
->linetable
->nitems
;
409 for (;nlines
> 0; nlines
--, le
++)
411 /* If the pc of this line is the same as the pc of the next line, then
414 && le
->pc
== (le
+ 1)->pc
)
417 sprintf (buf
, "%d", le
->line
);
418 Tcl_AppendElement (interp
, buf
);
425 map_arg_registers (argc
, argv
, func
, argp
)
428 int (*func
) PARAMS ((int regnum
, void *argp
));
433 /* Note that the test for a valid register must include checking the
434 reg_names array because NUM_REGS may be allocated for the union of the
435 register sets within a family of related processors. In this case, the
436 trailing entries of reg_names will change depending upon the particular
437 processor being debugged. */
439 if (argc
== 0) /* No args, just do all the regs */
443 && reg_names
[regnum
] != NULL
444 && *reg_names
[regnum
] != '\000';
451 /* Else, list of register #s, just do listed regs */
452 for (; argc
> 0; argc
--, argv
++)
454 regnum
= atoi (*argv
);
458 && reg_names
[regnum
] != NULL
459 && *reg_names
[regnum
] != '\000')
463 Tcl_SetResult (interp
, "bad register number", TCL_STATIC
);
473 get_register_name (regnum
, argp
)
475 void *argp
; /* Ignored */
477 Tcl_AppendElement (interp
, reg_names
[regnum
]);
480 /* This implements the TCL command `gdb_regnames', which returns a list of
481 all of the register names. */
484 gdb_regnames (clientData
, interp
, argc
, argv
)
485 ClientData clientData
;
493 return map_arg_registers (argc
, argv
, get_register_name
, 0);
496 #ifndef REGISTER_CONVERTIBLE
497 #define REGISTER_CONVERTIBLE(x) (0 != 0)
500 #ifndef REGISTER_CONVERT_TO_VIRTUAL
501 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
504 #ifndef INVALID_FLOAT
505 #define INVALID_FLOAT(x, y) (0 != 0)
509 get_register (regnum
, fp
)
512 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
513 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
514 int format
= (int)fp
;
516 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
518 Tcl_AppendElement (interp
, "Optimized out");
522 start_saving_output (); /* Start collecting stdout */
524 /* Convert raw data to virtual format if necessary. */
526 if (REGISTER_CONVERTIBLE (regnum
))
528 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
529 raw_buffer
, virtual_buffer
);
532 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
534 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
535 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
537 Tcl_AppendElement (interp
, get_saved_output ());
539 finish_saving_output (); /* Set stdout back to normal */
543 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
544 ClientData clientData
;
553 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
563 return map_arg_registers (argc
, argv
, get_register
, format
);
566 /* This contains the previous values of the registers, since the last call to
567 gdb_changed_register_list. */
569 static char old_regs
[REGISTER_BYTES
];
572 register_changed_p (regnum
, argp
)
573 void *argp
; /* Ignored */
575 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
578 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
581 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
582 REGISTER_RAW_SIZE (regnum
)) == 0)
585 /* Found a changed register. Save new value and return it's number. */
587 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
588 REGISTER_RAW_SIZE (regnum
));
590 sprintf (buf
, "%d", regnum
);
591 Tcl_AppendElement (interp
, buf
);
595 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
596 ClientData clientData
;
606 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
609 /* This implements the TCL command `gdb_cmd', which sends it's argument into
610 the GDB command scanner. */
613 gdb_cmd (clientData
, interp
, argc
, argv
)
614 ClientData clientData
;
621 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
625 execute_command (argv
[1], 1);
627 bpstat_do_actions (&stop_bpstat
);
629 /* Drain all buffered command output */
631 gdb_flush (gdb_stdout
);
636 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
637 handles cleanups, and calls to return_to_top_level (usually via error).
638 This is necessary in order to prevent a longjmp out of the bowels of Tk,
639 possibly leaving things in a bad state. Since this routine can be called
640 recursively, it needs to save and restore the contents of the jmp_buf as
644 call_wrapper (clientData
, interp
, argc
, argv
)
645 ClientData clientData
;
651 struct cleanup
*saved_cleanup_chain
;
653 jmp_buf saved_error_return
;
655 func
= (Tcl_CmdProc
*)clientData
;
656 memcpy (saved_error_return
, error_return
, sizeof (jmp_buf));
658 saved_cleanup_chain
= save_cleanups ();
660 if (!setjmp (error_return
))
661 val
= func (clientData
, interp
, argc
, argv
);
664 val
= TCL_ERROR
; /* Flag an error for TCL */
666 finish_saving_output (); /* Restore stdout to normal */
668 dis_asm_read_memory_hook
= 0; /* Restore disassembly hook */
670 gdb_flush (gdb_stderr
); /* Flush error output */
672 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
674 /* In case of an error, we may need to force the GUI into idle mode because
675 gdbtk_call_command may have bombed out while in the command routine. */
677 Tcl_VarEval (interp
, "gdbtk_tcl_idle", NULL
);
680 do_cleanups (ALL_CLEANUPS
);
682 restore_cleanups (saved_cleanup_chain
);
684 memcpy (error_return
, saved_error_return
, sizeof (jmp_buf));
690 gdb_listfiles (clientData
, interp
, argc
, argv
)
691 ClientData clientData
;
697 struct objfile
*objfile
;
698 struct partial_symtab
*psymtab
;
699 struct symtab
*symtab
;
701 ALL_PSYMTABS (objfile
, psymtab
)
702 Tcl_AppendElement (interp
, psymtab
->filename
);
704 ALL_SYMTABS (objfile
, symtab
)
705 Tcl_AppendElement (interp
, symtab
->filename
);
711 gdb_stop (clientData
, interp
, argc
, argv
)
712 ClientData clientData
;
722 /* This implements the TCL command `gdb_disassemble'. */
725 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
729 disassemble_info
*info
;
731 extern struct target_ops exec_ops
;
735 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
746 /* We need a different sort of line table from the normal one cuz we can't
747 depend upon implicit line-end pc's for lines. This is because of the
748 reordering we are about to do. */
750 struct my_line_entry
{
757 compare_lines (mle1p
, mle2p
)
761 struct my_line_entry
*mle1
, *mle2
;
764 mle1
= (struct my_line_entry
*) mle1p
;
765 mle2
= (struct my_line_entry
*) mle2p
;
767 val
= mle1
->line
- mle2
->line
;
772 return mle1
->start_pc
- mle2
->start_pc
;
776 gdb_disassemble (clientData
, interp
, argc
, argv
)
777 ClientData clientData
;
782 CORE_ADDR pc
, low
, high
;
783 int mixed_source_and_assembly
;
785 if (argc
!= 3 && argc
!= 4)
787 Tcl_SetResult (interp
, "wrong # args", TCL_STATIC
);
791 if (strcmp (argv
[1], "source") == 0)
792 mixed_source_and_assembly
= 1;
793 else if (strcmp (argv
[1], "nosource") == 0)
794 mixed_source_and_assembly
= 0;
797 Tcl_SetResult (interp
, "First arg must be 'source' or 'nosource'",
802 low
= parse_and_eval_address (argv
[2]);
806 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
808 Tcl_SetResult (interp
, "No function contains specified address",
814 high
= parse_and_eval_address (argv
[3]);
816 /* If disassemble_from_exec == -1, then we use the following heuristic to
817 determine whether or not to do disassembly from target memory or from the
820 If we're debugging a local process, read target memory, instead of the
821 exec file. This makes disassembly of functions in shared libs work
824 Else, we're debugging a remote process, and should disassemble from the
825 exec file for speed. However, this is no good if the target modifies it's
826 code (for relocation, or whatever).
829 if (disassemble_from_exec
== -1)
830 if (strcmp (target_shortname
, "child") == 0
831 || strcmp (target_shortname
, "procfs") == 0)
832 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
834 disassemble_from_exec
= 1; /* It's remote, read the exec file */
836 if (disassemble_from_exec
)
837 dis_asm_read_memory_hook
= gdbtk_dis_asm_read_memory
;
839 /* If just doing straight assembly, all we need to do is disassemble
840 everything between low and high. If doing mixed source/assembly, we've
841 got a totally different path to follow. */
843 if (mixed_source_and_assembly
)
844 { /* Come here for mixed source/assembly */
845 /* The idea here is to present a source-O-centric view of a function to
846 the user. This means that things are presented in source order, with
847 (possibly) out of order assembly immediately following. */
848 struct symtab
*symtab
;
849 struct linetable_entry
*le
;
851 struct my_line_entry
*mle
;
852 struct symtab_and_line sal
;
857 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
862 /* First, convert the linetable to a bunch of my_line_entry's. */
864 le
= symtab
->linetable
->item
;
865 nlines
= symtab
->linetable
->nitems
;
870 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
874 for (i
= 0; i
< nlines
- 1; i
++)
876 mle
[i
].line
= le
[i
].line
;
877 if (le
[i
].line
> le
[i
+ 1].line
)
879 mle
[i
].start_pc
= le
[i
].pc
;
880 mle
[i
].end_pc
= le
[i
+ 1].pc
;
883 mle
[i
].line
= le
[i
].line
;
884 mle
[i
].start_pc
= le
[i
].pc
;
885 sal
= find_pc_line (le
[i
].pc
, 0);
886 mle
[i
].end_pc
= sal
.end
;
888 /* Now, sort mle by line #s (and, then by addresses within lines). */
891 qsort (mle
, nlines
, sizeof (struct my_line_entry
), compare_lines
);
893 /* Scan forward until we find the start of the function. */
895 for (i
= 0; i
< nlines
; i
++)
896 if (mle
[i
].start_pc
>= low
)
899 /* Now, for each line entry, emit the specified lines (unless they have been
900 emitted before), followed by the assembly code for that line. */
902 current_line
= 0; /* Force out first line */
903 for (;i
< nlines
&& mle
[i
].start_pc
< high
; i
++)
905 if (mle
[i
].line
> current_line
)
908 print_source_lines (symtab
, mle
[i
].line
, INT_MAX
, 0);
910 print_source_lines (symtab
, mle
[i
].line
, mle
[i
+ 1].line
, 0);
911 current_line
= mle
[i
].line
;
913 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
916 fputs_unfiltered (" ", gdb_stdout
);
917 print_address (pc
, gdb_stdout
);
918 fputs_unfiltered (":\t ", gdb_stdout
);
919 pc
+= print_insn (pc
, gdb_stdout
);
920 fputs_unfiltered ("\n", gdb_stdout
);
927 for (pc
= low
; pc
< high
; )
930 fputs_unfiltered (" ", gdb_stdout
);
931 print_address (pc
, gdb_stdout
);
932 fputs_unfiltered (":\t ", gdb_stdout
);
933 pc
+= print_insn (pc
, gdb_stdout
);
934 fputs_unfiltered ("\n", gdb_stdout
);
938 dis_asm_read_memory_hook
= 0;
940 gdb_flush (gdb_stdout
);
946 tk_command (cmd
, from_tty
)
952 struct cleanup
*old_chain
;
954 retval
= Tcl_Eval (interp
, cmd
);
956 result
= strdup (interp
->result
);
958 old_chain
= make_cleanup (free
, result
);
960 if (retval
!= TCL_OK
)
963 printf_unfiltered ("%s\n", result
);
965 do_cleanups (old_chain
);
969 cleanup_init (ignored
)
972 if (mainWindow
!= NULL
)
973 Tk_DestroyWindow (mainWindow
);
977 Tcl_DeleteInterp (interp
);
981 /* Come here during long calculations to check for GUI events. Usually invoked
982 via the QUIT macro. */
987 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
990 /* Come here when there is activity on the X file descriptor. */
996 /* Process pending events */
998 while (Tk_DoOneEvent (TK_DONT_WAIT
|TK_ALL_EVENTS
) != 0);
1002 gdbtk_wait (pid
, ourstatus
)
1004 struct target_waitstatus
*ourstatus
;
1006 struct sigaction action
;
1007 static sigset_t nullsigmask
= {0};
1010 /* Needed for SunOS 4.1.x */
1011 #define SA_RESTART 0
1014 action
.sa_handler
= x_event
;
1015 action
.sa_mask
= nullsigmask
;
1016 action
.sa_flags
= SA_RESTART
;
1017 sigaction(SIGIO
, &action
, NULL
);
1019 pid
= target_wait (pid
, ourstatus
);
1021 action
.sa_handler
= SIG_IGN
;
1022 sigaction(SIGIO
, &action
, NULL
);
1027 /* This is called from execute_command, and provides a wrapper around
1028 various command routines in a place where both protocol messages and
1029 user input both flow through. Mostly this is used for indicating whether
1030 the target process is running or not.
1034 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1035 struct cmd_list_element
*cmdblk
;
1039 if (cmdblk
->class == class_run
)
1041 Tcl_VarEval (interp
, "gdbtk_tcl_busy", NULL
);
1042 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1043 Tcl_VarEval (interp
, "gdbtk_tcl_idle", NULL
);
1046 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1052 struct cleanup
*old_chain
;
1053 char *gdbtk_filename
;
1055 struct sigaction action
;
1056 static sigset_t nullsigmask
= {0};
1057 extern struct cmd_list_element
*setlist
;
1058 extern struct cmd_list_element
*showlist
;
1060 old_chain
= make_cleanup (cleanup_init
, 0);
1062 /* First init tcl and tk. */
1064 interp
= Tcl_CreateInterp ();
1067 error ("Tcl_CreateInterp failed");
1069 Tcl_DStringInit (&stdout_buffer
); /* Setup stdout buffer */
1071 mainWindow
= Tk_CreateMainWindow (interp
, NULL
, "gdb", "Gdb");
1074 return; /* DISPLAY probably not set */
1076 if (Tcl_Init(interp
) != TCL_OK
)
1077 error ("Tcl_Init failed: %s", interp
->result
);
1079 if (Tk_Init(interp
) != TCL_OK
)
1080 error ("Tk_Init failed: %s", interp
->result
);
1082 Tcl_CreateCommand (interp
, "gdb_cmd", call_wrapper
, gdb_cmd
, NULL
);
1083 Tcl_CreateCommand (interp
, "gdb_loc", call_wrapper
, gdb_loc
, NULL
);
1084 Tcl_CreateCommand (interp
, "gdb_sourcelines", call_wrapper
, gdb_sourcelines
,
1086 Tcl_CreateCommand (interp
, "gdb_listfiles", call_wrapper
, gdb_listfiles
,
1088 Tcl_CreateCommand (interp
, "gdb_stop", call_wrapper
, gdb_stop
, NULL
);
1089 Tcl_CreateCommand (interp
, "gdb_regnames", call_wrapper
, gdb_regnames
, NULL
);
1090 Tcl_CreateCommand (interp
, "gdb_fetch_registers", call_wrapper
,
1091 gdb_fetch_registers
, NULL
);
1092 Tcl_CreateCommand (interp
, "gdb_changed_register_list", call_wrapper
,
1093 gdb_changed_register_list
, NULL
);
1094 Tcl_CreateCommand (interp
, "gdb_disassemble", call_wrapper
,
1095 gdb_disassemble
, NULL
);
1096 Tcl_CreateCommand (interp
, "gdb_eval", call_wrapper
, gdb_eval
, NULL
);
1098 command_loop_hook
= Tk_MainLoop
;
1099 fputs_unfiltered_hook
= gdbtk_fputs
;
1100 print_frame_info_listing_hook
= null_routine
;
1101 query_hook
= gdbtk_query
;
1102 flush_hook
= gdbtk_flush
;
1103 create_breakpoint_hook
= gdbtk_create_breakpoint
;
1104 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
1105 enable_breakpoint_hook
= gdbtk_enable_breakpoint
;
1106 disable_breakpoint_hook
= gdbtk_disable_breakpoint
;
1107 interactive_hook
= gdbtk_interactive
;
1108 target_wait_hook
= gdbtk_wait
;
1109 call_command_hook
= gdbtk_call_command
;
1111 /* Get the file descriptor for the X server */
1113 x_fd
= ConnectionNumber (Tk_Display (mainWindow
));
1115 /* Setup for I/O interrupts */
1117 action
.sa_mask
= nullsigmask
;
1118 action
.sa_flags
= 0;
1119 action
.sa_handler
= SIG_IGN
;
1120 sigaction(SIGIO
, &action
, NULL
);
1124 if (ioctl (x_fd
, FIOASYNC
, &i
))
1125 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1128 if (ioctl (x_fd
, SIOCSPGRP
, &i
))
1129 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1131 if (ioctl (x_fd
, I_SETSIG
, S_INPUT
|S_RDNORM
) < 0)
1132 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1133 #endif /* ifndef FIOASYNC */
1135 add_com ("tk", class_obscure
, tk_command
,
1136 "Send a command directly into tk.");
1139 add_show_from_set (add_set_cmd ("disassemble-from-exec", class_support
,
1140 var_boolean
, (char *)&disassemble_from_exec
,
1145 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
1148 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1150 gdbtk_filename
= getenv ("GDBTK_FILENAME");
1151 if (!gdbtk_filename
)
1152 if (access ("gdbtk.tcl", R_OK
) == 0)
1153 gdbtk_filename
= "gdbtk.tcl";
1155 gdbtk_filename
= GDBTK_FILENAME
;
1157 if (Tcl_EvalFile (interp
, gdbtk_filename
) != TCL_OK
)
1158 error ("Failure reading %s: %s", gdbtk_filename
, interp
->result
);
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
;