[PATCH 2/2] ntdll: Retry creating thread stack in higher address space.

Rémi Bernon rbernon at codeweavers.com
Fri May 7 05:08:05 CDT 2021


When creating it in the lower 2G fails.

This fixes a regression from 789c1db18a4e192425da3771cac4726cda77130b,
which causes several apps to fail when the lower 2G are getting crowded,
or when they have unusually large default thread stack sizes.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/ntdll/tests/virtual.c | 2 +-
 dlls/ntdll/unix/virtual.c  | 7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index 686b4076801..853ff9c27a7 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -570,7 +570,7 @@ static void test_RtlCreateUserStack(void)
     CloseHandle(thread);
 
     thread = CreateThread(NULL, 0x80000000, test_stack_size_dummy_thread, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
-    todo_wine ok(thread != NULL, "CreateThread with huge stack failed\n");
+    ok(thread != NULL, "CreateThread with huge stack failed\n");
     WaitForSingleObject(thread, INFINITE);
     CloseHandle(thread);
 }
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index c3baa5f09c7..e036ebdec86 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -3051,6 +3051,7 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SI
     NTSTATUS status;
     sigset_t sigset;
     SIZE_T size, extra_size = 0;
+    unsigned int vprot = VPROT_READ | VPROT_WRITE | VPROT_COMMITTED;
 
     if (!reserve_size) reserve_size = main_image_info.MaximumStackSize;
     if (!commit_size) commit_size = main_image_info.CommittedStackSize;
@@ -3062,9 +3063,9 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SI
 
     server_enter_uninterrupted_section( &virtual_mutex, &sigset );
 
-    if ((status = map_view( &view, NULL, size + extra_size, FALSE,
-                            VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, 33 )) != STATUS_SUCCESS)
-        goto done;
+    status = map_view( &view, NULL, size + extra_size, FALSE, vprot, 33 );
+    if (status == STATUS_NO_MEMORY) status = map_view( &view, NULL, size + extra_size, FALSE, vprot, 0 );
+    if (status != STATUS_SUCCESS) goto done;
 
 #ifdef VALGRIND_STACK_REGISTER
     VALGRIND_STACK_REGISTER( view->base, (char *)view->base + view->size );
-- 
2.31.0




More information about the wine-devel mailing list