Bugzilla – Bug 319921
[PPC] StackFrame is invalid on Mono but not in Windows
Last modified: 2010-03-21 11:56:21 UTC
---- Reported by richard.torkar@htu.se 2005-12-29 07:35:34 MST ---- (Dunno which component to file this under, JIT maybe Paolo?) Description of Problem: I have below a simple example that works on Windows .NET (1.1.4322) and Linux (Mono 1.1.9.2), but bails with a System.NullReferenceException on OS X (Mono 1.1.11). Steps to reproduce the problem: Compile and run the example. // using System; using System.Diagnostics; using System.Reflection; class Foo { [STAThread] static void Main(string[] args) { Foo f = new Foo(); f.WhatsMyName(); } private void WhatsMyName() { StackTrace stackTrace = new StackTrace(); StackFrame stackFrame = stackTrace.GetFrame(1); MethodBase methodBaseCallee = stackFrame.GetMethod(); // Displays "Callee name: Main" Console.WriteLine("Callee name: {0}", methodBaseCallee.Name); StackFrame stackFrameLocal = new StackFrame(); MethodBase methodBase = stackFrameLocal.GetMethod(); // Displays "Name of method: WhatsMyName" Console.WriteLine("Name of method: {0}", methodBase.Name); } } // Actual Results: On OS X I get a System.NullReferenceException, while on Windows and Linux I get the correct behaviour (i.e. the C.WriteLine() are written). Expected Results: Callee name: Main Name of method: WhatsMyName Additional Information: I copied the executable from Windows (compiled using csc and correctly running) to Linux and OS X, and ran it using mono (it fails on OS X but not on Linux). FYI: On OS X I use: Mono JIT compiler version 1.1.11, (C) 2002-2005 Novell, Inc and Contributors. www.mono-project.com TLS: normal GC: Included Boehm (with typed GC) SIGSEGV : normal On Linux I use: Mono JIT compiler version 1.1.9.2, (C) 2002-2005 Novell, Inc and Contributors. www.mono-project.com TLS: normal GC: Included Boehm (with typed GC) SIGSEGV : normal Globalization: normal And on Windows I use: Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4 for Microsoft (R) .NET Framework version 1.1.4322 ---- Additional Comments From robertj@gmx.net 2005-12-29 14:43:48 MST ---- BTW, you should *never* rely on StackFrame. The MS .NET runtime uses to inline methods if the app was compiled for RELEASE and when the app isn't running by a debugger. When this happens, callee and caller are not the expected methods. You'll lose your mind, because you cannot debug this problem: it doesn't occure while debugging ;-) If you feel that you cannot live w/out this feature, you have to mark each method that will act as a callee or caller (in your sample) with [MethodImpl(MethodImplOptions.NoInlining)] while giving away some performance. I bet mono behaves similar. ---- Additional Comments From richard.torkar@htu.se 2005-12-30 04:04:14 MST ---- But the sample runs w/o a problem on Windows (1.* and 2.*). As well as Linux. How come it doesn't work on OS X? ---- Additional Comments From robertj@gmx.net 2005-12-30 06:16:28 MST ---- I did't say it's not a bug on PPC. I just wanted to warn you about using StackFrame at all. Your simple sample may work, but you should expect trouble using StackFrame at large in your apps. Unknown bug field "cf_op_sys_details" encountered while moving bug <cf_op_sys_details>OS X 10.4.3</cf_op_sys_details> Unknown operating system unknown. Setting to default OS "Other".
Created attachment 220293 [details] Additional testcase demonstrating the bug Not only does StackFrame() not return the right frame, it triggers an exception if called high enough up the stack. Both cases are demonstrated in the attached testcase, which works properly on gentoo x86 but breaks on gentoo ppc. My feeling is that the StackFrame mechanism should work reliably, period. I've been using it for a long time on MS frameworks, and on Mono (x86 and ppc), and it's always worked, regardless of optimisation levels etc. x86 results: Calling A() Result 'B', should be 'B' Calling B() Result 'B', should be 'B' PPC results: Calling A() Result 'Main', should be 'B' Calling B() Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object at Test.Test.B () [0x00000] at Test.Test.Main () [0x00000]
That's what I get on MS.NET (compiled w/out "/debug+"): Calling A() Result 'Main', should be 'B' Calling B() Result 'Main', should be 'B' So much about "it always worked".
No kidding... So as a developer should I give up on being able to figure out who my caller is by saying new StackFrame( 1 )? Is there a more appropriate way to do it? Thanks in advance.
This works fine in recent mono versions on ppc.