Nikolay Sivov : ntdll: Initialize critical section debug info with correct pointer value.

Alexandre Julliard julliard at winehq.org
Mon Nov 25 09:12:22 CST 2019


Module: wine
Branch: stable
Commit: d10f213840b3761920cc996bf62f00fa21884e5d
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=d10f213840b3761920cc996bf62f00fa21884e5d

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Tue Apr 30 13:19:22 2019 +0300

ntdll: Initialize critical section debug info with correct pointer value.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit fe0f8a150fdaaf71052ab50597207086cf5f4b4a)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>

---

 dlls/kernel32/sync.c       |  3 ++-
 dlls/kernel32/tests/sync.c | 14 +++++++++++++-
 dlls/ntdll/critsection.c   | 44 ++++++++++++++++++++++++++------------------
 dlls/ntdll/tests/rtl.c     |  1 -
 4 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index 6d47d7004c..9f5b614508 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -402,7 +402,8 @@ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
     HANDLE sem = crit->LockSemaphore;
     if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
     crit->LockSemaphore = ConvertToGlobalHandle( sem );
-    RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
+    if (crit->DebugInfo != (void *)(ULONG_PTR)-1)
+        RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
     crit->DebugInfo = NULL;
 }
 
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
index 8dea3b30c3..e77c40a2f6 100644
--- a/dlls/kernel32/tests/sync.c
+++ b/dlls/kernel32/tests/sync.c
@@ -2647,13 +2647,25 @@ static void test_crit_section(void)
     InitializeCriticalSection(&cs);
     ok(cs.DebugInfo != NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
     DeleteCriticalSection(&cs);
+    ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
 
     memset(&cs, 0, sizeof(cs));
     ret = InitializeCriticalSectionEx(&cs, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
     ok(ret, "Failed to initialize critical section.\n");
-todo_wine
     ok(cs.DebugInfo == (void *)(ULONG_PTR)-1, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
+
+    ret = TryEnterCriticalSection(&cs);
+    ok(ret, "Failed to enter critical section.\n");
+    LeaveCriticalSection(&cs);
+
+    cs.DebugInfo = NULL;
+
+    ret = TryEnterCriticalSection(&cs);
+    ok(ret, "Failed to enter critical section.\n");
+    LeaveCriticalSection(&cs);
+
     DeleteCriticalSection(&cs);
+    ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
 }
 
 START_TEST(sync)
diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index 42e432c8f6..e8ffc1ceed 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -59,6 +59,13 @@ static inline void small_pause(void)
 #endif
 }
 
+static void *no_debug_info_marker = (void *)(ULONG_PTR)-1;
+
+static BOOL crit_section_has_debuginfo(const RTL_CRITICAL_SECTION *crit)
+{
+    return crit->DebugInfo != NULL && crit->DebugInfo != no_debug_info_marker;
+}
+
 #ifdef __linux__
 
 static int wait_op = 128; /*FUTEX_WAIT|FUTEX_PRIVATE_FLAG*/
@@ -226,7 +233,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
     NTSTATUS ret;
 
     /* debug info is cleared by MakeCriticalSectionGlobal */
-    if (!crit->DebugInfo || ((ret = fast_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
+    if (!crit_section_has_debuginfo( crit ) || ((ret = fast_wait( crit, timeout )) == STATUS_NOT_IMPLEMENTED))
     {
         HANDLE sem = get_semaphore( crit );
         LARGE_INTEGER time;
@@ -321,20 +328,21 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULON
      * so (e.g.) MakeCriticalSectionGlobal() doesn't free it using HeapFree().
      */
     if (flags & RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO)
-        crit->DebugInfo = NULL;
+        crit->DebugInfo = no_debug_info_marker;
     else
-        crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
-
-    if (crit->DebugInfo)
     {
-        crit->DebugInfo->Type = 0;
-        crit->DebugInfo->CreatorBackTraceIndex = 0;
-        crit->DebugInfo->CriticalSection = crit;
-        crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList);
-        crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList);
-        crit->DebugInfo->EntryCount = 0;
-        crit->DebugInfo->ContentionCount = 0;
-        memset( crit->DebugInfo->Spare, 0, sizeof(crit->DebugInfo->Spare) );
+        crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
+        if (crit->DebugInfo)
+        {
+            crit->DebugInfo->Type = 0;
+            crit->DebugInfo->CreatorBackTraceIndex = 0;
+            crit->DebugInfo->CriticalSection = crit;
+            crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList);
+            crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList);
+            crit->DebugInfo->EntryCount = 0;
+            crit->DebugInfo->ContentionCount = 0;
+            memset( crit->DebugInfo->Spare, 0, sizeof(crit->DebugInfo->Spare) );
+        }
     }
     crit->LockCount      = -1;
     crit->RecursionCount = 0;
@@ -396,7 +404,7 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
     crit->LockCount      = -1;
     crit->RecursionCount = 0;
     crit->OwningThread   = 0;
-    if (crit->DebugInfo)
+    if (crit_section_has_debuginfo( crit ))
     {
         /* only free the ones we made in here */
         if (!crit->DebugInfo->Spare[0])
@@ -454,7 +462,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
         if ( status == STATUS_TIMEOUT )
         {
             const char *name = NULL;
-            if (crit->DebugInfo) name = (char *)crit->DebugInfo->Spare[0];
+            if (crit_section_has_debuginfo( crit )) name = (char *)crit->DebugInfo->Spare[0];
             if (!name) name = "?";
             ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n",
                  crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
@@ -472,7 +480,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
         if (status == STATUS_WAIT_0) break;
 
         /* Throw exception only for Wine internal locks */
-        if ((!crit->DebugInfo) || (!crit->DebugInfo->Spare[0])) continue;
+        if (!crit_section_has_debuginfo( crit ) || !crit->DebugInfo->Spare[0]) continue;
 
         /* only throw deadlock exception if configured timeout is reached */
         if (timeout > 0) continue;
@@ -485,7 +493,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
         rec.ExceptionInformation[0] = (ULONG_PTR)crit;
         RtlRaiseException( &rec );
     }
-    if (crit->DebugInfo) crit->DebugInfo->ContentionCount++;
+    if (crit_section_has_debuginfo( crit )) crit->DebugInfo->ContentionCount++;
     return STATUS_SUCCESS;
 }
 
@@ -518,7 +526,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
     NTSTATUS ret;
 
     /* debug info is cleared by MakeCriticalSectionGlobal */
-    if (!crit->DebugInfo || ((ret = fast_wake( crit )) == STATUS_NOT_IMPLEMENTED))
+    if (!crit_section_has_debuginfo( crit ) || ((ret = fast_wake( crit )) == STATUS_NOT_IMPLEMENTED))
     {
         HANDLE sem = get_semaphore( crit );
         ret = NtReleaseSemaphore( sem, 1, NULL );
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 5fe72ec38b..62662cb438 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -3152,7 +3152,6 @@ static void test_RtlInitializeCriticalSectionEx(void)
 
     memset(&cs, 0x11, sizeof(cs));
     pRtlInitializeCriticalSectionEx(&cs, 0, RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO);
-    todo_wine
     ok(cs.DebugInfo == no_debug, "expected DebugInfo == ~0, got %p\n", cs.DebugInfo);
     ok(cs.LockCount == -1, "expected LockCount == -1, got %d\n", cs.LockCount);
     ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount);




More information about the wine-cvs mailing list