Timer crashes and wineserver hangs

Mike McCormack mike at codeweavers.com
Mon Sep 6 10:06:27 CDT 2004


Hi All,

The following patch adds a test program that various crashes Wine or 
hangs the wineserver, depending on whether you apply the fix to 
RtlEnlargedUnsignedDivide() or not.

Problem 1)
The piece of assembly language in RtlEnlargedUnsignedDivide() is borked 
and doesn't produce the same results as the C code.  I vote that we get 
rid of the assembly completely, and let gcc produce the code.  Patch 
attached.

Problem 2)
The wineserver goes into a busy loop continually adding the expired 
timer back into the wait list. Backtrace below.

add_timeout_user (when=0x80e5550, func=0x80669a0 <timer_callback>,
     private=0x80e5528) at fd.c:193
193         user->when     = *when;
(gdb) bt
#0  add_timeout_user (when=0x80e5550, func=0x80669a0 <timer_callback>,
     private=0x80e5528) at fd.c:193
#1  0x080669f6 in timer_callback (private=0x80e5528) at timer.c:108
#2  0x0804fde4 in main_loop () at fd.c:252
#3  0x080541bf in main (argc=1, argv=0xbffff784) at main.c:133
#4  0x40144d06 in __libc_start_main () from /lib/libc.so.6
(gdb) quit

/me avoids writing a patch to solve the second problem until Alexandre 
suggests a fix

Mike


ChangeLog:
* add a test for timers
* remove bad asm code from RtlEnlargedUnsignedDivide()

-------------- next part --------------
Index: dlls/kernel/tests/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/kernel/tests/Makefile.in,v
retrieving revision 1.16
diff -u -r1.16 Makefile.in
--- dlls/kernel/tests/Makefile.in	19 May 2004 03:22:56 -0000	1.16
+++ dlls/kernel/tests/Makefile.in	6 Sep 2004 13:29:04 -0000
@@ -28,6 +28,7 @@
 	profile.c \
 	thread.c \
 	time.c \
+	timer.c \
 	virtual.c
 
 @MAKE_TEST_RULES@
--- /dev/null	1994-07-18 08:46:18.000000000 +0900
+++ dlls/kernel/tests/timer.c	2004-09-06 23:18:34.000000000 +0900
@@ -0,0 +1,69 @@
+/*
+ * Unit test suite for time functions
+ *
+ * Copyright 2004 Mike McCormack
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "wine/test.h"
+#include "winbase.h"
+
+typedef HANDLE (WINAPI *fnCreateWaitableTimerA)( SECURITY_ATTRIBUTES*, BOOL, LPSTR );
+typedef BOOL (WINAPI *fnSetWaitableTimer)(HANDLE, LARGE_INTEGER*, LONG, PTIMERAPCROUTINE, LPVOID, BOOL);
+
+
+void test_timer(void)
+{
+    HMODULE hker = GetModuleHandle("kernel32");
+    fnCreateWaitableTimerA pCreateWaitableTimerA;
+    fnSetWaitableTimer pSetWaitableTimer;
+    HANDLE handle;
+    BOOL r;
+    LARGE_INTEGER due;
+
+    pCreateWaitableTimerA = (fnCreateWaitableTimerA) GetProcAddress( hker, "CreateWaitableTimerA");
+    if( !pCreateWaitableTimerA )
+        return;
+
+    pSetWaitableTimer = (fnSetWaitableTimer) GetProcAddress( hker, "SetWaitableTimer");
+    if( !pSetWaitableTimer )
+        return;
+       
+    /* try once with a positive number */
+    handle = pCreateWaitableTimerA( NULL, 0, NULL );
+    ok( handle != NULL, "failed to create waitable timer with no name\n" );
+
+    due.QuadPart = 10000;
+    r = pSetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE ); 
+    ok( r, "failed to set timer\n");
+
+    CloseHandle( handle );
+
+    /* try once with a negative number */
+    handle = pCreateWaitableTimerA( NULL, 0, NULL );
+    ok( handle != NULL, "failed to create waitable timer with no name\n" );
+
+    due.QuadPart = -10000;
+    r = pSetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE ); 
+    ok( r, "failed to set timer\n");
+
+    CloseHandle( handle );
+}
+
+START_TEST(timer)
+{
+    test_timer();
+}
-------------- next part --------------
Index: dlls/ntdll/large_int.c
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/large_int.c,v
retrieving revision 1.11
diff -u -r1.11 large_int.c
--- dlls/ntdll/large_int.c	1 Oct 2003 03:20:21 -0000	1.11
+++ dlls/ntdll/large_int.c	6 Sep 2004 13:29:41 -0000
@@ -254,22 +254,9 @@
  */
 UINT WINAPI RtlEnlargedUnsignedDivide( ULONGLONG a, UINT b, UINT *remptr )
 {
-#if defined(__i386__) && defined(__GNUC__)
-    UINT ret, rem, p1, p2;
-
-    p1 = a >> 32;
-    p2 = a &  0xffffffffLL;
-
-    __asm__("div %4,%%eax"
-            : "=a" (ret), "=d" (rem)
-            : "0" (p2), "1" (p1), "g" (b) );
-    if (remptr) *remptr = rem;
-    return ret;
-#else
     UINT ret = a / b;
     if (remptr) *remptr = a % b;
     return ret;
-#endif
 }
 
 


More information about the wine-patches mailing list