Bug #2488

thread usage can result in bad HANDLE

Added by rogerdpack (Roger Pack) over 2 years ago. Updated about 1 year ago.

[ruby-core:27199]
Status:Closed Start date:12/17/2009
Priority:Normal Due date:
Assignee:ko1 (Koichi Sasada) % Done:

100%

Category:core
Target version:2.0.0
ruby -v:ruby 1.9.2dev (2009-12-31 trunk 26205) [i386-mswin32]

Description

require 'thwait'
loop {
 a = []
 10.times { a << Thread.new {}}
 ThreadsWait.all_waits(a)
 print '.'
}


C:\dev\digitalarchive_trunk>ruby -v
ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-mingw32]

C:\dev\digitalarchive_trunk>ruby stress_th.rb
.............[BUG] The handle is invalid.

ruby 1.9.1p376 (2009-12-07 revision 26041) [i386-mingw32]

-- control frame ----------
---------------------------
-- Ruby level backtrace information-----------------------------------------

[NOTE]
You may encounter a bug of Ruby interpreter. Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Works fine with 1.9.2

Thanks.
-r

lock_before_reset.patch (1.2 kB) wanabe (_ wanabe), 05/01/2010 09:24 pm


Related issues

related to Archive91 - Bug #3183: "[BUG] The handle is invalid." when working with Threads Closed 04/22/2010

Associated revisions

Revision 26207
Added by usa (Usaku NAKAMURA) over 2 years ago

* thread_win32.c (native_thread_destroy): decreased the probability of using the interrupt event in the thread termination. see [ruby-core:27199].

Revision 27630
Added by wanabe (_ wanabe) about 2 years ago

* thread_win32.c (w32_wait_events): get GVL before handle interrupt event. [ruby-core:27199], [ruby-core:29698]

History

Updated by usa (Usaku NAKAMURA) over 2 years ago

  • Assignee set to usa (Usaku NAKAMURA)
  • Target version set to 2.0.0
can reproduce with trunk.

Updated by usa (Usaku NAKAMURA) over 2 years ago

  • Status changed from Open to Assigned
  • ruby -v set to ruby 1.9.2dev (2009-12-31 trunk 26205) [i386-mswin32]

Updated by usa (Usaku NAKAMURA) over 2 years ago

  • Category set to core
  • Assignee changed from usa (Usaku NAKAMURA) to ko1 (Koichi Sasada)

Updated by rogerdpack (Roger Pack) about 2 years ago

appears "better" in trunk but not totally fixed, with this version:

ruby 1.9.2dev (2010-04-09 trunk 27265) [i386-mingw32]

Updated by rogerdpack (Roger Pack) about 2 years ago

from 3183 this code crashes trunk reliably still:

loop {
 all = []
 700.times{|i|
  all << Thread.new{}
   puts i
 }
 all.each(&:join)
}

Updated by luislavena (Luis Lavena) about 2 years ago

Roger,

Running r27453 over here, cannot make your example crash (based on bug report #3183).

OS: Windows 7, x64, 4GB RAM

Updated by wanabe (_ wanabe) about 2 years ago

Roger,
Does this patch fix the issue?

Developers (especially Koichi),
Is this solution right?
(Using GVL, timing of lock, condition, etc.)

Updated by rogerdpack (Roger Pack) about 2 years ago

That patch seems to fix it for me.

@Luis: I am able to reproduce #3183 (sometimes it takes a few minutes, and requires the puts in there).  Ex backtrace:

[BUG] w32_reset_event: The handle is invalid.

ruby 1.9.2dev (2010-05-05 trunk 27620) [i386-mingw32]

-- control frame ----------
---------------------------

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

(Windows 7 32 bit, 4GB RAM).  I assume it's just a timing issue.

-rp

Updated by usa (Usaku NAKAMURA) about 2 years ago

Hello,

In message "[ruby-core:30005] [Bug #2488] thread usage can result in bad HANDLE"
    on May.05,2010 06:35:12, <redmine@ruby-lang.org> wrote:
| (Windows 7 32 bit, 4GB RAM).  I assume it's just a timing issue.

I think so, too.
wanabe-san, please check in the patch and close #2488 and #3183.


Regards
-- 
U.Nakamura <usa@garbagecollect.jp>

Updated by wanabe (_ wanabe) about 2 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100
This issue was solved with changeset r27630.
Roger, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

Updated by wanabe (_ wanabe) about 2 years ago

Hello,

2010/5/6, Caleb Clausen <vikkous@gmail.com>:
> I don't understand win32 programming that well...

Me too.

> Why is it necessary to re-check that intr is set to what it was set to
> just two lines before? I assume it might be changed by the action of
> another thread, but if that's the case, wouldn't it be better to just
> check that field once while inside the global_vm_lock? (ie move the
> lock/unlock to be around the whole if statement.)

Yes, you are right.
I think first that it is good to avoid native_mutex_lock() as much as possible.
Now, I realize the condition (th && !intr) is fulfilled in a only few moments.

But if we delete check of outside, new check of mutex's existence will
be needed.
I'm afraid that it doesn't make sense from the standpoint of cost down.

> For that matter, shouldn't ruby be using the api provided by windows
> (WaitForSingleObject, apparently) to check the state of this 'event
> object' (really a semaphore)? If you do it that way, then maybe the
> global_vm_lock doesn't need to be touched.

I guess it is not very good idea.
Because th->native_thread_data.interrupt_event can be destroyed
by native_thread_destroy() between check and lock, but GVL can't.

And if ruby use  'event object', we should insert locking to somewhere
such as thread_cleanup_func(), but lock with GVL is in thread_start_func_2()
already. There is not a new cost.

But if you know the use case the lock can be harm, I'm glad to change it.

-- 
wanabe

Also available in: Atom PDF