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.
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')