Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Running pdb2mdb with Unity 5 and later

Discussion in 'Scripting' started by JoshPeterson, Mar 8, 2016.

  1. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,920
    The pdb2mdb.exe utility can be a really useful tool to aid in debugging managed assemblies which are built with Visual Studio. This tools allows the .pdb file Visual Studio generates containing debug information to be converted to a .mdb file which Mono debuggers (like MonoDevelop and Visual Studio Tools for Unity) can understand.

    Problem

    Beginning in Unity 5, this issue with pdb2mdb started to occur:

    https://issuetracker.unity3d.com/issues/4-dot-5-version-pdb2mdb-dot-exe-missing-few-dlls

    Basically, the pdb2mdb.exe utility is unable to find some assemblies it depends on, and exits with the following error (when it is executed on Windows):

    Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Mono.Cecil, Version=0.9.5.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756' or one of its dependencies. The system cannot find the file specified.
    at Pdb2Mdb.Driver.Main(String[] args)

    Actually, the Mono.Cecil assembly is shipped with the Unity installation. The real problem here is that pdb2mdb.exe from the Mono distribution is executed with the installed .NET Framework on Windows (the default behavior when a managed executable runs). The .NET framework does not understand how to find the Mono dependencies, and pdb2mdb.exe fails.

    Solutions

    There are a two ways to work around this issue.

    Option 1
    The pdb2mdb.exe utility should be executed with the Mono runtime (even on Windows). Running it like this will allow it to work correctly:

    "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono" "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.5\pdb2mdb.exe" <assembly to convert>

    Option 2
    Instead of using the pdb2mdb utility which ships with Mono, you can try the pdb2mdb utility available here:

    https://gist.github.com/jbevain/ba23149da8369e4a966f#file-pdb2mdb-exe

    This one is made to run on Windows with .NET, so it will work without the need to run it via Mono. Also, this version of pdb2mdb can convert assemblies built with Visual Studio 2015. The pdb2mdb utility which ships with Mono cannot convert them.

    Finally, if you are using Visual Studio Tools for Unity, this conversion should occur automatically when an assembly is imported into the Unity project. But if you would like to manually convert the .pdb files, these two options will work.
     
  2. CausticLasagne

    CausticLasagne

    Joined:
    Oct 2, 2015
    Posts:
    26
    Hi I am using this tool with the top one in a batch file like this:
    @echo off
    echo PDB to Mono MDB Converter
    echo Runtime
    "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\bin\mono" "C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.5\pdb2mdb.exe" "StealthGameLibrary.dll"

    pause
    When I run it I get this:
    PDB to Mono MDB Converter
    Runtime
    Mono pdb to mdb debug symbol store converter
    Usage: pdb2mdb assembly
    Press any key to continue . . .

    Can you point out where I might be going wrong please?

    EDIT: So I was sitting here wondering what I'd done wrong and what was in the folder prior to me successfully running the tool like last time, and then it hit me. Well make sure you guys copy the PDB file and the DLL together. The command syntax is really confusing because I thought only the DLL was required, so can you guys make this tool state that the pdb is required to produce the MDB please?
     
    Last edited: Jan 24, 2018
  3. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,920
    We can have a look at better error messages. This is not a tool Unity maintains, but we might be able to improve it.
     
  4. CausticLasagne

    CausticLasagne

    Joined:
    Oct 2, 2015
    Posts:
    26
    Thanks ;)
     
  5. hexagonius

    hexagonius

    Joined:
    Mar 26, 2013
    Posts:
    98
    @JoshPeterson I went as far as even trying this here: https://github.com/shravan2x/Pdb2Mdb-GUI and it worked. I now have followed the Unity BitBucket/UI documentation to get my own UI dll compiled and replaced in 2018.2.11f1 AND i have the UnityEngine.UI.dll.mdb in the same folder.
    Would you mind telling me how I can now debug source code from within UnityEngine.UI.dll? I read about using Redgate... something and Resharper. Is there a free alternative out there? Should this be working already? This is basically the first time I try something that doesn't happen in the Realms of Unity directly, but since the UI has bugs the Unity Devs won't fix, maybe I can lend a hand here, but for that I need to be able to debug the code.

    If you could help or link me a good instruction page to do all this I'll be happy :)
     
  6. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,920
    In 2018.2, Unity can read both PDB and MDB files, so there is no need to use any pdb2mdb tool. We don't have support for or documentation about debugging Unity source code, but the C# code is all available for reference here: https://github.com/Unity-Technologies/UnityCsReference

    You might be able to build it yourself and replace the managed assemblies in the Unity installation with the ones you built.

    Regarding Redgate and ReSharper, both tools will work to generally reflect and debug managed assemblies. I don't believe there are any free alternatives with the same behavior.
     
    zwcloud and mohamad_xtouch like this.
  7. xpsama

    xpsama

    Joined:
    Jul 19, 2018
    Posts:
    1
    i use unity 2018.3.0f2, When I import my dll, it will log a error message like this:

    System.InvalidOperationException: Magic is wrong.
    at Microsoft.Cci.Pdb.PdbFileHeader..ctor (System.IO.Stream reader, Microsoft.Cci.Pdb.BitAccess bits) [0x00088] in <b769d8a00e8245f489ba57d016607fc9>:0
    at Microsoft.Cci.Pdb.PdbFile.LoadFunctions (System.IO.Stream read, System.Collections.Generic.Dictionary`2[System.UInt32,Microsoft.Cci.Pdb.PdbTokenLine]& tokenToSourceMapping, System.String& sourceServerData, System.Int32& age, System.Guid& guid) [0x00012] in <b769d8a00e8245f489ba57d016607fc9>:0
    at Mono.Cecil.Pdb.NativePdbReader.PopulateFunctions () [0x00007] in <b769d8a00e8245f489ba57d016607fc9>:0
    at Mono.Cecil.Pdb.NativePdbReader.ProcessDebugHeader (Mono.Cecil.Cil.ImageDebugHeader header) [0x00087] in <b769d8a00e8245f489ba57d016607fc9>:0
    at Mono.Cecil.ModuleDefinition.ReadSymbols (Mono.Cecil.Cil.ISymbolReader reader) [0x00021] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at Mono.Cecil.ModuleReader.ReadSymbols (Mono.Cecil.ModuleDefinition module, Mono.Cecil.ReaderParameters parameters) [0x0004a] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at Mono.Cecil.ModuleReader.CreateModule (Mono.Cecil.PE.Image image, Mono.Cecil.ReaderParameters parameters) [0x00081] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at Mono.Cecil.ModuleDefinition.ReadModule (Mono.Disposable`1[T] stream, System.String fileName, Mono.Cecil.ReaderParameters parameters) [0x0000d] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at Mono.Cecil.ModuleDefinition.ReadModule (System.String fileName, Mono.Cecil.ReaderParameters parameters) [0x0006c] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at Mono.Cecil.AssemblyDefinition.ReadAssembly (System.String fileName, Mono.Cecil.ReaderParameters parameters) [0x00000] in <a3989f8c34e6476eaca56644d5639ee8>:0
    at AssemblyUpdater.Core.AssemblyUpdaterContext.ReadAssembly (System.String assemblyPath, APIUpdater.Framework.Log.IAPIUpdaterListener listener, System.IO.FileAccess mode, System.String nugetPath, System.String[] searchPaths) [0x00072] in <beff41bd86dd48a09189802b70907c29>:0
    at AssemblyUpdater.Core.AssemblyUpdaterContext.From (System.String assemblyPath, APIUpdater.Framework.Configuration.IConfigurationProvider configuration, System.String[] assemblySearchPaths, System.String nugetPath, AssemblyUpdater.Core.UpdaterMode mode, APIUpdater.Framework.Log.IAPIUpdaterListener listener) [0x0002c] in <beff41bd86dd48a09189802b70907c29>:0
    at AssemblyUpdater.Core.AssemblyUpdaterContext.From (System.String assemblyPath, System.String[] assemblySearchPaths, System.String nugetPath, AssemblyUpdater.Core.UpdaterMode mode, APIUpdater.Framework.Log.IAPIUpdaterListener listener) [0x00001] in <beff41bd86dd48a09189802b70907c29>:0
    at AssemblyUpdater.Application.Program.CheckForObsoleteAPIUsage (AssemblyUpdater.Application.CommandLineSpec config, APIUpdater.Framework.Log.ConsoleUpdateListener logger) [0x00013] in <beff41bd86dd48a09189802b70907c29>:0
    at AssemblyUpdater.Application.Program.Main (System.String[] args) [0x00057] in <beff41bd86dd48a09189802b70907c29>:0
    UnityEditor.Scripting.APIUpdaterAssemblyHelper:DoesAssemblyRequireUpgrade(String)

    I can't find any solution in google, and I can't debug my dll in runtime. How can I solve the problem? Thanks!
     
  8. JoshPeterson

    JoshPeterson

    Unity Technologies

    Joined:
    Jul 21, 2014
    Posts:
    6,920
    Is there an associated .pdb or .mdb file with this .dll that you import into the project? It looks like one exists, but that file is corrupt. Maybe try deleting the .pdb or .mdb file before importing the .dll into the project.
     
  9. gilley033

    gilley033

    Joined:
    Jul 10, 2012
    Posts:
    1,181
    Bumping this in case anyone else runs into the issue. In Visual Studio for my library, I went into Build -> Advanced and changed Debugging information to "Portable". It now works.
     
    Mark-Currie likes this.