You can replace malloc with your own implementation, but it has to be a
*working* implementation. Early in the per-process DLL initialization
there's a call to free(malloc(16)), which is used to figure out if
Cygwin's malloc has been overridden with an application-supplied version
of malloc. Since your malloc calls exit, this goes down the gutter. At
this early stage in initialization, Cygwin can't handle the exit call
correctly.
Unless we can implement a way to figure out if the application provides
malloc without actually calling malloc, the above testcases are bound to
fail.