[Mono-bugs] [Bug 81394][Cri] New - Segmentation fault with embedded Mono due to incorrect stack bottom calculation

bugzilla-daemon at bugzilla.ximian.com bugzilla-daemon at bugzilla.ximian.com
Wed Apr 18 10:28:13 EDT 2007


Please do not reply to this email- if you want to comment on the bug, go to the
URL shown below and enter your comments there.

Changed by horst.reiterer at fabasoft.com.

http://bugzilla.ximian.com/show_bug.cgi?id=81394

--- shadow/81394	2007-04-18 10:28:13.000000000 -0400
+++ shadow/81394.tmp.20082	2007-04-18 10:28:13.000000000 -0400
@@ -0,0 +1,125 @@
+Bug#: 81394
+Product: Mono: Runtime
+Version: 1.2
+OS: other
+OS Details: Red Hat Enterprise Linux 4
+Status: NEW   
+Resolution: 
+Severity: 
+Priority: Critical
+Component: JIT
+AssignedTo: lupus at ximian.com                            
+ReportedBy: horst.reiterer at fabasoft.com               
+QAContact: mono-bugs at ximian.com
+TargetMilestone: ---
+URL: 
+Cc: 
+Summary: Segmentation fault with embedded Mono due to incorrect stack bottom calculation
+
+Mono 1.2.3.1 (and earlier; also tested with Mono 1.1.13.2) built with
+--with-sigaltstack=no (default in the case of the official RPM builds for
+Linux x86) causes a segmentation fault in an embedded scenario.
+
+A process initializes the runtime in thread A. In thread B,
+mono_thread_attach() is called with an frame pointer value of 0x100000
+(illustrative), causing the stack bottom (jit_tls->endofstack) to be
+initialized with that value (approximately, because the address of a local
+variable is used).
+Now, if native code with a larger frame pointer (above or equal to
+endofstack) triggers the execution of a managed method which calls
+Assembly.GetExecutingAssembly(), or anything that causes a stack walk using
+mono_jit_walk_stack() and requires a non-NULL result, a segmentation fault
+will occur because a condition in mono_jit_walk_stack tests for the stack
+bottom boundary:
+
+  void mono_jit_walk_stack (MonoStackWalk func,
+    gboolean do_il_offset, gpointer user_data) {
+  {
+    // ...
+    while (MONO_CONTEXT_GET_BP (&ctx) < jit_tls->end_of_stack) {
+    // ...
+  }
+
+If mono is self-hosting, this can never occur because end_of_stack is
+initialized at the very beginning of the thread main, thus almost on the
+stack bottom. Subsequently executed code can never cause the frame pointer
+to be higher than the determined stack bottom. In the embedded case, this
+can happen if a thread not created by Mono calls mono_thread_attach() with
+a frame pointer of X and later indirectly executes code comparing
+jit_tls->end_of_stack with a frame pointer >= X.
+
+The main problem is the assumption that using an address of the current
+stack frame during mono_thread_attach() is correct for the embedded case.
+Correct would be the initialization of end_of_stack based on the actual
+stack bottom of the thread, initialized using pthread facilities.
+
+Workarounds:
+
+Mono built with --with-sigaltstack=yes does not cause this problem because
+mono_setup_altstack patches the stack bottom correctly based on pthread
+facilities. On x86-64, this does not occur aswell because the options
+default to --with-sigaltstack=yes.
+
+Fixes:
+
+I attached a patch against Mono 1.1.13.2 which basically duplicates the
+code dealing with determining the thread stack bottom in
+mono_setup_altstack() in mono_thread_attach(). The problem cannot be
+reproduced anymore after applying the patch.
+
+Steps to reproduce the problem:
+1. gcc testcase.c `pkg-config --cflags --libs mono`
+2. gmcs /target:library testcase.cs
+3. ./a.out
+
+Actual Results:
+
+A segmentation fault occurs in GetExecutingAssembly().
+
+attachandcall 0xf7df73b0
+call 0xf7d77364
+A called
+Calling GetExecutingAssembly
+GetExecutingAssembly returned: testcase, Version=0.0.0.0, Culture=neutral
+call 0xf7df73a4
+A called
+Calling GetExecutingAssembly
+Stacktrace:
+
+
+Native stacktrace:
+
+        /usr/lib/libmono.so.0 [0xf7e62721]
+        /usr/lib/libmono.so.0 [0xf7e3da99]
+        [0xffffe600]
+        [0xf7187936]
+        [0xf717f769]
+        [0xf717f6de]
+        /usr/lib/libmono.so.0 [0xf7e3d8fe]
+        /usr/lib/libmono.so.0(mono_runtime_invoke+0x35) [0xf7ea40d5]
+        ./a.out [0x8048922]
+        ./a.out [0x80489af]
+        /lib/libpthread.so.0 [0x6e62db]
+        /lib/libc.so.6(clone+0x5e) [0x66f14e]
+
+Expected Results:
+
+Successful execution:
+
+attachandcall 0xf7df73b0
+call 0xf7d77364
+A called
+Calling GetExecutingAssembly
+GetExecutingAssembly returned: testcase, Version=0.0.0.0, Culture=neutral
+call 0xf7df73a4
+A called
+Calling GetExecutingAssembly
+GetExecutingAssembly returned: testcase, Version=0.0.0.0, Culture=neutral
+
+How often does this happen? 
+
+100 out of 100 times
+
+Additional Information:
+
+Testcase and patch (against 1.1.13.2) are attached.


More information about the mono-bugs mailing list