Please help me debug wineserver

Misha Koshelev mk144210 at
Wed Jan 31 11:45:30 CST 2007

I guess I should have replied to the whole list.

On Tue, 2007-01-30 at 11:03 -0800, Dan Kegel wrote:
> Misha wrote:
> > I am new to wine programming but have a fair amount of
> > experience with C/C++ programming in general. I have
> > recently decided to make the Vector NTI application work
> > on Wine, and after overcoming quite a few installation
> > difficulties by making an install shell script,
> Cool.  Can you file a bug about those problems, and attach the
> shell script as a workaround?

> > I have run in to a problem that I have traced down to
> > wineserver. This problem occurs after repeatedly changing
> > folders in the Vector NTI "Open Molecule File" dialog,
> > which does not use the standard open file Windows dialog
> > (e.g., the "Open Shortcut" dialog in the same program works
> > fine). Wineserver crashes with the following error message:
> >
> > wineserver: object.c:274: release_object: Assertion `obj->refcount' failed.
> You also have a bug opened for this,
> I see you also have a possible workaround there.
Have submitted a patch to wine-patches. The problem occurs because
end_wait does not modify thread->wait in any meaningful way until it is 
done processing it, so if a user APC is sent to the same thread that
causes the thread to be woken again from one of the destroy_object 
functions (or anything else that causes the thread to be woken again 
from one of the destroy/release_object functions that end_wait calls),
end_wait will try to process the same thread->wait and will get in
trouble because it is already being processed by the end_wait that
called it. This patch fixes that by saying that a process will not
be woken when it is in the middle of being woken again. If anyone has
comments about the patch, I would appreciate to hear them (I have
attached it here too just in case).

> > On looking at the output of WINEDEBUG=+server, it seems
> > that the "Vector NTI" thread is woken up, and then receives
> > a USER_APC, at which time this crash occurs.
> What version of Wine?  There were recent changes in APC handling
> in wine-0.9.30 (and perhaps 0.9.29) that may have broken this.
> If you can verify that this worked ok in earlier versions like 0.9.27,
> that would help.  Alexandre is the expert on this.  He's on
> vacation but he'll want to take a look when he gets back.
Same behavior on git, 0.9.30, 0.9.29, and 0.9.22.

> - Dan

-------------- next part --------------
From 8c82e30fe5b7547a48de70cb2b111f621c985941 Mon Sep 17 00:00:00 2001
From: Misha Koshelev <mk144210 at>
Date: Wed, 31 Jan 2007 08:44:34 -0600
Subject: wineserver: Make sure while we are waking a thread we do not try to do it again.
 server/thread.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/server/thread.c b/server/thread.c
index b4a16cd..b477364 100644
--- a/server/thread.c
+++ b/server/thread.c
@@ -58,6 +58,8 @@ struct thread_wait
     struct thread          *thread;     /* owner thread */
     int                     count;      /* count of objects */
     int                     flags;
+    int                     waking;     /* whether we are currently waking this
+					 * thread */
     void                   *cookie;     /* magic cookie to return to client */
     struct timeval          timeout;
     struct timeout_user    *user;
@@ -447,6 +449,7 @@ static void end_wait( struct thread *thr
     int i;
     assert( wait );
+    thread->wait->waking = 1;
     for (i = 0, entry = wait->queues; i < wait->count; i++, entry++)
         entry->obj->ops->remove_queue( entry->obj, entry );
     if (wait->user) remove_timeout_user( wait->user );
@@ -467,6 +470,7 @@ static int wait_on( int count, struct ob
     wait->count   = count;
     wait->flags   = flags;
     wait->user    = NULL;
+    wait->waking  = 0;
     current->wait = wait;
     if (flags & SELECT_TIMEOUT)
@@ -495,6 +499,9 @@ static int check_wait( struct thread *th
     struct thread_wait *wait = thread->wait;
     struct wait_queue_entry *entry = wait->queues;
+    /* If we are already waking this thread, no need to wake it again */
+    if (wait->waking) return -1;
     /* Suspended threads may not acquire locks, but they can run system APCs */
     if (thread->process->suspend + thread->suspend > 0)

More information about the wine-devel mailing list