Tcl Source Code

View Ticket
Login
Ticket UUID: 859820
Title: tclsh84t crashes when opening pipe
Type: Bug Version: obsolete: 8.4.4
Submitter: yahalom Created on: 2003-12-14 12:54:25
Subsystem: 27. Channel Types Assigned To: davygrvy
Priority: 8 Severity:
Status: Closed Last Modified: 2004-01-21 16:19:21
Resolution: Fixed Closed By: davygrvy
    Closed on: 2004-01-21 09:19:21
Description:
tcl8.4.4
thread 2.5.2
win200

when I open a pipe to an exe and another thread closes 
a pipe to that exe tcl crashes.
it does not happen all the time. it seems that this 
actions need to happen at the same time exactly.
I made locking around the open and close points and it 
works fine.
is the open/close pipe not thread safe?
visual studio says:
Application popup: tclsh84t.exe - Application Error : The 
instruction at "0x100682fc" referenced memory 
at "0x00000009". The memory could not be "read".

unhandled exception in tclsh84t.exe (tcl84t.dll) 
0xC0000005: Access Violation
100682E6   call        1006BC20
100682EB   mov         esi,dword ptr ds:[100896D4h]
100682F1   add         esp,4
100682F4   test        esi,esi
100682F6   je          10068307
100682F8   mov         eax,dword ptr [esp+8]

->100682FC   cmp         dword ptr [esi],eax
100682FE   je          10068319
10068300   mov         esi,dword ptr [esi+8]
10068303   test        esi,esi
10068305   jne         100682FC
10068307   push        100896CCh
1006830C   call        1006BC70
10068311   add         esp,4
10068314   or          eax,0FFFFFFFFh
10068317   pop         esi
10068318   ret
10068319   push        100896CCh
1006831E   call        1006BC70
10068323   mov         eax,dword ptr [esi+4]
10068326   add         esp,4
10068329   pop         esi
User Comments: davygrvy added on 2004-01-21 16:19:08:
Logged In: YES 
user_id=7549

Good to know this worked-out.

davygrvy added on 2004-01-21 16:18:32:

File Added - 74247: patch.txt

Logged In: YES 
user_id=7549

attached patch.  Just apply this patch to the 8.4 source, it's 
the safest way to go.

c:\tcl_src\win\> patch -c -i patch.txt

yahalom added on 2004-01-21 14:48:47:
Logged In: YES 
user_id=130120

tested the fix and there is no crash. it seems the bug was 
fixed. thanks for the great work.
do you know when tcl8.5 will be out?
is it safe to take only tclWinPipe.c and compile it with tcl8.4?

davygrvy added on 2004-01-20 12:40:54:
Logged In: YES 
user_id=7549

r1.40 has the fix.

davygrvy added on 2004-01-20 12:39:24:
Logged In: YES 
user_id=7549

anon access might be running a day behind.  It's the same as 
the attachment here.

yahalom added on 2004-01-20 12:32:16:
Logged In: YES 
user_id=130120

I do not see that tclWinPipe was changed in the cvs. how do 
I get it in order to test it.

davygrvy added on 2004-01-20 12:20:21:
Logged In: YES 
user_id=7549

Committed patch to HEAD.  Please do a CVS update to test 
the fix.  All tests pass as before.  It looks right, to me.

davygrvy added on 2004-01-19 07:44:10:

File Added - 73932: tclWinPipe.c

Logged In: YES 
user_id=7549

Try this.  Get the attachment and rebuild.  I'd post a diff, but 
CVS is down today for maintenance.  This should avoid the 
pointer going stale.

davygrvy added on 2004-01-19 05:52:24:
Logged In: YES 
user_id=7549

ack.. bad code..  I'll fix and repost.

davygrvy added on 2004-01-19 04:19:16:
Logged In: YES 
user_id=7549

This might work:

diff -c -r1.39 tclWinPipe.c
*** tclWinPipe.c24 Dec 2003 04:18:23 -00001.39
--- tclWinPipe.c18 Jan 2004 21:17:24 -0000
***************
*** 2485,2491 ****
      int *statPtr,
      int options)
  {
!     ProcInfo *infoPtr, **prevPtrPtr;
      DWORD flags;
      Tcl_Pid result;
      DWORD ret, exitCode;
--- 2485,2491 ----
      int *statPtr,
      int options)
  {
!     ProcInfo *infoPtr = NULL, **nextPtrPtr;
      DWORD flags;
      Tcl_Pid result;
      DWORD ret, exitCode;
***************
*** 2506,2515 ****
       */
  
      Tcl_MutexLock(&pipeMutex);
!     prevPtrPtr = &procList;
!     for (infoPtr = procList; infoPtr != NULL;
!     prevPtrPtr = &infoPtr->nextPtr, infoPtr = infoPtr-
>nextPtr) {
!  if (infoPtr->hProcess == (HANDLE) pid) {
      break;
  }
      }
--- 2506,2516 ----
       */
  
      Tcl_MutexLock(&pipeMutex);
!     for (nextPtrPtr = &procList; (*nextPtrPtr) != NULL;
!     nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
! if (((*nextPtrPtr)->nextPtr)->hProcess == (HANDLE) 
pid) {
!     infoPtr = (*nextPtrPtr)->nextPtr;
!     *nextPtrPtr = infoPtr->nextPtr;
      break;
  }
      }
***************
*** 2539,2544 ****
--- 2540,2552 ----
      if (ret == WAIT_TIMEOUT) {
  *statPtr = 0;
  if (options & WNOHANG) {
+     /*
+      * Reinsert this ProcInfo* back on the linkedlist.
+      */
+     Tcl_MutexLock(&pipeMutex);
+     infoPtr->nextPtr = procList;
+     procList = infoPtr;
+     Tcl_MutexUnlock(&pipeMutex);
      return 0;
  } else {
      result = 0;
***************
*** 2605,2611 ****
       */
  
      CloseHandle(infoPtr->hProcess);
-     *prevPtrPtr = infoPtr->nextPtr;
      ckfree((char*)infoPtr);
  
      return result;
--- 2613,2618 ----

davygrvy added on 2004-01-19 03:42:13:
Logged In: YES 
user_id=7549

infoPtr is in some sort of uninitialized state.  It looks like the 
problem might be in Tcl_WaitPid at the end of the function.  
During the mutex protected search, prevPtrPtr was valid at 
that moment in time.  But after the wait to get the exit code, 
is it still valid?  I don't think so.

What we could do is splice this ProcInfo off prior to the wait 
and during the list lock, then reinsert for when the wait 
timedout.

yahalom, could you attach a script that reproduces this if 
possible.

yahalom added on 2004-01-18 20:42:12:
Logged In: YES 
user_id=130120

with symbols I get the exception in tclWinPipe.c
line : if (infoPtr->hProcess == (HANDLE) pid) {

the code:
unsigned long
TclpGetPid(
    Tcl_Pid pid)/* The HANDLE of the child 
process. */
{
    ProcInfo *infoPtr;

    Tcl_MutexLock(&pipeMutex);
    for (infoPtr = procList; infoPtr != NULL; infoPtr = infoPtr-
>nextPtr) {
if (infoPtr->hProcess == (HANDLE) pid) {
    Tcl_MutexUnlock(&pipeMutex);
    return infoPtr->dwProcessId;
}
    }
    Tcl_MutexUnlock(&pipeMutex);
    return (unsigned long) -1;
}

is there more info needed.

davygrvy added on 2004-01-18 15:34:46:
Logged In: YES 
user_id=7549

Could you build for symbols and reproduce it?  The position of 
the crash with a symbols build can get us to where that is in 
the code itself.

yahalom added on 2004-01-18 14:11:31:
Logged In: YES 
user_id=130120

I do not use thread::transfer in my app.
two different threads are opening/closing a pipe to the same 
program. there should be no problem with this but there is a 
crash.

davygrvy added on 2004-01-15 16:25:58:
Logged In: YES 
user_id=7549

If so, a patch can be found here:
https://sourceforge.net/tracker/index.php?
func=detail&aid=875701&group_id=10894&atid=310894

davygrvy added on 2004-01-15 16:01:23:
Logged In: YES 
user_id=7549

> is the open/close pipe not thread safe?

Are you using thread::transfer?  pipe channels do not support 
cut/splice operations yet.

Attachments: