* [RFA] insight gdb_stdlog bug
@ 2000-12-20 14:53 David Taylor
2001-01-12 1:37 ` Andrew Cagney
0 siblings, 1 reply; 2+ messages in thread
From: David Taylor @ 2000-12-20 14:53 UTC (permalink / raw)
To: insight; +Cc: gdb-patches
When GDBTK_TO_RESULT is set, insight gobbles all output written to
gdb_stdlog. But, the stuff written to gdb_stdlog isn't meant to be
parsed by insight -- it's meant to be read by a person.
While it might be desired -- when GDBTK_TO_RESULT is not set -- that
gdb_stdlog go the same place as gdb_stdout, it cannot have the same
pointer value as gdb_stdout or the code won't be able to distinguish
output meant for gdb_stdout vs output meant for gdb_stdlog when
GDBTK_TO_RESULT is set.
The following patch fixes that. (The result is that output written to
gdb_stdlog appears in the insight console window if it is active.)
ChangeLog entries (3 separate ChangeLog files):
* main.c (captured_main): Initialize gdb_stdlog to a copy of
gdb_stdout rather than to gdb_stdout, so that code can distinguish
them.
* tui/tui-file.c (tui_file_fputs): Handle gdb_stdlog the same
as gdb_stdout.
* gdbtk/generic/gdbtk-hooks.c (gdbtk_fputs): Distinguish between
gdb_stdlog and gdb_stdout.
Index: main.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/main.c,v
retrieving revision 1.207.12.1
diff -c -r1.207.12.1 main.c
*** main.c 2000/11/13 02:10:59 1.207.12.1
--- main.c 2000/12/20 22:23:25
***************
*** 203,209 ****
within its own _initialize function. */
gdb_stdout = tui_fileopen (stdout);
gdb_stderr = tui_fileopen (stderr);
! gdb_stdlog = gdb_stdout; /* for moment */
gdb_stdtarg = gdb_stderr; /* for moment */
#else
gdb_stdout = stdio_fileopen (stdout);
--- 203,209 ----
within its own _initialize function. */
gdb_stdout = tui_fileopen (stdout);
gdb_stderr = tui_fileopen (stderr);
! gdb_stdlog = tui_fileopen (stdout); /* for moment */
gdb_stdtarg = gdb_stderr; /* for moment */
#else
gdb_stdout = stdio_fileopen (stdout);
Index: tui/tui-file.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/tui/tui-file.c,v
retrieving revision 1.5
diff -c -r1.5 tui-file.c
*** tui-file.c 2000/07/30 01:50:07 1.5
--- tui-file.c 2000/12/20 22:23:25
***************
*** 181,187 ****
also tui_file_flush(). */
if (fputs_unfiltered_hook
&& (file == gdb_stdout
! || file == gdb_stderr))
fputs_unfiltered_hook (linebuffer, file);
else
{
--- 181,188 ----
also tui_file_flush(). */
if (fputs_unfiltered_hook
&& (file == gdb_stdout
! || file == gdb_stderr
! || file == gdb_stdlog))
fputs_unfiltered_hook (linebuffer, file);
else
{
Index: gdbtk/generic/gdbtk-hooks.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk/generic/gdbtk-hooks.c,v
retrieving revision 1.7
diff -c -r1.7 gdbtk-hooks.c
*** gdbtk-hooks.c 2000/10/23 22:42:01 1.7
--- gdbtk-hooks.c 2000/12/20 22:23:29
***************
*** 250,256 ****
if (result_ptr != NULL)
{
! if (result_ptr->flags & GDBTK_TO_RESULT)
{
if (result_ptr->flags & GDBTK_MAKES_LIST)
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
--- 250,258 ----
if (result_ptr != NULL)
{
! if (stream == gdb_stdlog)
! gdbtk_two_elem_cmd ("gdbtk_tcl_fputs", (char *) ptr);
! else if (result_ptr->flags & GDBTK_TO_RESULT)
{
if (result_ptr->flags & GDBTK_MAKES_LIST)
Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [RFA] insight gdb_stdlog bug
2000-12-20 14:53 [RFA] insight gdb_stdlog bug David Taylor
@ 2001-01-12 1:37 ` Andrew Cagney
0 siblings, 0 replies; 2+ messages in thread
From: Andrew Cagney @ 2001-01-12 1:37 UTC (permalink / raw)
To: David Taylor; +Cc: insight, gdb-patches
David Taylor wrote:
>
> When GDBTK_TO_RESULT is set, insight gobbles all output written to
> gdb_stdlog. But, the stuff written to gdb_stdlog isn't meant to be
> parsed by insight -- it's meant to be read by a person.
>
> While it might be desired -- when GDBTK_TO_RESULT is not set -- that
> gdb_stdlog go the same place as gdb_stdout, it cannot have the same
> pointer value as gdb_stdout or the code won't be able to distinguish
> output meant for gdb_stdout vs output meant for gdb_stdlog when
> GDBTK_TO_RESULT is set.
>
> The following patch fixes that. (The result is that output written to
> gdb_stdlog appears in the insight console window if it is active.)
>
> ChangeLog entries (3 separate ChangeLog files):
>
> * main.c (captured_main): Initialize gdb_stdlog to a copy of
> gdb_stdout rather than to gdb_stdout, so that code can distinguish
> them.
>
> * tui/tui-file.c (tui_file_fputs): Handle gdb_stdlog the same
> as gdb_stdout.
>
> * gdbtk/generic/gdbtk-hooks.c (gdbtk_fputs): Distinguish between
> gdb_stdlog and gdb_stdout.
David,
This feels wrong. Anything touching tui/tui-file.c is going in the
wrong direction. Rather than depend on tui-file.c, gdbtk should, like
mi, create its own *-file object and use that.
The attatched (very old) patch does this. From memory, its poossible
approval was lost in time.
Andrew
Index: ChangeLog-gdbtk
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/ChangeLog-gdbtk,v
retrieving revision 2.113
diff -p -r2.113 ChangeLog-gdbtk
*** ChangeLog-gdbtk 1999/06/21 20:12:40 2.113
--- ChangeLog-gdbtk 1999/06/25 07:34:29
***************
*** 1,3 ****
--- 1,27 ----
+ Wed May 26 10:37:25 1999 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * gdbtk-hooks.c (gdbtk_fputs): Make static.
+ (gdbtk_add_hooks): Delete assignment of flush_hook.
+ (struct gdbtk_file): Dummy structure.
+ (gdbtk_file_delete, gdbtk_file_new): New functions. Implement
+ ``struct gdb_file'' for GDBtk.
+ (gdbtk_flush): Delete function.
+
+ * gdbtk.h (gdbtk_claim_stdio, gdbtk_release_stdio,
+ gdbtk_null_stdio): Add declarations.
+ * gdbtk-hooks.c (gdbtk_claim_stdio, gdbtk_release_stdio,
+ gdbtk_null_stdio): New functions. Switch between output
+ alternatives.
+
+ * gdbtk.c (gdbtk_fputs): Delete declaration.
+ (gdbtk_init): Replace assignment of fputs_unfiltered_hook with
+ calls to gdbtk_claim_stdio and gdbtk_release_stdio.
+
+ * gdbtk-variable.c (create_variable): Call gdbtk_claim_stdio() to
+ restore GDBtk output. Call gdbtk_null_stdio() to discard the
+ output.
+ (variable_value_changed): Ditto.
+
1999-06-21 James Ingham <jingham@leda.cygnus.com>
* gdbtk.c (target_should_use_timer): Add check for "linuxthreads"
Index: gdbtk-hooks.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk-hooks.c,v
retrieving revision 2.25
diff -p -r2.25 gdbtk-hooks.c
*** gdbtk-hooks.c 1999/06/15 19:24:18 2.25
--- gdbtk-hooks.c 1999/06/25 07:34:30
*************** static void gdbtk_warning PARAMS ((con
*** 90,96 ****
static char* gdbtk_readline PARAMS ((char *));
static void gdbtk_readline_begin (char *format, ...);
static void gdbtk_readline_end PARAMS ((void));
- static void gdbtk_flush PARAMS ((GDB_FILE *));
static void gdbtk_pre_add_symbol PARAMS ((char *));
static void gdbtk_print_frame_info PARAMS ((struct symtab *, int, int, int));
static void gdbtk_post_add_symbol PARAMS ((void));
--- 90,95 ----
*************** static void gdbtk_error_begin PARAMS ((v
*** 103,114 ****
static void report_error (void);
static void gdbtk_annotate_signal (void);
! /*
! * gdbtk_fputs can't be static, because we need to call it in gdbtk.c.
! * See note there for details.
! */
!
! void gdbtk_fputs PARAMS ((const char *, GDB_FILE *));
int gdbtk_load_hash PARAMS ((char *, unsigned long));
static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
--- 102,108 ----
static void report_error (void);
static void gdbtk_annotate_signal (void);
! static void gdbtk_fputs PARAMS ((const char *, GDB_FILE *));
int gdbtk_load_hash PARAMS ((char *, unsigned long));
static void breakpoint_notify PARAMS ((struct breakpoint *, const char *));
*************** gdbtk_add_hooks(void)
*** 129,135 ****
print_frame_info_listing_hook = gdbtk_print_frame_info;
query_hook = gdbtk_query;
warning_hook = gdbtk_warning;
- flush_hook = gdbtk_flush;
create_breakpoint_hook = gdbtk_create_breakpoint;
delete_breakpoint_hook = gdbtk_delete_breakpoint;
--- 123,128 ----
*************** gdbtk_add_hooks(void)
*** 162,169 ****
}
/* These control where to put the gdb output which is created by
! {f}printf_{un}filtered and friends. gdbtk_fputs and gdbtk_flush are the
! lowest level of these routines and capture all output from the rest of GDB.
The reason to use the result_ptr rather than the gdbtk_interp's result
directly is so that a call_wrapper invoked function can preserve its result
--- 155,163 ----
}
/* These control where to put the gdb output which is created by
! {f}printf_{un}filtered and friends. gdbtk_fputs is the lowest
! level of these routines and capture all output from the rest of
! GDB.
The reason to use the result_ptr rather than the gdbtk_interp's result
directly is so that a call_wrapper invoked function can preserve its result
*************** int gdbtk_two_elem_cmd (cmd_name, argv1)
*** 205,221 ****
return result;
}
- static void
- gdbtk_flush (stream)
- GDB_FILE *stream;
- {
- #if 0
- /* Force immediate screen update */
-
- Tcl_VarEval (gdbtk_interp, "gdbtk_tcl_flush", NULL);
- #endif
- }
-
/* This handles all the output from gdb. All the gdb printf_xxx functions
* eventually end up here. The output is either passed to the result_ptr
* where it will go to the result of some gdbtk command, or passed to the
--- 199,204 ----
*************** gdbtk_flush (stream)
*** 236,246 ****
*
*/
! void
gdbtk_fputs (ptr, stream)
const char *ptr;
GDB_FILE *stream;
{
in_fputs = 1;
if (result_ptr != NULL)
--- 219,238 ----
*
*/
! static int gdbtk_file_magic;
!
! struct gdbtk_file
! {
! int *magic;
! };
!
! static void
gdbtk_fputs (ptr, stream)
const char *ptr;
GDB_FILE *stream;
{
+ /* struct gdbtk_file *gdbtk = gdb_file_data (stream); */
+ /* ASSERT (gdbtk_file->magic == &gdbtk_file_magic); */
in_fputs = 1;
if (result_ptr != NULL)
*************** gdbtk_fputs (ptr, stream)
*** 276,281 ****
--- 268,342 ----
}
in_fputs = 0;
+ }
+
+ static gdb_file_delete_ftype gdbtk_file_delete;
+ static void
+ gdbtk_file_delete (stream)
+ struct gdb_file *stream;
+ {
+ struct gdbtk_file *gdbtk = gdb_file_data (stream);
+ /* ASSERT (gdbtk_file->magic == &gdbtk_file_magic); */
+ free (gdbtk);
+ }
+
+ static struct gdb_file *gdbtk_file_new PARAMS ((void));
+ static struct gdb_file *
+ gdbtk_file_new ()
+ {
+ struct gdb_file *gdb_file = gdb_file_new ();
+ struct gdbtk_file *gdbtk_file = xmalloc (sizeof (struct gdbtk_file));
+ gdbtk_file->magic = &gdbtk_file_magic;
+ set_gdb_file_fputs (gdb_file, gdbtk_fputs);
+ set_gdb_file_data (gdb_file, gdbtk_file, gdbtk_file_delete);
+ return gdb_file;
+ }
+
+ static struct gdb_file *tty_stdout;
+ static struct gdb_file *tty_stderr;
+
+ static struct gdb_file *gdbtk_stdout;
+ static struct gdb_file *gdbtk_stderr;
+
+ static struct gdb_file *null_stdout;
+ static struct gdb_file *null_stderr;
+
+ void
+ gdbtk_claim_stdio ()
+ {
+ static int done;
+ if (!done)
+ {
+ /* save the original gdb_stdout/gdb_stderr. */
+ tty_stdout = gdb_stdout;
+ tty_stderr = gdb_stderr;
+ /* create GDBtk's stdout/stderr. */
+ gdbtk_stdout = gdbtk_file_new ();
+ gdbtk_stderr = gdbtk_file_new ();
+ /* and null devices */
+ null_stdout = gdb_file_new ();
+ null_stderr = gdb_file_new ();
+ done = 1;
+ }
+ /* select our stdio */
+ gdb_stdout = gdbtk_stdout;
+ gdb_stderr = gdbtk_stderr;
+ }
+
+ void
+ gdbtk_release_stdio ()
+ {
+ /* restore the original stdio. */
+ gdb_stdout = tty_stdout;
+ gdb_stderr = tty_stderr;
+ }
+
+ void
+ gdbtk_null_stdio ()
+ {
+ /* null output */
+ gdb_stdout = null_stdout;
+ gdb_stderr = null_stderr;
}
/*
Index: gdbtk-variable.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk-variable.c,v
retrieving revision 2.7
diff -p -r2.7 gdbtk-variable.c
*** gdbtk-variable.c 1999/05/25 19:06:14 2.7
--- gdbtk-variable.c 1999/06/25 07:34:34
*************** create_variable (name, real_name, frame)
*** 546,553 ****
/* Several of the GDB_* calls can cause messages to be displayed. We swallow
those here, because we don't need them (the "value" command will
show them). */
! old_fputs = fputs_unfiltered_hook;
! fputs_unfiltered_hook = null_fputs;
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
--- 546,552 ----
/* Several of the GDB_* calls can cause messages to be displayed. We swallow
those here, because we don't need them (the "value" command will
show them). */
! gdbtk_null_stdio ();
/* Parse and evaluate the expression, filling in as much
of the variable's data as possible */
*************** create_variable (name, real_name, frame)
*** 572,578 ****
FREEIF ((char *) var);
/* Restore the output hook to normal */
! fputs_unfiltered_hook = old_fputs;
return NULL;
}
--- 571,577 ----
FREEIF ((char *) var);
/* Restore the output hook to normal */
! gdbtk_claim_stdio ();
return NULL;
}
*************** create_variable (name, real_name, frame)
*** 584,590 ****
FREEIF (var);
/* Restore the output hook to normal */
! fputs_unfiltered_hook = old_fputs;
printf_unfiltered ("Attempt to use a type name as an expression.");
return NULL;
--- 583,589 ----
FREEIF (var);
/* Restore the output hook to normal */
! gdbtk_claim_stdio ();
printf_unfiltered ("Attempt to use a type name as an expression.");
return NULL;
*************** create_variable (name, real_name, frame)
*** 623,629 ****
GDB_select_frame (old_fi, -1);
/* Restore the output hook to normal */
! fputs_unfiltered_hook = old_fputs;
var->num_children = number_of_children (var);
var->format = variable_default_display (var);
--- 622,628 ----
GDB_select_frame (old_fi, -1);
/* Restore the output hook to normal */
! gdbtk_claim_stdio ();
var->num_children = number_of_children (var);
var->format = variable_default_display (var);
*************** variable_value_changed (var)
*** 1130,1137 ****
/* evaluate_expression can output errors to the screen,
so swallow them here. */
! old_hook = fputs_unfiltered_hook;
! fputs_unfiltered_hook = null_fputs;
/* Arrays, struct, classes, unions never change value */
if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_STRUCT
--- 1129,1135 ----
/* evaluate_expression can output errors to the screen,
so swallow them here. */
! gdbtk_null_stdio ();
/* Arrays, struct, classes, unions never change value */
if (type != NULL && (TYPE_CODE (type) == TYPE_CODE_STRUCT
*************** variable_value_changed (var)
*** 1179,1185 ****
}
/* Restore the original fputs_hook. */
! fputs_unfiltered_hook = old_hook;
}
/* Restore selected frame */
--- 1177,1183 ----
}
/* Restore the original fputs_hook. */
! gdbtk_claim_stdio ();
}
/* Restore selected frame */
*************** call_gdb_type_print (val)
*** 1476,1483 ****
int result;
/* Save the old hook and install new hook */
! old_hook = fputs_unfiltered_hook;
! fputs_unfiltered_hook = variable_fputs;
/* Call our command with our args */
clear_gdb_output ();
--- 1474,1480 ----
int result;
/* Save the old hook and install new hook */
! gdbtk_null_stdio ();
/* Call our command with our args */
clear_gdb_output ();
*************** call_gdb_type_print (val)
*** 1489,1495 ****
result = TCL_ERROR;
/* Restore fputs hook */
! fputs_unfiltered_hook = old_hook;
return result;
}
--- 1486,1492 ----
result = TCL_ERROR;
/* Restore fputs hook */
! gdbtk_claim_stdio ();
return result;
}
*************** call_gdb_val_print (val, format)
*** 1505,1512 ****
int result;
/* Save the old hook and install new hook */
! old_hook = fputs_unfiltered_hook;
! fputs_unfiltered_hook = variable_fputs;
/* Call our command with our args */
clear_gdb_output ();
--- 1502,1508 ----
int result;
/* Save the old hook and install new hook */
! gdbtk_null_stdio ();
/* Call our command with our args */
clear_gdb_output ();
*************** call_gdb_val_print (val, format)
*** 1516,1522 ****
r = GDB_value_fetch_lazy (val);
if (r != GDB_OK)
{
! fputs_unfiltered_hook = old_hook;
return TCL_ERROR;
}
}
--- 1512,1518 ----
r = GDB_value_fetch_lazy (val);
if (r != GDB_OK)
{
! gdbtk_claim_stdio ();
return TCL_ERROR;
}
}
*************** call_gdb_val_print (val, format)
*** 1528,1534 ****
result = TCL_ERROR;
/* Restore fputs hook */
! fputs_unfiltered_hook = old_hook;
return result;
}
--- 1524,1530 ----
result = TCL_ERROR;
/* Restore fputs hook */
! gdbtk_claim_stdio ();
return result;
}
Index: gdbtk.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk.c,v
retrieving revision 2.135
diff -p -r2.135 gdbtk.c
*** gdbtk.c 1999/06/21 20:12:37 2.135
--- gdbtk.c 1999/06/25 07:34:35
*************** void gdbtk_add_hooks PARAMS ((void));
*** 112,125 ****
int gdbtk_test PARAMS ((char *));
- /*
- * gdbtk_fputs is defined in the gdbtk_hooks.c, but we need it here
- * because we delay adding this hook till all the setup is done. That
- * way errors will go to stdout.
- */
-
- extern void gdbtk_fputs PARAMS ((const char *, GDB_FILE *));
-
/* Handle for TCL interpreter */
Tcl_Interp *gdbtk_interp = NULL;
--- 112,117 ----
*************** gdbtk_find_main";
*** 525,531 ****
/* fputs_unfiltered_hook = NULL; */ /* Force errors to stdout/stderr */
! fputs_unfiltered_hook = gdbtk_fputs;
if (Tcl_GlobalEval (gdbtk_interp, (char *) script) != TCL_OK)
{
--- 517,524 ----
/* fputs_unfiltered_hook = NULL; */ /* Force errors to stdout/stderr */
! /* create custom GDBtk streams. */
! gdbtk_claim_stdio ();
if (Tcl_GlobalEval (gdbtk_interp, (char *) script) != TCL_OK)
{
*************** gdbtk_find_main";
*** 536,542 ****
msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
! fputs_unfiltered_hook = NULL; /* Force errors to stdout/stderr */
#ifdef _WIN32
MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
--- 529,535 ----
msg = Tcl_GetVar (gdbtk_interp, "errorInfo", TCL_GLOBAL_ONLY);
! gdbtk_release_stdio (); /* Force errors to stdout/stderr */
#ifdef _WIN32
MessageBox (NULL, msg, NULL, MB_OK | MB_ICONERROR | MB_TASKMODAL);
Index: gdbtk.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/gdbtk.h,v
retrieving revision 2.8
diff -p -r2.8 gdbtk.h
*** gdbtk.h 1999/04/02 18:33:13 2.8
--- gdbtk.h 1999/06/25 07:34:35
*************** extern int x_event PARAMS ((int));
*** 149,154 ****
--- 149,159 ----
extern int gdbtk_two_elem_cmd PARAMS ((char *, char *));
extern int call_wrapper PARAMS ((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []));
+ /* GDBtk stdio control functions. */
+ extern void gdbtk_claim_stdio PARAMS ((void));
+ extern void gdbtk_release_stdio PARAMS ((void));
+ extern void gdbtk_null_stdio PARAMS ((void));
+
#ifdef _WIN32
extern void close_bfds ();
#endif /* _WIN32 */
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2001-01-12 1:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-12-20 14:53 [RFA] insight gdb_stdlog bug David Taylor
2001-01-12 1:37 ` Andrew Cagney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).