Sdk: dotnet build uses DebugType=portable for projects targeting .NET Framework

Created on 20 May 2017  Â·  11Comments  Â·  Source: dotnet/sdk

_From @innix on May 19, 2017 18:26_

dotnet build by default uses DebugType value of portable which I believe is only valid for .NET Core projects. When portable pdb's are emitted for .NET Framework projects, they just get ignored. This can be confirmed by looking at a stack trace.

Steps to reproduce

  1. Create a new console app:
$ mkdir foo
$ cd foo
$ dotnet new console
  1. In the .csproj file, change the TargetFramework to net462 (or whatever full .NET Framework version you have installed).

  2. Change Program.cs to this:

using System;

namespace foo
{
    class Program
    {
        static void Main(string[] args) => A();

        static void A() => B();
        static void B() => C();
        static void C() => throw new Exception("Oh no!");
    }
}
  1. Run the app:
$ dotnet run

Expected behavior

I expect source file names and line numbers to be present in the stack trace:

Unhandled Exception: System.Exception: Oh no!
   at foo.Program.C() in C:\Users\Phil\Desktop\foo\Program.cs:line 11
   at foo.Program.B() in C:\Users\Phil\Desktop\foo\Program.cs:line 10
   at foo.Program.A() in C:\Users\Phil\Desktop\foo\Program.cs:line 9
   at foo.Program.Main(String[] args) in C:\Users\Phil\Desktop\foo\Program.cs:line 7

That is the stack trace you get when running it as a netcoreapp1.1 app, so a stack trace for a net462 app should be identical, right?

Actual behavior

This is what you actually get when targeting net462:

Unhandled Exception: System.Exception: Oh no!
   at foo.Program.C()
   at foo.Program.B()
   at foo.Program.A()
   at foo.Program.Main(String[] args)

It can easily be fixed by changing the DebugType to full/pdbonly in your .csproj file but the default behaviour seems wrong.

Environment data

dotnet --info output:

$ dotnet --info
.NET Command Line Tools (1.0.4)

Product Information:
 Version:            1.0.4
 Commit SHA-1 hash:  af1e6684fd

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.15063
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\1.0.4

_Copied from original issue: dotnet/cli#6637_

Most helpful comment

Another data point: VS Code is only able to debug assemblies with Portable PDBs. So if Windows PDBs are produced for the library VS Code won't be able to debug it even on Windows.

All 11 comments

@tmat Is this expected? Should portable PDBs work for full framework TFMs?

_From @tmat on May 19, 2017 21:52_

They'll work starting with 4.7.1. They were supposed to work in 4.7 but the support was removed due to an issue that's fixed in 4.7.1.

_From @tmat on May 19, 2017 21:53_

(by work I mean the stack trace reporting line numbers and file names)

I think it may still make sense for any full framework that is not 471, to default to a different debug type. I will move this issue to dotnet/sdk.

This is by design. We shouldn't add unnecessary complexity to the defaults. Portable PDB for < 4.7.1 is not incorrect, it's just that the framework stack trace implementation can't read them, but any VS capable of using the SDK has a debugger that can. I think we should continue to have the same default irrespective of target framework. Users can set the PDB type in their projects if they want stack trace on older versions of .NET framework to show source info. It is going to open up a can of worms around breaking change of moving default from props to targets in order to vary by TargetFrameworkIdentifier and TargetFrameworkVersion.

Another data point: VS Code is only able to debug assemblies with Portable PDBs. So if Windows PDBs are produced for the library VS Code won't be able to debug it even on Windows.

So what would be be best option to choose from? full or portable ? Or can we define both?

portable now fully supported by .NET Framework 4.7.1, it seems to be preferable PDB format now.
https://blogs.msdn.microsoft.com/dotnet/2017/10/17/announcing-the-net-framework-4-7-1/ (scroll to Runtime – Support for Portable PDBs).

... yet it has to be set to full (at least for now) in order to get code coverage running, just linking here for the sake of reference: https://github.com/Microsoft/vstest/issues/800

If I modify the original repro to <TargetFramework>net471</TargetFramework>, I still get no file names. Is there an additional requirement?

This is the csproj:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net471</TargetFramework>
  </PropertyGroup>

</Project>

Hm, it does work if I target net472.

Was this page helpful?
0 / 5 - 0 ratings