Welcome to the Inedo Forums! Check out the Forums Guide for help getting started.

If you are experiencing any issues with the forum software, please visit the Contact Form on our website and let us know!

Cannot access source-files



  • Hi,
    We are trying to use the symbol/source server functionality of ProGet, however are not succeeding.

    We have a feed with symbol/source support turned on. We have published a nuget package to this feed that contains the dll, pdb under lib and the source under src.

    We have followed the instructions from http://inedo.com/support/tutorials/debug-into-internal-nuget-packages-with-proget. It seems that VisualStudio is able to successfully find and download the PDB however when it then goes to retrieve the source it receives a 404.

    If I go and try to access the URL that VisualStudio is attempting to access:
    http://localhost:81/source-files/Default/MyPackage/2.0.0/

    I get a Request Handler not found (404) with the Error Details:
    /source-files/Default/MyPackage/2.0.0/ does not map to any handlers. The URL may have been entered incorrectly or linked to from an old reference.

    I have checked the package on disk and it does still have the structure of the one we uploaded. Also the UI in proget says a source/symbol package is available and I can download the package with the source and symbols from the UI.

    We have been evaluating ProGet for sometime now and finally have the budget approved to purchase. However not being able to debug into the packages is making us question if we want to proceed...

    Product: ProGet
    Version: 3.1.6



  • UPDATE:
    So I have looked at a PDB that we can successfully debug into and the key differences seem to be:

    Broken:

    SRCSRV: source files ---------------------------------------
    d:\buildagent\work\96969837443edb4\lending.infrastructure.databaseupdater\customdbupdbupsqlserverdatabaseupdater.cs*
    d:\buildagent\work\96969837443edb4\lending.infrastructure.databaseupdater\customdbupdbupcustomextensions.cs*
    d:\buildagent\work\96969837443edb4\lending.infrastructure.databaseupdater\customdbupshareablesqlserverconnectionmanager.cs*
    SRCSRV: end ------------------------------------------------
    

    Works:

    SRCSRV: source files ------------------------------------------
    d:\BuildAgent\work\96969837443edb4\Lending.Infrastructure.DatabaseUpdater\CustomDbUp\ShareableSqlServerConnectionManager.cs*Lending.Infrastructure.DatabaseUpdater/CustomDbUp/ShareableSqlServerConnectionManager.cs
    d:\BuildAgent\work\96969837443edb4\Lending.Infrastructure.DatabaseUpdater\CustomDbUp\DbUpCustomExtensions.cs*Lending.Infrastructure.DatabaseUpdater/CustomDbUp/DbUpCustomExtensions.cs
    d:\BuildAgent\work\96969837443edb4\Lending.Infrastructure.DatabaseUpdater\CustomDbUp\DbUpSqlServerDatabaseUpdater.cs*Lending.Infrastructure.DatabaseUpdater/CustomDbUp/DbUpSqlServerDatabaseUpdater.cs
    SRCSRV: end ------------------------------------------------
    

    If I add the same after the * in our ProGet generated PDB everything works as expected!

    Is there something I can do to fix this on my end or is this a bug in ProGet?



  • Solved!

    The below uses decompiled code.

    We are generating our packages as per NuGet.org which stipulates that your folder structure under src should match our sln structure.

    C:\Projects
        \MyProject
            \Common
                \MyClass.cs
            \Full
                \Properties
                    \AssemblyInfo.cs
                \MyAssembly.csproj (producing \lib\net40\MyAssembly.dll)
            \Silverlight
                \Properties
                    \AssemblyInfo.cs
                \MySilverlightExtensions.cs
                \MyAssembly.csproj (producing \lib\sl4\MyAssembly.dll)
    
    \src
        \Common
            \MyClass.cs
        \Full
            \Properties
                \AssemblyInfo.cs
        \Silverlight
            \Properties
                \AssemblyInfo.cs
            \MySilverlightExtensions.cs
    

    So the problem is with the way ProGet is scanning the Nupkg to find source files.

    When ProGet invokes SymbolServerHandler.ProcessInternalRequest, it iterates over the CSharpCode.SharpZipLib.Zip.ZipEntries using:

    var list = zipFile.Cast<ZipEntry>().Where(e =>e.Name.StartsWith("src/", StringComparison.OrdinalIgnoreCase)).Select(e => e.Name.Substring(4));
    

    This actually returns both folders and files. So from the above example you get a collection that contains:

    ""
    "Common/"
    "Common/MyClass.cs"
    "Full/"
    "Full/Properties/"
    "Full/Properties/AssemblyInfo.cs"
    "Silverlight/"
    "Silverlight/Properties/"
    "Silverlight/Properties/AssemblyInfo.cs"
    "Silverlight/Properties/MySilverlightExtensions.cs"
    

    So when it then goes to match entries from the PDB to the actual source files:

    using (PdbFile pdbFile = new PdbFile((Stream) seekableStream, false, true))
    {
      foreach (string str3 in pdbFile.EnumerateSourceFileNames())
      {
        string streamName = str3;
        string str4 = list.FirstOrDefault<string>(n => streamName.Replace('\\', '/').IndexOf(n, StringComparison.OrdinalIgnoreCase) >= 0);
        if (str4 != null)
          srcsrv.SourceFilesSection.Add(streamName, str4.TrimStart('/'));
      }
    }
    

    It always matches on the first empty string, or even folder names.

    This is a potential fix:

    using (SeekableStream seekableStream = new SeekableStream((Func<Stream>)(() => zipFile.GetInputStream(pdbEntry)), pdbEntry.Size))
    {
    	var regex = new Regex(@"^src/(.*)\.([A-Z,a-z]{1,3})$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant);
    	
    	var list = zipFile.Cast<ZipEntry>().Where(e => regex.IsMatch(e.Name)).Select(e => e.Name.Substring(4)).ToList();
    


  • Thanks for the detailed investigation! We have logged this as PG-250 and a fix will be included in the next release (v3.1.7). Provided there's no issues with testing, you can expect this release later today.


Log in to reply
 

Inedo Website HomeSupport HomeCode of ConductForums GuideDocumentation