views:

45

answers:

1

Hello, I followed this example from Scott Hanselmans webpage: http://www.hanselman.com/blog/ReleaseISNOTDebug64bitOptimizationsAndCMethodInliningInReleaseBuildCallStacks.aspx

My goal is to get the line number from where the exception is thrown not where it is caught.

When I compile the code with the following build-script it wont work

SET FXROOT=%Systemroot%\Microsoft.NET\Framework\v4.0.30319

DEL *.exe /q

"%FXROOT%\csc.exe" /t:exe /out:NormalRelease.exe /debug:pdbonly /o+ NormalProgram.cs

NormalRelease.exe > NormalRelease32.txt

Output:

System.ApplicationException: generic bad thing
   at NormalProgram.Main(String[] args) in c:\Development\DebugSymbols\DebugSymConsole\NormalProgram.cs:line 8

When I compile the code with this build-script it will work

SET FXROOT=%Systemroot%\Microsoft.NET\Framework\v2.0.50727

DEL *.exe /q

"%FXROOT%\csc.exe" /t:exe /out:NormalRelease.exe /debug:pdbonly /o+ NormalProgram.cs

NormalRelease.exe > NormalRelease32.txt

Output:

System.ApplicationException: generic bad thing
   at NormalProgram.badMethod() in c:\Development\DebugSymbols\DebugSymConsole\NormalProgram.cs:line 18
   at NormalProgram.Main(String[] args) in c:\Development\DebugSymbols\DebugSymConsole\NormalProgram.cs:line 8

The difference is that in my first example i compiled against the .net2-framework, and in my second example I compiled against the .net4-framework.

Any solutions to my problem would be appreciated, thanks.

+1  A: 

This is something you are going to have to deal with if you expect to generate line numbers from code generated in the Release configuration. The JIT compiler's optimizer is enabled and it is going to move code around to create more efficient machine code. That's going to affect the accuracy of the reported line number.

The specific workaround here is to apply this attribute to "badMethod":

using System.Runtime.CompilerServices;
...
        [MethodImpl(MethodImplOptions.NoInlining)]
        void badMethod() {
            // etc...
        }

This is not a joyful workaround, inlining is an important optimization, especially on property getter/setters. The reason it is different between .NET 2.0 and 4.0 is because they have different jitters with different rules for deciding when a method should be inlined.

Hans Passant