Mail Archives: djgpp/1996/06/12/08:16:30
On Sun, 9 Jun 1996 j DOT aldrich6 AT genie DOT com wrote:
> encountered another problem. If I told the program to output to stdprn
> when my printer was not turned on, then the first call to fprintf using
> stdprn would cause a SIGSEGV.
[snip]
> --- Under DOS w/CWSDPMI ---
>
> C:\CPROGS>test2
> Exiting due to signal SIGSEGV
> Page fault at eip=00006168, error=0006
This is a bug in the library function `_flsbuf'. It doesn't allocate a
buffer for line-buffered standard streams, and `stdprn' is the only
standard stream that is defined by default to be line-buffered. So
`_flsbuf' boldly dereferences a NULL pointer, and CWSDPMI promptly catches
that. Below I post a patch for this problem. I also want to reiterate
the following passage from the DJGPP FAQ list (section 9.1):
**Q*: My v2.0 program crashes, but only under CWSDPMI; it runs OK
under other DPMI hosts like Windows, OS/2 or QDPMI. Is this a bug in
CWSDPMI?*
[snip]
Another possible cause of problems will most probably be seen under
CWSDPMI. Unlike other DPMI hosts, CWSDPMI supports some DPMI 1.0
extensions which allow DJGPP to capture and disallow illegal
dereference of pointers which point to addresses less than 1000h (aka
"NULL pointer protection"). This feature may be disabled by setting
the `_CRT0_FLAG_NULLOK' bit in `_crt0_startup_flags'; if this makes
SIGSEGV crashes to go away, your program is using such illegal
pointers.
Now, how the heck, I wonder, did that FAQ author know that in advance?...
Here is that patch I promised. After you install it, CWSDPMI and Windows
make `fprintf' fail when the printer is OFF, and under QDPMI you will
crash (the well-known QDPMI bug in handling Int 24h).
----------------------------- cut here ---------------------------------
*** src/libc/ansi/stdio/flsbuf.c~0 Fri Jun 16 08:59:52 1995
--- src/libc/ansi/stdio/flsbuf.c Wed Jun 12 13:44:44 1996
*************** _flsbuf(int c, FILE *f)
*** 24,30 ****
if ((f->_flag&_IOWRT)==0)
return EOF;
! tryagain:
if (f->_flag&_IOLBF)
{
base = f->_base;
--- 24,48 ----
if ((f->_flag&_IOWRT)==0)
return EOF;
! if ((base = f->_base) == NULL && (f->_flag & _IONBF) == 0)
! {
! size = _go32_info_block.size_of_transfer_buffer;
! if ((f->_base = base = malloc (size)) == NULL)
! f->_flag |= _IONBF;
! else
! {
! f->_flag |= _IOMYBUF;
! f->_bufsiz = size;
! if (f == stdout && isatty (fileno (stdout)))
! f->_flag |= _IOLBF;
! else
! rn = n = 0;
!
! f->_ptr = base;
! f->_cnt = f->_bufsiz;
! }
! }
!
if (f->_flag&_IOLBF)
{
base = f->_base;
*************** _flsbuf(int c, FILE *f)
*** 51,76 ****
}
else
{
! if ((base=f->_base)==NULL)
! {
! size = _go32_info_block.size_of_transfer_buffer;
! if ((f->_base=base=malloc(size)) == NULL)
! {
! f->_flag |= _IONBF;
! goto tryagain;
! }
! f->_flag |= _IOMYBUF;
! f->_bufsiz = size;
! if (f==stdout && isatty(fileno(stdout)))
! {
! f->_flag |= _IOLBF;
! f->_ptr = base;
! goto tryagain;
! }
! rn = n = 0;
! }
! else
! rn = f->_ptr - base;
f->_ptr = base;
f->_cnt = f->_bufsiz;
}
--- 69,75 ----
}
else
{
! rn = f->_ptr - base;
f->_ptr = base;
f->_cnt = f->_bufsiz;
}
- Raw text -