Commit fe0f8a15 authored by Nikolay Sivov's avatar Nikolay Sivov Committed by Alexandre Julliard

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

parent 10bbe111
...@@ -402,7 +402,8 @@ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit ) ...@@ -402,7 +402,8 @@ void WINAPI MakeCriticalSectionGlobal( CRITICAL_SECTION *crit )
HANDLE sem = crit->LockSemaphore; HANDLE sem = crit->LockSemaphore;
if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 ); if (!sem) NtCreateSemaphore( &sem, SEMAPHORE_ALL_ACCESS, NULL, 0, 1 );
crit->LockSemaphore = ConvertToGlobalHandle( sem ); crit->LockSemaphore = ConvertToGlobalHandle( sem );
RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo ); if (crit->DebugInfo != (void *)(ULONG_PTR)-1)
RtlFreeHeap( GetProcessHeap(), 0, crit->DebugInfo );
crit->DebugInfo = NULL; crit->DebugInfo = NULL;
} }
......
...@@ -2648,6 +2648,7 @@ static void test_crit_section(void) ...@@ -2648,6 +2648,7 @@ static void test_crit_section(void)
InitializeCriticalSection(&cs); InitializeCriticalSection(&cs);
ok(cs.DebugInfo != NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo); ok(cs.DebugInfo != NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
DeleteCriticalSection(&cs); DeleteCriticalSection(&cs);
ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
if (!pInitializeCriticalSectionEx) if (!pInitializeCriticalSectionEx)
{ {
...@@ -2658,9 +2659,20 @@ static void test_crit_section(void) ...@@ -2658,9 +2659,20 @@ static void test_crit_section(void)
memset(&cs, 0, sizeof(cs)); memset(&cs, 0, sizeof(cs));
ret = pInitializeCriticalSectionEx(&cs, 0, CRITICAL_SECTION_NO_DEBUG_INFO); ret = pInitializeCriticalSectionEx(&cs, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
ok(ret, "Failed to initialize critical section.\n"); 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); 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); DeleteCriticalSection(&cs);
ok(cs.DebugInfo == NULL, "Unexpected debug info pointer %p.\n", cs.DebugInfo);
} }
START_TEST(sync) START_TEST(sync)
......
...@@ -59,6 +59,13 @@ static inline void small_pause(void) ...@@ -59,6 +59,13 @@ static inline void small_pause(void)
#endif #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__ #ifdef __linux__
static int wait_op = 128; /*FUTEX_WAIT|FUTEX_PRIVATE_FLAG*/ 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 ) ...@@ -226,7 +233,7 @@ static inline NTSTATUS wait_semaphore( RTL_CRITICAL_SECTION *crit, int timeout )
NTSTATUS ret; NTSTATUS ret;
/* debug info is cleared by MakeCriticalSectionGlobal */ /* 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 ); HANDLE sem = get_semaphore( crit );
LARGE_INTEGER time; LARGE_INTEGER time;
...@@ -321,20 +328,21 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULON ...@@ -321,20 +328,21 @@ NTSTATUS WINAPI RtlInitializeCriticalSectionEx( RTL_CRITICAL_SECTION *crit, ULON
* so (e.g.) MakeCriticalSectionGlobal() doesn't free it using HeapFree(). * so (e.g.) MakeCriticalSectionGlobal() doesn't free it using HeapFree().
*/ */
if (flags & RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO) if (flags & RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO)
crit->DebugInfo = NULL; crit->DebugInfo = no_debug_info_marker;
else else
crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
if (crit->DebugInfo)
{ {
crit->DebugInfo->Type = 0; crit->DebugInfo = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_CRITICAL_SECTION_DEBUG));
crit->DebugInfo->CreatorBackTraceIndex = 0; if (crit->DebugInfo)
crit->DebugInfo->CriticalSection = crit; {
crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList); crit->DebugInfo->Type = 0;
crit->DebugInfo->ProcessLocksList.Flink = &(crit->DebugInfo->ProcessLocksList); crit->DebugInfo->CreatorBackTraceIndex = 0;
crit->DebugInfo->EntryCount = 0; crit->DebugInfo->CriticalSection = crit;
crit->DebugInfo->ContentionCount = 0; crit->DebugInfo->ProcessLocksList.Blink = &(crit->DebugInfo->ProcessLocksList);
memset( crit->DebugInfo->Spare, 0, sizeof(crit->DebugInfo->Spare) ); 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->LockCount = -1;
crit->RecursionCount = 0; crit->RecursionCount = 0;
...@@ -396,7 +404,7 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit ) ...@@ -396,7 +404,7 @@ NTSTATUS WINAPI RtlDeleteCriticalSection( RTL_CRITICAL_SECTION *crit )
crit->LockCount = -1; crit->LockCount = -1;
crit->RecursionCount = 0; crit->RecursionCount = 0;
crit->OwningThread = 0; crit->OwningThread = 0;
if (crit->DebugInfo) if (crit_section_has_debuginfo( crit ))
{ {
/* only free the ones we made in here */ /* only free the ones we made in here */
if (!crit->DebugInfo->Spare[0]) if (!crit->DebugInfo->Spare[0])
...@@ -454,7 +462,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) ...@@ -454,7 +462,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
if ( status == STATUS_TIMEOUT ) if ( status == STATUS_TIMEOUT )
{ {
const char *name = NULL; 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 = "?"; if (!name) name = "?";
ERR( "section %p %s wait timed out in thread %04x, blocked by %04x, retrying (60 sec)\n", 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) ); crit, debugstr_a(name), GetCurrentThreadId(), HandleToULong(crit->OwningThread) );
...@@ -472,7 +480,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) ...@@ -472,7 +480,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
if (status == STATUS_WAIT_0) break; if (status == STATUS_WAIT_0) break;
/* Throw exception only for Wine internal locks */ /* 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 */ /* only throw deadlock exception if configured timeout is reached */
if (timeout > 0) continue; if (timeout > 0) continue;
...@@ -485,7 +493,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit ) ...@@ -485,7 +493,7 @@ NTSTATUS WINAPI RtlpWaitForCriticalSection( RTL_CRITICAL_SECTION *crit )
rec.ExceptionInformation[0] = (ULONG_PTR)crit; rec.ExceptionInformation[0] = (ULONG_PTR)crit;
RtlRaiseException( &rec ); RtlRaiseException( &rec );
} }
if (crit->DebugInfo) crit->DebugInfo->ContentionCount++; if (crit_section_has_debuginfo( crit )) crit->DebugInfo->ContentionCount++;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
...@@ -518,7 +526,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit ) ...@@ -518,7 +526,7 @@ NTSTATUS WINAPI RtlpUnWaitCriticalSection( RTL_CRITICAL_SECTION *crit )
NTSTATUS ret; NTSTATUS ret;
/* debug info is cleared by MakeCriticalSectionGlobal */ /* 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 ); HANDLE sem = get_semaphore( crit );
ret = NtReleaseSemaphore( sem, 1, NULL ); ret = NtReleaseSemaphore( sem, 1, NULL );
......
...@@ -3152,7 +3152,6 @@ static void test_RtlInitializeCriticalSectionEx(void) ...@@ -3152,7 +3152,6 @@ static void test_RtlInitializeCriticalSectionEx(void)
memset(&cs, 0x11, sizeof(cs)); memset(&cs, 0x11, sizeof(cs));
pRtlInitializeCriticalSectionEx(&cs, 0, RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO); 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.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.LockCount == -1, "expected LockCount == -1, got %d\n", cs.LockCount);
ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount); ok(cs.RecursionCount == 0, "expected RecursionCount == 0, got %d\n", cs.RecursionCount);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment