www.delorie.com/djgpp/bugs/show.cgi   search  
Bug 000073

When Created: 04/11/1996 09:11:46
Against DJGPP version: 2.00
By whom: eliz@is.elta.co.il
Abstract: gdb hangs when printing more than a screenful of text
When debugging programs that switch `stdin' to binary mode, GDB will
hang when it needs to print more than a screenful of text (e.g., if
you request a stack backtrace with the `bt' command, or disassemble
a sufficiently large function).  The first screenful is printed as it
should, then GDB prints the line telling you to press Enter or q and
Enter, and then it hangs; only Ctrl-Alt-Del will help at this point.

Workaround added: 04/11/1996 09:16:06
By whom: eliz@is.elta.co.il
Lie to GDB about the size of your screen, like this:

           (gdb)set height 2000

(or any other large number).  The info GDB prints will scroll off the
screen, of course, but at least you won't be stuck half-way through a
debugging session (and risk losing files).

Solution added: 04/11/1996 09:21:49
By whom: eliz@is.elta.co.il
The problem is caused by GDB using `fgetc' to read a single
character from `stdin'.  This causes problems with binary
reads.  The following patch will momentarily switch `stdin'
back to text mode, call `fgetc' and switch back again.

*** gdb/main.c~0        Wed Jul 27 08:48:54 1994
--- gdb/main.c  Mon Apr  8 17:44:10 1996
*************** gdb_readline (prrompt)
*** 1140,1146 ****
--- 1140,1163 ----
      {
        /* Read from stdin if we are executing a user defined command.
         This is the right thing for prompt_for_continue, at least.  */
+
+ #ifdef __DJGPP__
+
+       /* Under DJGPP, setting stdin to binary (in the debuggee) also
+          affects the debugger, in particular it breaks single-character
+          reads with `fgetc'.  We must momentarily switch stdin to text
+          mode and back for `fgetc' to work.  */
+
+       int current_mode = (instream && instream != stdin)
+                            ? -1
+                              : setmode (fileno (stdin), O_TEXT);
        c = fgetc (instream ? instream : stdin);
+       if (current_mode == O_BINARY)
+         setmode (fileno (stdin), O_BINARY);
+
+ #else
+       c = fgetc (instream ? instream : stdin);
+ #endif

        if (c == EOF)
        {
*** gdb/utils.c~0       Fri Jun 23 07:53:16 1995
--- gdb/utils.c Mon Apr  8 17:51:22 1996
*************** print_spaces (n, file)
*** 775,780 ****
--- 775,784 ----
     The first, a control string, should end in "? ".
     It should not say how to answer, because we do that.  */

+ #ifdef __DJGPP__
+ #include <fcntl.h>
+ #endif
+
  /* VARARGS */
  int
  query (va_alist)
*************** query (va_alist)
*** 785,790 ****
--- 789,807 ----
    register int answer;
    register int ans2;

+ #ifdef __DJGPP__
+
+   /* Under DJGPP, setting stdin to binary (in the debuggee) also
+      affects the debugger, in particular it breaks single-character
+      reads with `fgetc'.  We must momentarily switch stdin to text
+      mode and back for `fgetc' to work.  */
+
+   int current_mode = input_from_terminal_p () ?
+                      setmode (fileno (stdin), O_TEXT) :
+                        -1;
+
+ #endif
+
    /* Automatically answer "yes" if input is not from a terminal.  */
    if (!input_from_terminal_p ())
      return 1;
*************** query (va_alist)
*** 801,806 ****
--- 818,828 ----
        gdb_flush (gdb_stdout);
        answer = fgetc (stdin);
        clearerr (stdin);               /* in case of C-d */
+ #ifdef __DJGPP__
+       if (answer == EOF)
+         if (current_mode == O_BINARY)
+           setmode (fileno (stdin), O_BINARY);
+ #endif
        if (answer == EOF)      /* C-d */
          return 1;
        if (answer != '
')     /* Eat rest of input line, to EOF or newline */
*************** query (va_alist)
*** 812,817 ****
--- 834,844 ----
          while (ans2 != EOF && ans2 != '
');
        if (answer >= 'a')
        answer -= 040;
+ #ifdef __DJGPP__
+       if (answer == 'Y' || answer == 'N')
+         if (current_mode == O_BINARY)
+           setmode (fileno (stdin), O_BINARY);
+ #endif
        if (answer == 'Y')
        return 1;
        if (answer == 'N')

Fixed in version on 04/13/1999 08:00:31
By whom: eliz@is.elta.co.il



  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2010   by DJ Delorie     Updated Jul 2010