Cygwin: split malloc_init

Cygwin 3.3 only: Replace SRWLOCK usage for malloc synchronization with
the first incarnation of the patch splitting malloc_init into two parts.
The SRWLOCK usage requires TryAcquireSRWLockExclusive, which isn't
available on Vista / Server 2008, unfortunately.

Per https://cygwin.com/pipermail/cygwin-developers/2021-October/012429.html,
we may encounter a crash when starting multiple threads during process
startup (here: fhandler_fifo::fixup_after_{fork,exec}) which in turn
allocate memory via malloc.

The problem is concurrent usage of malloc before the malloc muto has
been initialized.

To fix this issue, split malloc_init into malloc_init_0, called from
dll_crt0_0, and malloc_init_1, called from dll_crt_0_1.  malloc_init_0
just initializes the muto, malloc_init_1 checks for user space provided
malloc.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2021-10-26 18:03:28 +02:00 committed by Corinna Vinschen
parent 462ca33745
commit e528cfe919
6 changed files with 13 additions and 6 deletions

View File

@ -39,6 +39,8 @@ void *mmap64 (void *, size_t, int, int, int, off_t);
# define __malloc_lock() mallock.acquire ()
# define __malloc_unlock() mallock.release ()
extern muto mallock;
inline void malloc_init_0 () { mallock.init ("mallock"); }
extern void malloc_init_1 ();
#endif

View File

@ -29,6 +29,7 @@ details. */
#include "shared_info.h"
#include "cygwin_version.h"
#include "dll_init.h"
#include "cygmalloc.h"
#include "heap.h"
#include "tls_pbuf.h"
#include "exception.h"
@ -769,6 +770,8 @@ dll_crt0_0 ()
NtOpenProcessToken (NtCurrentProcess (), MAXIMUM_ALLOWED, &hProcToken);
set_cygwin_privileges (hProcToken);
malloc_init_0 ();
device::init ();
do_global_ctors (&__CTOR_LIST__, 1);
cygthread::init ();
@ -857,7 +860,7 @@ dll_crt0_1 (void *)
on a functioning malloc and it's possible that the user's program may
have overridden malloc. We only know about that at this stage,
unfortunately. */
malloc_init ();
malloc_init_1 ();
user_shared->initialize ();
#ifdef CYGHEAP_DEBUG

View File

@ -230,7 +230,6 @@ user_heap_info::init ()
debug_printf ("heap base %p, heap top %p, heap size %ly (%lu)",
base, top, chunk, chunk);
page_const--;
// malloc_init ();
}
#define pround(n) (((size_t)(n) + page_const) & ~page_const)

View File

@ -10,7 +10,6 @@ details. */
/* Heap management. */
void heap_init ();
void malloc_init ();
#define inheap(s) \
(cygheap->user_heap.ptr && s \

View File

@ -272,10 +272,8 @@ strdup (const char *s)
muto NO_COPY mallock;
void
malloc_init ()
malloc_init_1 ()
{
mallock.init ("mallock");
/* Check if malloc is provided by application. If so, redirect all
calls to malloc/free/realloc to application provided. This may
happen if some other dll calls cygwin's malloc, but main code provides

View File

@ -0,0 +1,6 @@
Bug Fixes
---------
- Fix a fix in 3.3.0 which broke Vista / Server 2008 by using a Windows
function introduced with Windows 7 only, namely TryAcquireSRWLockExclusive.
Addresses: https://cygwin.com/pipermail/cygwin/2021-October/249732.html