Misc AIX/PASE tweaks (mono/mono#15651)
authorCalvin Buckley <calvin@cmpct.info>
Thu, 11 Jul 2019 16:42:47 +0000 (13:42 -0300)
committerZoltan Varga <vargaz@gmail.com>
Thu, 11 Jul 2019 16:42:47 +0000 (12:42 -0400)
* Partial enablement of alternate stack for AIX/i

It turns out much like macOS, AIX doesn't like to do mprotect/valloc
for the first thread's guard pages, so skip those. It seems mostly
fine except for one or two crashes causes it to grab the wrong IAR
and deadlock dumping memory. As such, leave the code and configure
script override to disable in place, just change the comment and
add support code.

* Use Qp2getifaddrs on PASE

Not sure if proper way to implement. Reuses getifaddrs code as much
as possible, since it's merely a name change based on the docs, due
to it being namespaced in case AIX gets it or something.

I'm not sure how many of these codepaths still work properly;
one had a questionable order of ifdef.

This will eventually prepare for CoreFX NetworkInterface, so test
it here.

Commit migrated from https://github.com/mono/mono/commit/41469ee55a6db885c1b46c29c454e503c0965f21

src/mono/configure.ac
src/mono/mono/metadata/w32socket.c
src/mono/mono/mini/mini-exceptions.c
src/mono/mono/utils/mono-threads-aix.c
src/mono/mono/utils/networking-posix.c

index b2e2875..58093b2 100644 (file)
@@ -525,7 +525,9 @@ case "$host" in
                with_gc=sgen
                need_link_unlink=yes
                use_sigposix=yes
-               dnl the valloc call to alloc the guard page bombs out, even with extending the data area
+               dnl Similar limitation to macOS about the first thread and the
+               dnl guard page, except sometimes the runtime hangs. Disable for
+               dnl now until cause can be determined or it seems OK enough.
                with_sigaltstack=no
                dnl use pthread TLS, __thread has issues with the compiler flags we use
                with_tls=pthread
@@ -3338,6 +3340,7 @@ if test x$host_win32 = xno; then
        AC_CHECK_DECL(F_DUPFD_CLOEXEC,   [AC_DEFINE(HAVE_F_DUPFD_CLOEXEC, 1, [F_DUPFD_CLOEXEC])], [], [[#include <fcntl.h>]])
 
        # AC_CHECK_FUNC(getifaddrs,           [AC_DEFINE(HAVE_GETIFADDRS, 1, [getifaddrs])]) # already done above
+       AC_CHECK_FUNC(Qp2getifaddrs,     [AC_DEFINE(HAVE_QP2GETIFADDRS, 1, [Qp2getifaddrs])])
 
        AC_CHECK_FUNC(lseek64,           [AC_DEFINE(HAVE_LSEEK64, 1, [lseek64])])
        AC_CHECK_FUNC(mmap64,            [AC_DEFINE(HAVE_MMAP64, 1, [mmap64])])
index 2aae810..16e6f4f 100644 (file)
 #ifdef HAVE_GETIFADDRS
 // <net/if.h> must be included before <ifaddrs.h>
 #include <ifaddrs.h>
+#elif defined(HAVE_QP2GETIFADDRS)
+/* Bizarrely, IBM i implements this, but AIX doesn't, so on i, it has a different name... */
+#include <as400_types.h>
+#include <as400_protos.h>
+/* Defines to just reuse ifaddrs code */
+#define ifaddrs ifaddrs_pase
+#define freeifaddrs Qp2freeifaddrs
+#define getifaddrs Qp2getifaddrs
 #endif
 
 #if defined(_MSC_VER) && G_HAVE_API_SUPPORT(HAVE_CLASSIC_WINAPI_SUPPORT | HAVE_UWP_WINAPI_SUPPORT)
@@ -1970,7 +1978,7 @@ ipaddress_handle_to_struct_in6_addr (MonoObjectHandle ipaddr)
 static int
 get_local_interface_id (int family)
 {
-#if !defined(HAVE_GETIFADDRS) || !defined(HAVE_IF_NAMETOINDEX)
+#if !(defined(HAVE_GETIFADDRS) || defined(HAVE_QP2GETIFADDRS)) || !defined(HAVE_IF_NAMETOINDEX)
        return 0;
 #else
        struct ifaddrs *ifap = NULL, *ptr;
index 4ded14f..e00edba 100644 (file)
@@ -3046,10 +3046,14 @@ mono_setup_altstack (MonoJitTlsData *tls)
        size_t stsize = 0;
        stack_t sa;
        guint8 *staddr = NULL;
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(_AIX)
        /*
         * On macOS Mojave we are encountering a bug when changing mapping for main thread
         * stack pages. Stack overflow on main thread will kill the app.
+        *
+        * AIX seems problematic as well; it gives ENOMEM for mprotect and valloc, if we
+        * do this for thread 1 with its stack at the top of memory. Other threads seem
+        * fine for the altstack guard page, though.
         */
        gboolean disable_stack_guard = mono_threads_platform_is_main_thread ();
 #else
index 538f4d8..17a4878 100644 (file)
@@ -38,4 +38,11 @@ mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize)
        *stsize = pi.__pi_stackend - pi.__pi_stackaddr;
 }
 
+gboolean
+mono_threads_platform_is_main_thread (void)
+{
+       /* returns 1 on main thread, even if the kernel tid is diff */
+       return pthread_self () == 1;
+}
+
 #endif
index 0736e8a..5988932 100644 (file)
 #ifdef HAVE_GETIFADDRS
 #include <ifaddrs.h>
 #endif
+#ifdef HAVE_QP2GETIFADDRS
+/* Bizarrely, IBM i implements this, but AIX doesn't, so on i, it has a different name... */
+#include <as400_types.h>
+#include <as400_protos.h>
+/* Defines to just reuse ifaddrs code */
+#define ifaddrs ifaddrs_pase
+#define freeifaddrs Qp2freeifaddrs
+#define getifaddrs Qp2getifaddrs
+#endif
 
 #include <mono/utils/networking.h>
 #include <mono/utils/mono-threads-coop.h>
@@ -280,7 +289,7 @@ done:
        return result;
 }
 
-#elif defined(HAVE_GETIFADDRS)
+#elif defined(HAVE_GETIFADDRS) || defined(HAVE_QP2GETIFADDRS)
 
 void *
 mono_get_local_interfaces (int family, int *interface_count)