Mono.Cecil (Pdb) creates incorrect pdb file.

364 views
Skip to first unread message

Pavels

unread,
Mar 30, 2010, 3:20:09 PM3/30/10
to mono-cecil
Hi, I have a problem.
I use mono.cecil to modify a WPF .exe file. Visual Studio creates pdb
file that is 131 KB, after modification with mono.cecil (and
mono.cecil.pdb) the pdb file is only 40 KB.

AssemblyDefinition sourceAssembly =
AssemblyFactory.GetAssembly(shadowCopyPath);

ModuleDefinition modDef = sourceAssembly.MainModule;
PdbFactory pdbFactory = new PdbFactory();
ISymbolReader reader = pdbFactory.CreateReader(modDef,
shadowCopyPath);

modDef.LoadSymbols(reader);

foreach (TypeDefinition type in sourceAssembly.MainModule.Types)
{
//Do some modification
}

modDef.SaveSymbols(Path.GetDirectoryName(shadowCopyPath));
AssemblyFactory.SaveAssembly(sourceAssembly, shadowCopyPath);

Am i doing something wrong?

Jb Evain

unread,
Mar 30, 2010, 3:27:12 PM3/30/10
to mono-...@googlegroups.com
Hi,

On Tue, Mar 30, 2010 at 9:20 PM, Pavels <pavels.m...@gmail.com> wrote:
> Hi, I have a problem.
> I use mono.cecil to modify a WPF .exe file. Visual Studio creates pdb
> file that is 131 KB, after modification with mono.cecil (and
> mono.cecil.pdb) the pdb file is only 40 KB.

Are you concerned because of the size of your pdb? Or is it unusable
after Cecil manipulated it?

--
Jb Evain <j...@nurv.fr>

Pavels

unread,
Mar 30, 2010, 4:04:04 PM3/30/10
to mono-cecil

On Mar 30, 10:27 pm, Jb Evain <j...@nurv.fr> wrote:
> Hi,
>

> On Tue, Mar 30, 2010 at 9:20 PM, Pavels <pavels.mihail...@gmail.com> wrote:
> > Hi, I have a problem.
> > I use mono.cecil to modify a WPF .exe file. Visual Studio creates pdb
> > file that is 131 KB, after modification with mono.cecil (and
> > mono.cecil.pdb) the pdb file is only 40 KB.
>
> Are you concerned because of the size of your pdb? Or is it unusable
> after Cecil manipulated it?
>
> --
> Jb Evain  <j...@nurv.fr>

It is unusable after Cecil manipulation. Visual Studio manages to
Attach to process for debugging, but even if i set a breakpoint, it is
never hit (shows empty breakpoint).

The manipulations i'm doing are :

CilWorker MSILWorker = prop.SetMethod.Body.CilWorker;

Instruction callRaisePropertyChanged = MSILWorker.Create(OpCodes.Call,
raisePropertyChanged);

if
(prop.SetMethod.Body.Instructions.Contains(callRaisePropertyChanged))
break;

Instruction ldarg0 = MSILWorker.Create(OpCodes.Ldarg_0);
Instruction propertyName = MSILWorker.Create(OpCodes.Ldstr,
prop.Name);


MSILWorker.InsertBefore(prop.SetMethod.Body.Instructions[prop.SetMethod.Body.Instructions.Count
- 1], ldarg0);

MSILWorker.InsertAfter(ldarg0, propertyName);
MSILWorker.InsertAfter(propertyName, callRaisePropertyChanged);
MSILWorker.InsertAfter(callRaisePropertyChanged,
MSILWorker.Create(OpCodes.Nop));


-- I add a method call on property set method.

Jb Evain

unread,
Mar 30, 2010, 4:38:35 PM3/30/10
to mono-...@googlegroups.com
On Tue, Mar 30, 2010 at 10:04 PM, Pavels <pavels.m...@gmail.com> wrote:
> It is unusable after Cecil manipulation. Visual Studio manages to
> Attach to process for debugging, but even if i set a breakpoint, it is
> never hit (shows empty breakpoint).

What's written in VS's output window about loading your instrumented
assembly and its symbols?

--
Jb Evain <j...@nurv.fr>

Message has been deleted

Pavels

unread,
Mar 31, 2010, 12:06:28 AM3/31/10
to mono-cecil
'ScriptUploader.exe' (Managed): Loaded 'D:\HomeProjects\VersionBuilder
\VersionBuilder.ScriptUploaderV2\bin\Debug\ScriptUploader.exe',
Symbols loaded.

But when i check breakpoint
"The breakpoint will not currently be hit. No symbols have been loaded
for this document".

Exe was compiled under debug configuration and modified on the same
PC :/

Pavels

unread,
Mar 31, 2010, 2:18:59 AM3/31/10
to mono-cecil
I even tried to do nothing with assembly, just load and unload. The
pdb file changes(from 132KB to 40KB), but still debug doesn't work.

AssemblyDefinition sourceAssembly =
AssemblyFactory.GetAssembly(shadowCopyPath);

ModuleDefinition modDef = sourceAssembly.MainModule;
PdbFactory pdbFactory = new PdbFactory();
ISymbolReader reader = pdbFactory.CreateReader(modDef,
shadowCopyPath);

modDef.LoadSymbols(reader);

foreach (TypeDefinition type in sourceAssembly.MainModule.Types)
{

//Do nothing
}

modDef.SaveSymbols(Path.GetDirectoryName(shadowCopyPath));
AssemblyFactory.SaveAssembly(sourceAssembly, shadowCopyPath);

I tried to do this process manually and by using AfterBuild task.
Signing and not signing also doesn't help :/
I'm using Mono.Cecil 0.6.9.0 and Mono.Cecil.Pdb 0.2 (from the mono
trunk).

If full source code is needed i can share it.

Pavels

unread,
Mar 31, 2010, 2:40:02 AM3/31/10
to mono-cecil
It seems to me that i'm doing something wrong, i tried do nothing on
DLL and after that when i try to run exe that uses that dll i receive
an error - Error for MS( EventType : clr20r3 P1 :
scriptuploader.exe P2 : 1.0.0.0
P3 : 4bb2ec1a P4 : presentationframework P5 : 3.0.0.0 P6 :
4938d608
P7 : 961 P8 : f P9 : system.badimageformatexception )

Buryak Alexander

unread,
Apr 8, 2010, 7:57:57 AM4/8/10
to mono-cecil
I don't think that you do something wrong. I have the same issues with
PDB files and already reported this bug here: https://bugzilla.novell.com/show_bug.cgi?id=531630
You can revert to r132172 and it will fix your problem.
But be careful: new PDB file path should be shorter than old one
(yeap, that's another bug of CECIL).

I'm working with r132172 for a halfyear for now and the only annoying
bug I have now is this one:
http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/024f9019-699d-44e1-b0f9-43da50782e7d

WBR,
Alex

Jb Evain

unread,
Apr 8, 2010, 8:19:47 AM4/8/10
to mono-...@googlegroups.com
On Thu, Apr 8, 2010 at 1:57 PM, Buryak Alexander
<buryak.a...@gmail.com> wrote:
> I don't think that you do something wrong. I have the same issues with
> PDB files and already reported this bug here: https://bugzilla.novell.com/show_bug.cgi?id=531630

In the case of 531630, the assembly can be overwritten, and broking
the DLL/EXE, not the pdb. If VS can load the assembly but fails to
read the pdb then it's a different issue.

> But be careful: new PDB file path should be shorter than old one
> (yeap, that's another bug of CECIL).

This one will be fixed in the release due next monday.

> I'm working with r132172 for a halfyear for now and the only annoying
> bug I have now is this one:
> http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/024f9019-699d-44e1-b0f9-43da50782e7d

I don't really see how that's related to Cecil if the pdb doesn't
expose the variables and that even ildasm doesn't show them.

--
Jb Evain <j...@nurv.fr>

Александр Буряк

unread,
Apr 8, 2010, 12:54:28 PM4/8/10
to mono-...@googlegroups.com
In the case of 531630, the assembly can be overwritten, and broking
the DLL/EXE, not the pdb. If VS can load the assembly but fails to
read the pdb then it's a different issue.

In 531630 VS successfully loads both assembly and PDB file.
The assembly works fine, but PDB is almost empty.
This thread author's case is identical as far as I've understood.

 
This one will be fixed in the release due next monday.

That would be great!

 
I don't really see how that's related to Cecil if the pdb doesn't
expose the variables and that even ildasm doesn't show them.

Original PDB produced by compiler exposes all variables - debugger uses them perfectly, ildasm can see them.
But it seems that loading+saving of that PDB looses such variables, ildasm still sees them, but debugger - is not.
Probably some metainfo or something else is lost during the process - that is not vital for all other debugging features, but breakes debugger in very specific cases...

 

--
Jb Evain  <j...@nurv.fr>

--
--
mono-cecil

To unsubscribe, reply using "remove me" as the subject.

Jb Evain

unread,
Apr 8, 2010, 1:21:27 PM4/8/10
to mono-...@googlegroups.com
On Thu, Apr 8, 2010 at 6:54 PM, Александр Буряк
<buryak.a...@gmail.com> wrote:
> In 531630 VS successfully loads both assembly and PDB file.
> The assembly works fine, but PDB is almost empty.
> This thread author's case is identical as far as I've understood.

The case of 531630 will be fixed as well.

> Original PDB produced by compiler exposes all variables - debugger uses them
> perfectly, ildasm can see them.
> But it seems that loading+saving of that PDB looses such variables, ildasm
> still sees them, but debugger - is not.

That sucks. It's indeed maybe some special flags, I'll investigate and
see if I can get it for monday.

--
Jb Evain <j...@nurv.fr>

Александр Буряк

unread,
Apr 9, 2010, 4:30:29 AM4/9/10
to mono-...@googlegroups.com
The case of 531630 will be fixed as well.
 
That sucks. It's indeed maybe some special flags, I'll investigate and
see if I can get it for monday.

That would be fantastic!
Let us know if you need any additional info.

WBR,
Alex

Pavels

unread,
Apr 9, 2010, 11:39:55 AM4/9/10
to mono-cecil
Well yes, it just like Alex mentioned even if i do nothing with code,
just load and save pdb and dll file then cecil creates 40KB pdb file,
that is 1/3 of pdb file that generates VS(original pdb is 130KB) and
after that project is not debuggable. This is definitely a bug.

Buryak Alexander

unread,
Apr 13, 2010, 5:09:52 PM4/13/10
to mono-cecil
Greetings.

I've switched to Cecil 0.9 successfully.

Good news: PDB files are written almost properly - thay are large,
debugger-valid and working fine.
Unless one annoying situation I've mentioned before (about "yieldy"
functions):
http://www.google.com/url?sa=D&q=http://social.msdn.microsoft.com/Forums/en-US/csharpide/thread/024f9019-699d-44e1-b0f9-43da50782e7d&usg=AFQjCNGxaJAnv2A_hBJfqQQPi7ThwBR30w
- these variables are still lost in the debugger.

By the way, two litte fixes:

1. diff from MethodBodyRocks.GetParameter():
if (method.HasThis) {
+ if (index == 0)
+ return body.ThisParameter;
index--;
Otherwise Cecil crashes on accessing this in IL during SimplifyMacro()
method execution.

2. in MetadataImporter.ImportAssemblyName() it's useful to check for
(name.PublicKeyToken == null) before taking key token length for byte
array - or Cecil crashes on assemblies without PublicKeyToken.

Great job anyway.
I'm looking forward to fixing "yieldy" bug - after that Cecil will be
perfect for me!

WBR,
Alex

On Apr 8, 9:21 pm, Jb Evain <j...@nurv.fr> wrote:
> On Thu, Apr 8, 2010 at 6:54 PM, Александр Буряк
>

Buryak Alexander

unread,
Apr 13, 2010, 5:43:25 PM4/13/10
to mono-cecil
Found some troubles with saving IL code: load+save breaks some random
methods and causes runtime errors like
"System.BadImageFormatException : Bad IL range."

I'll take a closer look tomorrow and give some examples of such
functions for further investigation and bugfix.
Old Cecil works with those functions properly.

WBR,
Alex

On Apr 14, 1:09 am, Buryak Alexander <buryak.alexan...@gmail.com>
wrote:


> Greetings.
>
> I've switched to Cecil 0.9 successfully.
>
> Good news: PDB files are written almost properly - thay are large,
> debugger-valid and working fine.
> Unless one annoying situation I've mentioned before (about "yieldy"

> functions):http://www.google.com/url?sa=D&q=http://social.msdn.microsoft.com/For...

Jb Evain

unread,
Apr 13, 2010, 5:49:01 PM4/13/10
to mono-...@googlegroups.com
Hey Alexander,

2010/4/13 Buryak Alexander <buryak.a...@gmail.com>:


> Unless one annoying situation I've mentioned before (about "yieldy"
> functions):

I'll investigate those.

> 1. diff from MethodBodyRocks.GetParameter():


> 2. in MetadataImporter.ImportAssemblyName() it's useful to check for

Both are fixed.

Thanks!

--
Jb Evain <j...@nurv.fr>

Jb Evain

unread,
Apr 13, 2010, 5:49:50 PM4/13/10
to mono-...@googlegroups.com
Hey,

2010/4/13 Buryak Alexander <buryak.a...@gmail.com>:


> Found some troubles with saving IL code: load+save breaks some random
> methods and causes runtime errors like
> "System.BadImageFormatException : Bad IL range."
>
> I'll take a closer look tomorrow and give some examples of such
> functions for further investigation and bugfix.
> Old Cecil works with those functions properly.

Weird. It would be great if you could send me samples of those assemblies.

Buryak Alexander

unread,
Apr 13, 2010, 6:40:05 PM4/13/10
to mono-cecil
On Apr 14, 1:49 am, Jb Evain <j...@nurv.fr> wrote:
> Both are fixed.
That's fast! Thank you.

> Weird. It would be great if you could send me samples of those assemblies.

I'll recheck my code (it worked fine on old cecil, but may be I've
made some mistakes updating it for cecil/light) - and if I fail to fix
it, I'll make some examples for you.


WBR,
Alex

> Hey,
>
> 2010/4/13 Buryak Alexander <buryak.alexan...@gmail.com>:

Buryak Alexander

unread,
Apr 13, 2010, 6:16:56 PM4/13/10
to mono-cecil
Sorry, false alarm: latest source code has no troubles with IL
generation unless I make some changes to the IL.
I'll recheck my code later and let you know if there are any problems
in Cecil itself.

On Apr 14, 1:43 am, Buryak Alexander <buryak.alexan...@gmail.com>

Jb Evain

unread,
Apr 19, 2010, 6:59:32 PM4/19/10
to mono-...@googlegroups.com
Hey Alexander,

On Thu, Apr 8, 2010 at 6:54 PM, Александр Буряк
<buryak.a...@gmail.com> wrote:
> Original PDB produced by compiler exposes all variables - debugger uses them
> perfectly, ildasm can see them.
> But it seems that loading+saving of that PDB looses such variables, ildasm
> still sees them, but debugger - is not.
> Probably some metainfo or something else is lost during the process - that
> is not vital for all other debugging features, but breakes debugger in very
> specific cases...

I spent a bit of time tonight to try and figure out what's the deal
here. Apparently, at least according to the CCI sources, the pdb
contains custom metadata, and the iterator stuff is one of those
custom metadata.

I have no idea if I can get those custom metadata elements when
reading the assembly and saving them back yet. But at least we have a
clue at what's going on.

--
Jb Evain <j...@nurv.fr>

--
--
mono-cecil

Subscription settings: http://groups.google.com/group/mono-cecil/subscribe?hl=en

Александр Буряк

unread,
Apr 20, 2010, 3:01:27 AM4/20/10
to mono-...@googlegroups.com
 
I spent a bit of time tonight to try and figure out what's the deal
here. Apparently, at least according to the CCI sources, the pdb
contains custom metadata, and the iterator stuff is one of those
custom metadata.

Can you provide some links about this stuff?
I would like to repost them in the MS forum's "ildasm+ilasm" topic.
 

I have no idea if I can get those custom metadata elements when
reading the assembly and saving them back yet. But at least we have a
clue at what's going on.

It's great that the source of the problem is defined now.
May be I'll try to fix it myself on this week.

Thanks for your help!

WBR,
Alex

--
--
mono-cecil

Jb Evain

unread,
Apr 20, 2010, 9:00:18 AM4/20/10
to mono-...@googlegroups.com
Hey,

On Tue, Apr 20, 2010 at 9:01 AM, Александр Буряк
<buryak.a...@gmail.com> wrote:
> It's great that the source of the problem is defined now.

I wrote a bit about the issue here:

http://github.com/jbevain/cecil/issues#issue/4

Basically, ildasm and Cecil are not writing back the custom metadata
the pdb contains. The CCI uses a call to SetSymAttribute on a method
with a binary format, for a "MD2" attribute category.

Man I love working with PDBs, it's always such a joy.

Pavels

unread,
Apr 20, 2010, 3:27:45 PM4/20/10
to mono-cecil
Well looks like the Cecil v0.9.1 solved the issue, but now i've
spotted some small "bug". When i modify .exe file (add 4 lines of
code) , the breakpoints some times moves from places where they were
set and even when i attach to process and set breakpoint in that place
it seems that this breakpoint is set somewhere else(when i step into,
i see the code that should be ~4 lines from place where the breakpoint
was set).

Example
Assembly A contains class B and C. I modify class B. Start debugging
and set breakpoint somewhere in class C.

What is interesting that all other breakpoints work correctly :/ I'll
try to submit some code that reproduces this behaviour.
Reply all
Reply to author
Forward
0 new messages