Menu

#117 MS exception on pipe close

open
nobody
None
5
2004-10-22
2004-10-22
Steve Bold
No

I have an application running on Windows XP, using
Tcl/Tk 8.4.3
and BLT 2.4Z and built using Visual C++ 6.

When I run the application under the msdev debugger,
each use of blt::bgexec
triggers a debugger error. These are reproducable in
bltsh.exe and are reported as:

First-chance exception in bltsh.exe (NTDLL.DLL):
0xC0000008: invalid Handle.

The problem is reproducible with very simple commands
such as:

blt::bgexec q ls

When not using the debugger, there are no visible
symptoms of the problem.
I think that the exception is preventing BLT from
cleaning up the pipes
and so causing a resource leak but it's hard to prove
this.

The error is reported here:

NTDLL! 77f7592b()
7ffe0304()
Blt_DeleteFileHandler(int 1904) line 2301 + 9 bytes
CloseSink() line 856 + 12 bytes
StdoutProc(void * 0x00a914e8, int -3) line 1707 + 19
bytes
PipeEventProc(Tcl_Event * 0x00a96150, int -3) line 329
+ 17 bytes
TCL84! 004dca6a()
TCL84! 004dcdef()
BgexecCmd(void * 0x00000000, Tcl_Interp *
0x00a4a7a0, int 3, char * * 0x0026f528) line 1944 + 8
bytes
TCL84! 004809c6()
TCL84! 00481d36()
TCL84! 004af41e()
TCL84! 004ae4f7()
TCL84! 00482e24()
TCL84! 004c16c6()
TCL84! 004d8531()
main() line 195 + 19 bytes
BLTSH! mainCRTStartup + 227 bytes
KERNEL3

As often happens, the error has truncated the
traceback so the exact
point of failure is obscured. Stepping through the code
shows that
the final statement before the error is the following:

DeletePipeHandler(PipeHandler * 0x00a95cb8) line 532
Blt_DeleteFileHandler(int 1904) line 2301 + 9 bytes
CloseSink() line 856 + 12 bytes
StdoutProc(void * 0x00a914e8, int -3) line 1707 + 19
bytes
PipeEventProc(Tcl_Event * 0x00a96150, int -3) line 329
+ 17 bytes
TCL84! 004dca6a()
TCL84! 004dcdef()
BgexecCmd(void * 0x00000000, Tcl_Interp *
0x00a4a7a0, int 3, char * * 0x0026f528) line 1944 + 8
bytes
TCL84! 004809c6()
TCL84! 00481d36()
TCL84! 004af41e()
TCL84! 004ae4f7()
TCL84! 00482e24()
TCL84! 004c16c6()
TCL84! 004d8531()
main() line 195 + 19 bytes
BLTSH! mainCRTStartup + 227 bytes
KERNEL32! 77e7eb69()

There are some aspects of PipeReaderThread() that look
wrong to me, though it could be
my mis-understaning:

* the pipe will be closed with the thread reader calling:

WaitForSingleObject(pipePtr->idleEvent, INFINITE);

but the test 'pipePtr->flags & PIPE_DELETED' occurs
before the wait,
so it always goes on to try to read from the handle.
Should the order
be reversed?

* the main thread calls Tcl_EventuallyFree() on pipePtr.
PipeReaderThread() doesn't
have a Tcl_Preserve() on this, so can it safely
dereference pipePtr in its
final iteration?

Unfortunately, I didn't manage to resolve the exception
problem

Discussion

  • Nobody/Anonymous

    Logged In: NO

    I am seeing this error as well, and think it is causing
    problems.

    But I don't think the problem is with the PipeReaderThread
    as suggested. That test on PIPE_DELETED should never occur
    in normal operation. I think it would take an exceptional
    condition to hit it. Normally, an EOF or error will occur
    from the ReadFile and the ExitThread(0) will kick in before
    you get around to that test again.

    I also don't think the PipeReadThread needs to have a
    TclPreserve on the pipePtr. I think there are other checks
    in the event sequencing that prevent the DeletePipeHandler
    from being called while the thread is still going. But I
    could be wrong on this.

     
  • Nobody/Anonymous

    Logged In: NO

    I believe this occurs because CloseSink (in bltBgexec.c)
    does "close(sinkPtr->fd);" and on WIndows this means
    CloseHandle((HANDLE)sinkPtr->fd, from the #ifdef WIN32
    #define. Then, a few lines later CloseSink calls
    Tcl_DeleteFileHandler, which on Windows is
    BltDeleteFileHandler. Blt_DeleteFileHandler in turn calls
    DeletePipeHandler which calls CloseHandle(pipePtr->hPipe).
    but pipePtr->hPipe is our good friend sinkPtr->fd, which
    apparently has already been closed enough, thus the debug
    message. I tried commenting out the first close, and the
    message goes away. Now to figure out if that is appropriate
    for Windows (I think it is), and for Linux (might not be,
    because the closing is different there).

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.