From 41469ee55a6db885c1b46c29c454e503c0965f21 Mon Sep 17 00:00:00 2001 From: Calvin Buckley Date: Thu, 11 Jul 2019 13:42:47 -0300 Subject: [PATCH] Misc AIX/PASE tweaks (#15651) * 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. --- configure.ac | 5 ++++- mono/metadata/w32socket.c | 10 +++++++++- mono/mini/mini-exceptions.c | 6 +++++- mono/utils/mono-threads-aix.c | 7 +++++++ mono/utils/networking-posix.c | 11 ++++++++++- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index b2e2875d09b..58093b21750 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ]]) # 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])]) diff --git a/mono/metadata/w32socket.c b/mono/metadata/w32socket.c index 2aae8102ed5..16e6f4fb1ce 100644 --- a/mono/metadata/w32socket.c +++ b/mono/metadata/w32socket.c @@ -97,6 +97,14 @@ #ifdef HAVE_GETIFADDRS // must be included before #include +#elif defined(HAVE_QP2GETIFADDRS) +/* Bizarrely, IBM i implements this, but AIX doesn't, so on i, it has a different name... */ +#include +#include +/* 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; diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 4ded14fc469..e00edba727e 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -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 diff --git a/mono/utils/mono-threads-aix.c b/mono/utils/mono-threads-aix.c index 538f4d895fb..17a48788c3e 100644 --- a/mono/utils/mono-threads-aix.c +++ b/mono/utils/mono-threads-aix.c @@ -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 diff --git a/mono/utils/networking-posix.c b/mono/utils/networking-posix.c index 0736e8a5a3d..59889328372 100644 --- a/mono/utils/networking-posix.c +++ b/mono/utils/networking-posix.c @@ -29,6 +29,15 @@ #ifdef HAVE_GETIFADDRS #include #endif +#ifdef HAVE_QP2GETIFADDRS +/* Bizarrely, IBM i implements this, but AIX doesn't, so on i, it has a different name... */ +#include +#include +/* Defines to just reuse ifaddrs code */ +#define ifaddrs ifaddrs_pase +#define freeifaddrs Qp2freeifaddrs +#define getifaddrs Qp2getifaddrs +#endif #include #include @@ -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) -- 2.11.4.GIT