1 /* Tcl/Tk interface routines.
2 Copyright 1994, 1995 Free Software Foundation, Inc.
4 Written by Stu Grossman <grossman@cygnus.com> of Cygnus Support.
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
)
209 error ("Breakpoint #%d does not exist", bpnum
);
211 if (b
->type
!= bp_breakpoint
)
214 sal
= find_pc_line (b
->address
, 0);
216 Tcl_DStringAppendElement (result_ptr
, symtab_to_filename (sal
.symtab
));
217 dsprintf_append_element (result_ptr
, "%d", sal
.line
);
218 dsprintf_append_element (result_ptr
, "0x%lx", b
->address
);
219 Tcl_DStringAppendElement (result_ptr
, bptypes
[b
->type
]);
220 Tcl_DStringAppendElement (result_ptr
, b
->enable
== enabled
? "1" : "0");
221 Tcl_DStringAppendElement (result_ptr
, bpdisp
[b
->disposition
]);
222 dsprintf_append_element (result_ptr
, "%d", b
->silent
);
223 dsprintf_append_element (result_ptr
, "%d", b
->ignore_count
);
225 Tcl_DStringStartSublist (result_ptr
);
226 for (cmd
= b
->commands
; cmd
; cmd
= cmd
->next
)
227 Tcl_DStringAppendElement (result_ptr
, cmd
->line
);
228 Tcl_DStringEndSublist (result_ptr
);
230 Tcl_DStringAppendElement (result_ptr
, b
->cond_string
);
232 dsprintf_append_element (result_ptr
, "%d", b
->thread
);
233 dsprintf_append_element (result_ptr
, "%d", b
->hit_count
);
239 breakpoint_notify(b
, action
)
240 struct breakpoint
*b
;
246 if (b
->type
!= bp_breakpoint
)
249 sprintf (buf
, "gdbtk_tcl_breakpoint %s %d", action
, b
->number
);
251 v
= Tcl_Eval (interp
, buf
);
255 gdbtk_fputs (interp
->result
, gdb_stdout
);
256 gdbtk_fputs ("\n", gdb_stdout
);
261 gdbtk_create_breakpoint(b
)
262 struct breakpoint
*b
;
264 breakpoint_notify (b
, "create");
268 gdbtk_delete_breakpoint(b
)
269 struct breakpoint
*b
;
271 breakpoint_notify (b
, "delete");
275 gdbtk_modify_breakpoint(b
)
276 struct breakpoint
*b
;
278 breakpoint_notify (b
, "modify");
281 /* This implements the TCL command `gdb_loc', which returns a list consisting
282 of the source and line number associated with the current pc. */
285 gdb_loc (clientData
, interp
, argc
, argv
)
286 ClientData clientData
;
293 struct symtab_and_line sal
;
299 pc
= selected_frame
? selected_frame
->pc
: stop_pc
;
300 sal
= find_pc_line (pc
, 0);
304 struct symtabs_and_lines sals
;
307 sals
= decode_line_spec (argv
[1], 1);
314 error ("Ambiguous line spec");
319 error ("wrong # args");
322 Tcl_DStringAppendElement (result_ptr
, sal
.symtab
->filename
);
324 Tcl_DStringAppendElement (result_ptr
, "");
326 find_pc_partial_function (pc
, &funcname
, NULL
, NULL
);
327 Tcl_DStringAppendElement (result_ptr
, funcname
);
329 filename
= symtab_to_filename (sal
.symtab
);
330 Tcl_DStringAppendElement (result_ptr
, filename
);
332 sprintf (buf
, "%d", sal
.line
);
333 Tcl_DStringAppendElement (result_ptr
, buf
); /* line number */
335 sprintf (buf
, "0x%lx", pc
);
336 Tcl_DStringAppendElement (result_ptr
, buf
); /* PC */
341 /* This implements the TCL command `gdb_eval'. */
344 gdb_eval (clientData
, interp
, argc
, argv
)
345 ClientData clientData
;
350 struct expression
*expr
;
351 struct cleanup
*old_chain
;
355 error ("wrong # args");
357 expr
= parse_expression (argv
[1]);
359 old_chain
= make_cleanup (free_current_contents
, &expr
);
361 val
= evaluate_expression (expr
);
363 val_print (VALUE_TYPE (val
), VALUE_CONTENTS (val
), VALUE_ADDRESS (val
),
364 gdb_stdout
, 0, 0, 0, 0);
366 do_cleanups (old_chain
);
371 /* This implements the TCL command `gdb_sourcelines', which returns a list of
372 all of the lines containing executable code for the specified source file
373 (ie: lines where you can put breakpoints). */
376 gdb_sourcelines (clientData
, interp
, argc
, argv
)
377 ClientData clientData
;
382 struct symtab
*symtab
;
383 struct linetable_entry
*le
;
388 error ("wrong # args");
390 symtab
= lookup_symtab (argv
[1]);
393 error ("No such file");
395 /* If there's no linetable, or no entries, then we are done. */
397 if (!symtab
->linetable
398 || symtab
->linetable
->nitems
== 0)
400 Tcl_DStringAppendElement (result_ptr
, "");
404 le
= symtab
->linetable
->item
;
405 nlines
= symtab
->linetable
->nitems
;
407 for (;nlines
> 0; nlines
--, le
++)
409 /* If the pc of this line is the same as the pc of the next line, then
412 && le
->pc
== (le
+ 1)->pc
)
415 sprintf (buf
, "%d", le
->line
);
416 Tcl_DStringAppendElement (result_ptr
, buf
);
423 map_arg_registers (argc
, argv
, func
, argp
)
426 void (*func
) PARAMS ((int regnum
, void *argp
));
431 /* Note that the test for a valid register must include checking the
432 reg_names array because NUM_REGS may be allocated for the union of the
433 register sets within a family of related processors. In this case, the
434 trailing entries of reg_names will change depending upon the particular
435 processor being debugged. */
437 if (argc
== 0) /* No args, just do all the regs */
441 && reg_names
[regnum
] != NULL
442 && *reg_names
[regnum
] != '\000';
449 /* Else, list of register #s, just do listed regs */
450 for (; argc
> 0; argc
--, argv
++)
452 regnum
= atoi (*argv
);
456 && reg_names
[regnum
] != NULL
457 && *reg_names
[regnum
] != '\000')
460 error ("bad register number");
467 get_register_name (regnum
, argp
)
469 void *argp
; /* Ignored */
471 Tcl_DStringAppendElement (result_ptr
, reg_names
[regnum
]);
474 /* This implements the TCL command `gdb_regnames', which returns a list of
475 all of the register names. */
478 gdb_regnames (clientData
, interp
, argc
, argv
)
479 ClientData clientData
;
487 return map_arg_registers (argc
, argv
, get_register_name
, 0);
490 #ifndef REGISTER_CONVERTIBLE
491 #define REGISTER_CONVERTIBLE(x) (0 != 0)
494 #ifndef REGISTER_CONVERT_TO_VIRTUAL
495 #define REGISTER_CONVERT_TO_VIRTUAL(x, y, z, a)
498 #ifndef INVALID_FLOAT
499 #define INVALID_FLOAT(x, y) (0 != 0)
503 get_register (regnum
, fp
)
507 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
508 char virtual_buffer
[MAX_REGISTER_VIRTUAL_SIZE
];
509 int format
= (int)fp
;
511 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
513 Tcl_DStringAppendElement (result_ptr
, "Optimized out");
517 /* Convert raw data to virtual format if necessary. */
519 if (REGISTER_CONVERTIBLE (regnum
))
521 REGISTER_CONVERT_TO_VIRTUAL (regnum
, REGISTER_VIRTUAL_TYPE (regnum
),
522 raw_buffer
, virtual_buffer
);
525 memcpy (virtual_buffer
, raw_buffer
, REGISTER_VIRTUAL_SIZE (regnum
));
527 val_print (REGISTER_VIRTUAL_TYPE (regnum
), virtual_buffer
, 0,
528 gdb_stdout
, format
, 1, 0, Val_pretty_default
);
530 Tcl_DStringAppend (result_ptr
, " ", -1);
534 gdb_fetch_registers (clientData
, interp
, argc
, argv
)
535 ClientData clientData
;
543 error ("wrong # args");
551 return map_arg_registers (argc
, argv
, get_register
, format
);
554 /* This contains the previous values of the registers, since the last call to
555 gdb_changed_register_list. */
557 static char old_regs
[REGISTER_BYTES
];
560 register_changed_p (regnum
, argp
)
562 void *argp
; /* Ignored */
564 char raw_buffer
[MAX_REGISTER_RAW_SIZE
];
567 if (read_relative_register_raw_bytes (regnum
, raw_buffer
))
570 if (memcmp (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
571 REGISTER_RAW_SIZE (regnum
)) == 0)
574 /* Found a changed register. Save new value and return it's number. */
576 memcpy (&old_regs
[REGISTER_BYTE (regnum
)], raw_buffer
,
577 REGISTER_RAW_SIZE (regnum
));
579 sprintf (buf
, "%d", regnum
);
580 Tcl_DStringAppendElement (result_ptr
, buf
);
584 gdb_changed_register_list (clientData
, interp
, argc
, argv
)
585 ClientData clientData
;
593 return map_arg_registers (argc
, argv
, register_changed_p
, NULL
);
596 /* This implements the TCL command `gdb_cmd', which sends it's argument into
597 the GDB command scanner. */
600 gdb_cmd (clientData
, interp
, argc
, argv
)
601 ClientData clientData
;
607 error ("wrong # args");
609 execute_command (argv
[1], 1);
611 bpstat_do_actions (&stop_bpstat
);
616 /* This routine acts as a top-level for all GDB code called by tcl/Tk. It
617 handles cleanups, and calls to return_to_top_level (usually via error).
618 This is necessary in order to prevent a longjmp out of the bowels of Tk,
619 possibly leaving things in a bad state. Since this routine can be called
620 recursively, it needs to save and restore the contents of the jmp_buf as
624 call_wrapper (clientData
, interp
, argc
, argv
)
625 ClientData clientData
;
631 struct cleanup
*saved_cleanup_chain
;
633 jmp_buf saved_error_return
;
634 Tcl_DString result
, *old_result_ptr
;
636 Tcl_DStringInit (&result
);
637 old_result_ptr
= result_ptr
;
638 result_ptr
= &result
;
640 func
= (Tcl_CmdProc
*)clientData
;
641 memcpy (saved_error_return
, error_return
, sizeof (jmp_buf));
643 saved_cleanup_chain
= save_cleanups ();
645 if (!setjmp (error_return
))
646 val
= func (clientData
, interp
, argc
, argv
);
649 val
= TCL_ERROR
; /* Flag an error for TCL */
651 gdb_flush (gdb_stderr
); /* Flush error output */
653 gdb_flush (gdb_stdout
); /* Sometimes error output comes here as well */
655 /* In case of an error, we may need to force the GUI into idle mode because
656 gdbtk_call_command may have bombed out while in the command routine. */
658 Tcl_VarEval (interp
, "gdbtk_tcl_idle", NULL
);
661 do_cleanups (ALL_CLEANUPS
);
663 restore_cleanups (saved_cleanup_chain
);
665 memcpy (error_return
, saved_error_return
, sizeof (jmp_buf));
667 Tcl_DStringResult (interp
, &result
);
668 result_ptr
= old_result_ptr
;
674 gdb_listfiles (clientData
, interp
, argc
, argv
)
675 ClientData clientData
;
680 struct objfile
*objfile
;
681 struct partial_symtab
*psymtab
;
682 struct symtab
*symtab
;
684 ALL_PSYMTABS (objfile
, psymtab
)
685 Tcl_DStringAppendElement (result_ptr
, psymtab
->filename
);
687 ALL_SYMTABS (objfile
, symtab
)
688 Tcl_DStringAppendElement (result_ptr
, symtab
->filename
);
694 gdb_stop (clientData
, interp
, argc
, argv
)
695 ClientData clientData
;
705 /* This implements the TCL command `gdb_disassemble'. */
708 gdbtk_dis_asm_read_memory (memaddr
, myaddr
, len
, info
)
712 disassemble_info
*info
;
714 extern struct target_ops exec_ops
;
718 res
= xfer_memory (memaddr
, myaddr
, len
, 0, &exec_ops
);
729 /* We need a different sort of line table from the normal one cuz we can't
730 depend upon implicit line-end pc's for lines. This is because of the
731 reordering we are about to do. */
733 struct my_line_entry
{
740 compare_lines (mle1p
, mle2p
)
744 struct my_line_entry
*mle1
, *mle2
;
747 mle1
= (struct my_line_entry
*) mle1p
;
748 mle2
= (struct my_line_entry
*) mle2p
;
750 val
= mle1
->line
- mle2
->line
;
755 return mle1
->start_pc
- mle2
->start_pc
;
759 gdb_disassemble (clientData
, interp
, argc
, argv
)
760 ClientData clientData
;
765 CORE_ADDR pc
, low
, high
;
766 int mixed_source_and_assembly
;
767 static disassemble_info di
= {
768 (fprintf_ftype
) fprintf_filtered
, /* fprintf_func */
769 gdb_stdout
, /* stream */
770 NULL
, /* application_data */
772 NULL
, /* private_data */
773 NULL
, /* read_memory_func */
774 dis_asm_memory_error
, /* memory_error_func */
775 dis_asm_print_address
/* print_address_func */
778 if (argc
!= 3 && argc
!= 4)
779 error ("wrong # args");
781 if (strcmp (argv
[1], "source") == 0)
782 mixed_source_and_assembly
= 1;
783 else if (strcmp (argv
[1], "nosource") == 0)
784 mixed_source_and_assembly
= 0;
786 error ("First arg must be 'source' or 'nosource'");
788 low
= parse_and_eval_address (argv
[2]);
792 if (find_pc_partial_function (low
, NULL
, &low
, &high
) == 0)
793 error ("No function contains specified address");
796 high
= parse_and_eval_address (argv
[3]);
798 /* If disassemble_from_exec == -1, then we use the following heuristic to
799 determine whether or not to do disassembly from target memory or from the
802 If we're debugging a local process, read target memory, instead of the
803 exec file. This makes disassembly of functions in shared libs work
806 Else, we're debugging a remote process, and should disassemble from the
807 exec file for speed. However, this is no good if the target modifies it's
808 code (for relocation, or whatever).
811 if (disassemble_from_exec
== -1)
812 if (strcmp (target_shortname
, "child") == 0
813 || strcmp (target_shortname
, "procfs") == 0)
814 disassemble_from_exec
= 0; /* It's a child process, read inferior mem */
816 disassemble_from_exec
= 1; /* It's remote, read the exec file */
818 if (disassemble_from_exec
)
819 di
.read_memory_func
= gdbtk_dis_asm_read_memory
;
821 di
.read_memory_func
= dis_asm_read_memory
;
823 /* If just doing straight assembly, all we need to do is disassemble
824 everything between low and high. If doing mixed source/assembly, we've
825 got a totally different path to follow. */
827 if (mixed_source_and_assembly
)
828 { /* Come here for mixed source/assembly */
829 /* The idea here is to present a source-O-centric view of a function to
830 the user. This means that things are presented in source order, with
831 (possibly) out of order assembly immediately following. */
832 struct symtab
*symtab
;
833 struct linetable_entry
*le
;
836 struct my_line_entry
*mle
;
837 struct symtab_and_line sal
;
842 symtab
= find_pc_symtab (low
); /* Assume symtab is valid for whole PC range */
847 /* First, convert the linetable to a bunch of my_line_entry's. */
849 le
= symtab
->linetable
->item
;
850 nlines
= symtab
->linetable
->nitems
;
855 mle
= (struct my_line_entry
*) alloca (nlines
* sizeof (struct my_line_entry
));
859 /* Copy linetable entries for this function into our data structure, creating
860 end_pc's and setting out_of_order as appropriate. */
862 /* First, skip all the preceding functions. */
864 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++) ;
866 /* Now, copy all entries before the end of this function. */
869 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
871 if (le
[i
].line
== le
[i
+ 1].line
872 && le
[i
].pc
== le
[i
+ 1].pc
)
873 continue; /* Ignore duplicates */
875 mle
[newlines
].line
= le
[i
].line
;
876 if (le
[i
].line
> le
[i
+ 1].line
)
878 mle
[newlines
].start_pc
= le
[i
].pc
;
879 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
883 /* If we're on the last line, and it's part of the function, then we need to
884 get the end pc in a special way. */
889 mle
[newlines
].line
= le
[i
].line
;
890 mle
[newlines
].start_pc
= le
[i
].pc
;
891 sal
= find_pc_line (le
[i
].pc
, 0);
892 mle
[newlines
].end_pc
= sal
.end
;
896 /* Now, sort mle by line #s (and, then by addresses within lines). */
899 qsort (mle
, newlines
, sizeof (struct my_line_entry
), compare_lines
);
901 /* Now, for each line entry, emit the specified lines (unless they have been
902 emitted before), followed by the assembly code for that line. */
904 next_line
= 0; /* Force out first line */
905 for (i
= 0; i
< newlines
; i
++)
907 /* Print out everything from next_line to the current line. */
909 if (mle
[i
].line
>= next_line
)
912 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, 0);
914 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, 0);
916 next_line
= mle
[i
].line
+ 1;
919 for (pc
= mle
[i
].start_pc
; pc
< mle
[i
].end_pc
; )
922 fputs_unfiltered (" ", gdb_stdout
);
923 print_address (pc
, gdb_stdout
);
924 fputs_unfiltered (":\t ", gdb_stdout
);
925 pc
+= (*tm_print_insn
) (pc
, &di
);
926 fputs_unfiltered ("\n", gdb_stdout
);
933 for (pc
= low
; pc
< high
; )
936 fputs_unfiltered (" ", gdb_stdout
);
937 print_address (pc
, gdb_stdout
);
938 fputs_unfiltered (":\t ", gdb_stdout
);
939 pc
+= (*tm_print_insn
) (pc
, &di
);
940 fputs_unfiltered ("\n", gdb_stdout
);
944 gdb_flush (gdb_stdout
);
950 tk_command (cmd
, from_tty
)
956 struct cleanup
*old_chain
;
958 retval
= Tcl_Eval (interp
, cmd
);
960 result
= strdup (interp
->result
);
962 old_chain
= make_cleanup (free
, result
);
964 if (retval
!= TCL_OK
)
967 printf_unfiltered ("%s\n", result
);
969 do_cleanups (old_chain
);
973 cleanup_init (ignored
)
976 if (mainWindow
!= NULL
)
977 Tk_DestroyWindow (mainWindow
);
981 Tcl_DeleteInterp (interp
);
985 /* Come here during long calculations to check for GUI events. Usually invoked
986 via the QUIT macro. */
991 /* Tk_DoOneEvent (TK_DONT_WAIT|TK_IDLE_EVENTS); */
994 /* Come here when there is activity on the X file descriptor. */
1000 /* Process pending events */
1002 while (Tk_DoOneEvent (TK_DONT_WAIT
|TK_ALL_EVENTS
) != 0);
1006 gdbtk_wait (pid
, ourstatus
)
1008 struct target_waitstatus
*ourstatus
;
1010 struct sigaction action
;
1011 static sigset_t nullsigmask
= {0};
1014 /* Needed for SunOS 4.1.x */
1015 #define SA_RESTART 0
1018 action
.sa_handler
= x_event
;
1019 action
.sa_mask
= nullsigmask
;
1020 action
.sa_flags
= SA_RESTART
;
1021 sigaction(SIGIO
, &action
, NULL
);
1023 pid
= target_wait (pid
, ourstatus
);
1025 action
.sa_handler
= SIG_IGN
;
1026 sigaction(SIGIO
, &action
, NULL
);
1031 /* This is called from execute_command, and provides a wrapper around
1032 various command routines in a place where both protocol messages and
1033 user input both flow through. Mostly this is used for indicating whether
1034 the target process is running or not.
1038 gdbtk_call_command (cmdblk
, arg
, from_tty
)
1039 struct cmd_list_element
*cmdblk
;
1043 if (cmdblk
->class == class_run
)
1045 Tcl_VarEval (interp
, "gdbtk_tcl_busy", NULL
);
1046 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1047 Tcl_VarEval (interp
, "gdbtk_tcl_idle", NULL
);
1050 (*cmdblk
->function
.cfunc
)(arg
, from_tty
);
1056 struct cleanup
*old_chain
;
1057 char *gdbtk_filename
;
1059 struct sigaction action
;
1060 static sigset_t nullsigmask
= {0};
1062 old_chain
= make_cleanup (cleanup_init
, 0);
1064 /* First init tcl and tk. */
1066 interp
= Tcl_CreateInterp ();
1069 error ("Tcl_CreateInterp failed");
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
);
1097 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_list", call_wrapper
,
1098 gdb_get_breakpoint_list
, NULL
);
1099 Tcl_CreateCommand (interp
, "gdb_get_breakpoint_info", call_wrapper
,
1100 gdb_get_breakpoint_info
, NULL
);
1102 command_loop_hook
= Tk_MainLoop
;
1103 print_frame_info_listing_hook
= null_routine
;
1104 query_hook
= gdbtk_query
;
1105 flush_hook
= gdbtk_flush
;
1106 create_breakpoint_hook
= gdbtk_create_breakpoint
;
1107 delete_breakpoint_hook
= gdbtk_delete_breakpoint
;
1108 modify_breakpoint_hook
= gdbtk_modify_breakpoint
;
1109 interactive_hook
= gdbtk_interactive
;
1110 target_wait_hook
= gdbtk_wait
;
1111 call_command_hook
= gdbtk_call_command
;
1113 /* Get the file descriptor for the X server */
1115 x_fd
= ConnectionNumber (Tk_Display (mainWindow
));
1117 /* Setup for I/O interrupts */
1119 action
.sa_mask
= nullsigmask
;
1120 action
.sa_flags
= 0;
1121 action
.sa_handler
= SIG_IGN
;
1122 sigaction(SIGIO
, &action
, NULL
);
1126 if (ioctl (x_fd
, FIOASYNC
, &i
))
1127 perror_with_name ("gdbtk_init: ioctl FIOASYNC failed");
1130 if (ioctl (x_fd
, SIOCSPGRP
, &i
))
1131 perror_with_name ("gdbtk_init: ioctl SIOCSPGRP failed");
1133 if (ioctl (x_fd
, I_SETSIG
, S_INPUT
|S_RDNORM
) < 0)
1134 perror_with_name ("gdbtk_init: ioctl I_SETSIG failed");
1135 #endif /* ifndef FIOASYNC */
1137 add_com ("tk", class_obscure
, tk_command
,
1138 "Send a command directly into tk.");
1140 Tcl_LinkVar (interp
, "disassemble-from-exec", (char *)&disassemble_from_exec
,
1143 /* Load up gdbtk.tcl after all the environment stuff has been setup. */
1145 gdbtk_filename
= getenv ("GDBTK_FILENAME");
1146 if (!gdbtk_filename
)
1147 if (access ("gdbtk.tcl", R_OK
) == 0)
1148 gdbtk_filename
= "gdbtk.tcl";
1150 gdbtk_filename
= GDBTK_FILENAME
;
1152 /* Defer setup of fputs_unfiltered_hook to near the end so that error messages
1153 prior to this point go to stdout/stderr. */
1155 fputs_unfiltered_hook
= gdbtk_fputs
;
1157 if (Tcl_EvalFile (interp
, gdbtk_filename
) != TCL_OK
)
1159 fputs_unfiltered_hook
= NULL
; /* Force errors to stdout/stderr */
1161 fprintf_unfiltered (stderr
, "%s:%d: %s\n", gdbtk_filename
,
1162 interp
->errorLine
, interp
->result
);
1164 fputs_unfiltered ("Stack trace:\n", gdb_stderr
);
1165 fputs_unfiltered (Tcl_GetVar (interp
, "errorInfo", 0), gdb_stderr
);
1169 discard_cleanups (old_chain
);
1172 /* Come here during initialze_all_files () */
1175 _initialize_gdbtk ()
1179 /* Tell the rest of the world that Gdbtk is now set up. */
1181 init_ui_hook
= gdbtk_init
;