Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Feb 2013 13:50:23 GMT
From:      Jack Pappas <jack.pappas@tidepowerd.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   ports/176030: [PATCH] Bugfixes for mono's 'sgen' GC
Message-ID:  <201302111350.r1BDoNKv083173@red.freebsd.org>
Resent-Message-ID: <201302111400.r1BE00iG015959@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         176030
>Category:       ports
>Synopsis:       [PATCH] Bugfixes for mono's 'sgen' GC
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 11 14:00:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Jack Pappas
>Release:        9.1-STABLE
>Organization:
>Environment:
FreeBSD jack-bsd 9.1-RELEASE FreeBSD 9.1-RELEASE #0 r245748M: Mon Jan 21 20:56:47 EST 2013     root@jack-bsd:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
I recently submitted a patch for lang/mono which was just a small configuration change to enable the new 'sgen' garbage collector. After using the new GC for a while, I noticed that mono sometimes crashed with an assertion -- which turned out to be a bug in 'sgen'. I figured out the bug and submitted fixes to the Mono team for inclusion in the next release (3.0.4).

This patch also includes a small configuration change (along with a new patch file, detailed below) which enables Mono's 'sigaltstack' support on FreeBSD.

This patch includes four (4) new files:
- 'files/patch-mono_metadata_sgen-gc.c' and 'files/patch-mono_metadata_threads.c' contain the fixes for the 'sgen' garbage collector.
- 'files/patch-mono_mini_mini-exceptions.c' contains a fix that allows the 'sigaltstack' option to work correctly on FreeBSD.
- 'files/patch-mcs_tools_gacutil_driver.cs' contains a fix for the Mono 'gacutil' tool. This fix is required for my submitted patch to upgrade lang/fsharp to the latest version -- without this fix, the port can't 'deinstall' properly.

>How-To-Repeat:

>Fix:
Please see the included 'diff'.

Patch attached with submission follows:

Index: files/patch-configure
===================================================================
--- files/patch-configure	(revision 312057)
+++ files/patch-configure	(working copy)
@@ -1,12 +1,11 @@
-
-$FreeBSD$
-
---- configure.orig
-+++ configure
-@@ -3995,10 +3995,6 @@
+--- ./configure.orig	2013-01-08 13:47:51.000000000 -0500
++++ ./configure	2013-02-11 07:52:29.000000000 -0500
+@@ -3993,12 +3993,6 @@
+ 
+ 		libdl=
  		libgc_threads=pthreads
- 		# This doesn't seem to work as of 7.0 on amd64
- 		with_sigaltstack=no
+-		# This doesn't seem to work as of 7.0 on amd64
+-		with_sigaltstack=no
 -# TLS is only partially implemented on -CURRENT (compiler support
 -# but NOT library support)
 -#
Index: files/patch-mcs_tools_gacutil_driver.cs
===================================================================
--- files/patch-mcs_tools_gacutil_driver.cs	(revision 0)
+++ files/patch-mcs_tools_gacutil_driver.cs	(working copy)
@@ -0,0 +1,38 @@
+--- ./mcs/tools/gacutil/driver.cs.orig	2013-01-08 13:43:19.000000000 -0500
++++ ./mcs/tools/gacutil/driver.cs	2013-02-11 08:32:50.000000000 -0500
+@@ -427,15 +427,33 @@
+ 					break;
+ 
+ 				string dir = directories [i];
++				string extension = null;
++				
++				if (File.Exists(Path.Combine (dir, assembly_name + ".dll"))) {
++					extension = ".dll";
++				} else if (File.Exists(Path.Combine (dir, assembly_name + ".DLL"))) {
++					extension = ".DLL";
++				} else if (File.Exists(Path.Combine (dir, assembly_name + ".exe"))) {
++					extension = ".exe";
++				} else if (File.Exists(Path.Combine (dir, assembly_name + ".EXE"))) {
++					extension = ".EXE";
++				} else {
++					failures++;
++					WriteLine("Cannot find the assembly: " + assembly_name);
++					continue;
++				}
++
++				string AssemblyFilename = assembly_name + extension;
+ 
+ 				AssemblyName an = AssemblyName.GetAssemblyName (
+-					Path.Combine (dir, assembly_name + ".dll"));
++					Path.Combine(dir, AssemblyFilename));
+ 				WriteLine ("Assembly: " + an.FullName);
+ 
+ 				Directory.Delete (dir, true);
+ 				if (package != null) {
+ 					string link_dir = Path.Combine (libdir, package);
+-					string link = Path.Combine (link_dir, assembly_name + ".dll");
++					string link = Path.Combine(link_dir, AssemblyFilename);
++
+ 					try { 
+ 						File.Delete (link);
+ 					} catch {
Index: files/patch-mono_metadata_sgen-gc.c
===================================================================
--- files/patch-mono_metadata_sgen-gc.c	(revision 0)
+++ files/patch-mono_metadata_sgen-gc.c	(working copy)
@@ -0,0 +1,52 @@
+--- ./mono/metadata/sgen-gc.c.orig	2013-01-08 13:41:08.000000000 -0500
++++ ./mono/metadata/sgen-gc.c	2013-02-09 12:28:15.000000000 -0500
+@@ -179,6 +179,9 @@
+ #ifdef HAVE_PTHREAD_H
+ #include <pthread.h>
+ #endif
++#ifdef HAVE_PTHREAD_ATTR_GET_NP
++#include <pthread_np.h>
++#endif
+ #ifdef HAVE_SEMAPHORE_H
+ #include <semaphore.h>
+ #endif
+@@ -3990,17 +3993,28 @@
+ #endif
+ 
+ 	/* try to get it with attributes first */
+-#if defined(HAVE_PTHREAD_GETATTR_NP) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
+-	{
+-		size_t size;
+-		void *sstart;
+-		pthread_attr_t attr;
+-		pthread_getattr_np (pthread_self (), &attr);
+-		pthread_attr_getstack (&attr, &sstart, &size);
+-		info->stack_start_limit = sstart;
+-		info->stack_end = (char*)sstart + size;
+-		pthread_attr_destroy (&attr);
+-	}
++#if (defined(HAVE_PTHREAD_GETATTR_NP) || defined(HAVE_PTHREAD_ATTR_GET_NP)) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
++  {
++	size_t size;
++	void *sstart;
++	pthread_attr_t attr;
++
++#if defined(HAVE_PTHREAD_GETATTR_NP)
++	/* Linux */
++	pthread_getattr_np (pthread_self (), &attr);
++#elif defined(HAVE_PTHREAD_ATTR_GET_NP)
++	/* BSD */
++	pthread_attr_init (&attr);
++	pthread_attr_get_np (pthread_self (), &attr);
++#else
++#error Cannot determine which API is needed to retrieve pthread attributes.
++#endif
++
++	pthread_attr_getstack (&attr, &sstart, &size);
++	info->stack_start_limit = sstart;
++	info->stack_end = (char*)sstart + size;
++	pthread_attr_destroy (&attr);
++  }
+ #elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
+ 		 info->stack_end = (char*)pthread_get_stackaddr_np (pthread_self ());
+ 		 info->stack_start_limit = (char*)info->stack_end - pthread_get_stacksize_np (pthread_self ());
Index: files/patch-mono_metadata_threads.c
===================================================================
--- files/patch-mono_metadata_threads.c	(revision 0)
+++ files/patch-mono_metadata_threads.c	(working copy)
@@ -0,0 +1,107 @@
+--- ./mono/metadata/threads.c.orig	2013-01-08 13:41:07.000000000 -0500
++++ ./mono/metadata/threads.c	2013-02-09 12:28:05.000000000 -0500
+@@ -785,7 +785,16 @@
+ void
+ mono_thread_get_stack_bounds (guint8 **staddr, size_t *stsize)
+ {
+-#if defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
++#if defined(HOST_WIN32)
++	/* FIXME: 	If this function won't (or shouldn't) ever be called when running on
++			Windows, use the error preprocessor declaration here instead of this
++			default code (to _ensure_ we don't call this function on Windows). */
++	*staddr = NULL;
++	*stsize = (size_t)-1;
++	return;
++
++#elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
++	/* Mac OS X */
+ 	*staddr = (guint8*)pthread_get_stackaddr_np (pthread_self ());
+ 	*stsize = pthread_get_stacksize_np (pthread_self ());
+ 
+@@ -793,52 +802,54 @@
+ 	*staddr -= *stsize;
+ 	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
+ 	return;
+-	/* FIXME: simplify the mess below */
+-#elif !defined(HOST_WIN32)
++
++#elif (defined(HAVE_PTHREAD_GETATTR_NP) || defined(HAVE_PTHREAD_ATTR_GET_NP)) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
++	/* Linux, BSD */
++
+ 	pthread_attr_t attr;
+ 	guint8 *current = (guint8*)&attr;
+ 
+-	pthread_attr_init (&attr);
+-#  ifdef HAVE_PTHREAD_GETATTR_NP
+-	pthread_getattr_np (pthread_self(), &attr);
+-#  else
+-#    ifdef HAVE_PTHREAD_ATTR_GET_NP
+-	pthread_attr_get_np (pthread_self(), &attr);
+-#    elif defined(sun)
+-	*staddr = NULL;
+-	pthread_attr_getstacksize (&attr, &stsize);
+-#    elif defined(__OpenBSD__)
+-	stack_t ss;
+-	int rslt;
+-
+-	rslt = pthread_stackseg_np(pthread_self(), &ss);
+-	g_assert (rslt == 0);
++	#if defined(HAVE_PTHREAD_GETATTR_NP)
++	/* Linux */
++	pthread_getattr_np (pthread_self (), &attr);
+ 
+-	*staddr = (guint8*)((size_t)ss.ss_sp - ss.ss_size);
+-	*stsize = ss.ss_size;
+-#    else
+-	*staddr = NULL;
+-	*stsize = 0;
+-	return;
+-#    endif
+-#  endif
++	#elif defined(HAVE_PTHREAD_ATTR_GET_NP)
++	/* BSD */
++	pthread_attr_init (&attr);
++	pthread_attr_get_np (pthread_self (), &attr);
++	
++	#else
++	#error Cannot determine which API is needed to retrieve pthread attributes.
++	#endif
+ 
+-#  if !defined(sun)
+-#    if !defined(__OpenBSD__)
+ 	pthread_attr_getstack (&attr, (void**)staddr, stsize);
+-#    endif
++	pthread_attr_destroy (&attr);
++
+ 	if (*staddr)
+ 		g_assert ((current > *staddr) && (current < *staddr + *stsize));
+-#  endif
+ 
++	/* When running under emacs, sometimes staddr is not aligned to a page size */
++	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
++
++#elif defined(sun)
++	/* What OS / architecture is this for? */
++	pthread_attr_t attr;
++	pthread_attr_init (&attr);
++	pthread_attr_getstacksize (&attr, &stsize);
+ 	pthread_attr_destroy (&attr);
+-#else
+ 	*staddr = NULL;
+-	*stsize = (size_t)-1;
+-#endif
+ 
+ 	/* When running under emacs, sometimes staddr is not aligned to a page size */
+ 	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
++	return;
++
++#else
++	/* FIXME:	It'd be better to use the 'error' preprocessor macro here so we know
++			at compile-time if the target platform isn't supported. */
++	*staddr = NULL;
++	*stsize = 0;
++	return;
++#endif
+ }	
+ 
+ MonoThread *
Index: files/patch-mono_mini_mini-exceptions.c
===================================================================
--- files/patch-mono_mini_mini-exceptions.c	(revision 0)
+++ files/patch-mono_mini_mini-exceptions.c	(working copy)
@@ -0,0 +1,16 @@
+--- ./mono/mini/mini-exceptions.c.orig	2013-02-09 12:00:43.000000000 -0500
++++ ./mono/mini/mini-exceptions.c	2013-02-09 12:01:11.000000000 -0500
+@@ -2002,10 +2002,10 @@
+ 
+ 	sa.ss_sp = tls->signal_stack;
+ 	sa.ss_size = MONO_ARCH_SIGNAL_STACK_SIZE;
+-#if __APPLE__
+-	sa.ss_flags = 0;
+-#else
++#ifdef __linux__
+ 	sa.ss_flags = SS_ONSTACK;
++#else
++	sa.ss_flags = 0;
+ #endif
+ 	g_assert (sigaltstack (&sa, NULL) == 0);
+ 


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302111350.r1BDoNKv083173>