This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [RFA] insight gdb_stdlog bug


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 */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]