Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
I am writing to console from several threads using printf(). The process is synchronized and it works fine.
The problem is that sometimes some of threads freezes (never returns ) at WriteFile() function used to implement printf() and the really strange here is that it returns and everything continues when i click with the right button (NOT THE LEFT) on the console.
Can someone help me to figure out what's going on?
Thank you very much in advance!
void Log::write( const char* msg )
{
printf( msg );
} ...
and in ...\VC98\CRT\SRC\WRITE.C
/* now define version that doesn't lock/unlock, validate fh */
int __cdecl _write_lk (
int fh,
const void *buf,
unsigned cnt
)
{
int lfcount; /* count of line feeds */
int charcount; /* count of chars written so far */
int written; /* count of chars written on this write */
ULONG dosretval; /* o.s. return value */
char ch; /* current character */
char *p, *q; /* pointers into buf and lfbuf resp. */
char lfbuf[BUF_SIZE]; /* lf translation buffer */
#else /* _MT */
/* now define normal version */
int __cdecl _write (
int fh,
const void *buf,
unsigned cnt
)
{
int lfcount; /* count of line feeds */
int charcount; /* count of chars written so far */
int written; /* count of chars written on this write */
ULONG dosretval; /* o.s. return value */
char ch; /* current character */
char *p, *q; /* pointers into buf and lfbuf resp. */
char lfbuf[BUF_SIZE]; /* lf translation buffer */
/* validate handle */
if ( ((unsigned)fh >= (unsigned)_nhandle) ||
!(_osfile(fh) & FOPEN) )
{
/* out of range -- return error */
errno = EBADF;
_doserrno = 0; /* not o.s. error */
return -1;
}
#endif /* _MT */
lfcount = charcount = 0; /* nothing written yet */
if (cnt == 0)
return 0; /* nothing to do */
if (_osfile(fh) & FAPPEND) {
/* appending - seek to end of file; ignore error, because maybe
file doesn't allow seeking */
(void)_lseek_lk(fh, 0, FILE_END);
}
/* check for text mode with LF's in the buffer */
if ( _osfile(fh) & FTEXT ) {
/* text mode, translate LF's to CR/LF's on output */
p = (char *)buf; /* start at beginning of buffer */
dosretval = 0; /* no OS error yet */
while ( (unsigned)(p - (char *)buf) < cnt ) {
q = lfbuf; /* start at beginning of lfbuf */
/* fill the lf buf, except maybe last char */
while ( q - lfbuf < BUF_SIZE - 1 &&
(unsigned)(p - (char *)buf) < cnt ) {
ch = *p++;
if ( ch == LF ) {
++lfcount;
*q++ = CR;
}
*q++ = ch;
}
/* write the lf buf and update total */
<strong>HERE IS THE PROBLEM : </strong>
<strong>if ( WriteFile( (HANDLE)_osfhnd(fh),
lfbuf,
q - lfbuf,
(LPDWORD)&written,
NULL) )</strong> {
charcount += written;
if (written < q - lfbuf)
break;
}
else {
dosretval = GetLastError();
break;
}
}
}
else {
/* binary mode, no translation */
if ( WriteFile( (HANDLE)_osfhnd(fh),
(LPVOID)buf,
cnt,
(LPDWORD)&written,
NULL) ) {
dosretval = 0;
charcount = written;
}
else
dosretval = GetLastError();
}
if (charcount == 0) {
/* If nothing was written, first check if an o.s. error,
otherwise we return -1 and set errno to ENOSPC,
unless a device and first char was CTRL-Z */
if (dosretval != 0) {
/* o.s. error happened, map error */
if (dosretval == ERROR_ACCESS_DENIED) {
/* wrong read/write mode should return EBADF, not
EACCES */
errno = EBADF;
_doserrno = dosretval;
}
else
_dosmaperr(dosretval);
return -1;
}
else if ((_osfile(fh) & FDEV) && *(char *)buf == CTRLZ)
return 0;
else {
errno = ENOSPC;
_doserrno = 0; /* no o.s. error */
return -1;
}
}
else
/* return adjusted bytes written */
return charcount - lfcount;
}
... and so on
>printf( msg );
Bad idea. If msg contains any sequences of characters that look like a format modifier, you'll invoke undefined behavior. Do this instead:
printf( "%s", msg ); >sometimes some of threads freezes
Sounds like a deadlock to me. It also sounds like a perfect opportunity to search google for similar problems and solutions.