pdb2mdb and Mono.Cecil.Pdb 27 Apr 2009

Sainte Anne I always complained about the fact that debug symbols were not portable between different CLR implementations. The .net CLR consumes pdb files, which is an undocumented format. Another file format was added to the ECMA-335 in a late revision. I wrote about this file format a while ago. To sum up, it was added very late while Mono already started to use its own format (mdb) and the .net CLR doesn't understand it anyway. So even if it's not a bad format (it could use some improvements, like a GUID heap similar to the one in a .net assembly), basically no one uses it in the real world. As mentioned in a recent post, the CCI contains an interesting piece of code, a managed pdb reader, licensed under the Ms-PL. I extracted it, and used it to be able to better share debug symbols between the .net CLR and Mono.


Robert Jordan, a long time Mono contributor, first wrote a tool named pdb2mdb, to convert a pdb to a mdb. The issue is that it was based on a combination of COM and the mixed mode assembly ISymWrapper which comes with the .net framework. All in all, it means that this version of pdb2mdb could only run on on the .net framework on Windows. With the managed pdb reader, it was very easy to write a fully managed pdb2mdb tool. It's now available in svn, and it will come with every other developer tool, such as ilasm or the linker. It's very easy to use. Say you're deploying a .net application on Linux, you have an assembly Foo.dll, and a Foo.pdb file, just use:
pdb2mdb Foo.dll
And the tool will generate a file Foo.dll.mdb, that Mono can use to display line information in stack traces.


Mono.Cecil.Pdb is an assembly that you use together with Cecil, to have line information at the IL level. It's used by tools such as Gendarme, or MoMA, to help diagnose and locate issues. I've integrated the managed reader, and the folks from NDepend were kind enough to beta test it. After a few fixes, the managed reader passed all NDepend tests, and was performing a lot better than its unmanaged counterpart. It's now the default, and only the pdb writer uses the ISymWrapper approach. It would be an interesting challenge for someone to try to write a managed writer from the information gathered in the reader. It may not be easy though.