From: Rodrigo Kumpera Date: Mon, 16 Nov 2015 05:22:56 +0000 (-0500) Subject: [android] Add fallback for thread bounds calculation for Android. X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=2a7be75dfb7a1d2afb9ef3e9780398fb52ede841;p=mono.git [android] Add fallback for thread bounds calculation for Android. On some junk Samsung x86 device, pthread_attr_getstack is completely broken. If the returned value is not sane, we parse /proc/self/maps to find the right memory regions for the current stack. Fixes BXC #21550 and DESK #83333. List of original contributors: Rodrigo Kumpera --- diff --git a/mono/utils/mono-threads-android.c b/mono/utils/mono-threads-android.c index a72ee81a560..fa82387f26f 100644 --- a/mono/utils/mono-threads-android.c +++ b/mono/utils/mono-threads-android.c @@ -2,8 +2,55 @@ #if defined(PLATFORM_ANDROID) -#ifdef ENABLE_EXTENSION_MODULE -#include "../../../mono-extensions/mono/utils/mono-threads-android.c" -#endif +#include +#include +#include +#include "glib.h" + +static void +slow_get_thread_bounds (guint8 *current, guint8 **staddr, size_t *stsize) +{ + char buff [1024]; + FILE *f = fopen ("/proc/self/maps", "r"); + if (!f) + g_error ("Could not determine thread bounds, failed to open /proc/self/maps"); + + while (fgets (buff, sizeof (buff), f)) { + intmax_t low, high; + char *ptr = buff; + char *end = NULL; + //each line starts with the range we want: f7648000-f7709000 + low = strtoimax (ptr, &end, 16); + if (end) { + ptr = end + 1; //skip the dash to make sure we don't get a negative number + end = NULL; + high = strtoimax (ptr, &end, 16); + } + if (end && low <= (intmax_t)(size_t)current && high > (intmax_t)(size_t)current) { + *staddr = (guint8 *)(size_t)low; + *stsize = (size_t)(high - low); + fclose (f); + return; + } + } + g_error ("Could not determine thread bounds, failed to find current stack pointer in /proc/self/maps"); +} + +void +mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize) +{ + pthread_attr_t attr; + guint8 *current = (guint8*)&attr; + + *staddr = NULL; + *stsize = (size_t)-1; + + pthread_getattr_np (pthread_self (), &attr); + pthread_attr_getstack (&attr, (void**)staddr, stsize); + pthread_attr_destroy (&attr); + + if (*staddr && ((current <= *staddr) || (current > *staddr + *stsize))) + slow_get_thread_bounds (current, staddr, stsize); +} #endif