How to get variable names in methods?

412 katselukertaa
Siirry ensimmäiseen lukemattomaan viestiin

Timwi

lukematon,
8.5.2009 klo 16.59.098.5.2009
vastaanottaja mono-cecil
Hi,

I'm trying to get a list of the names of the local variables in a
specific method.

So I'm using something like this ...
foreach (var m in myLibrary.Modules.Cast<ModuleDefinition>
()) {
foreach (var t in m.Types.Cast<TypeDefinition>()) {
foreach (var e in t.Methods.Cast<MethodDefinition>
()) {
foreach (var v in
e.Body.Variables.Cast<VariableDefinition>()) {
Console.WriteLine(v.Name);
}
}
}
}

Unfortunately, I only get "V_0", "V_1", etc., not the real variable
names.

I tried actually changing the names to something like "a", "b", etc.,
by assigning to v.Name, but Red Gate's .NET Reflector still shows them
with their original name, so the name wasn't changed.

Renaming methods by assigning to m.Name appears to work. Reflector
shows the new names.

Why doesn't this work for variables, and how do I make it work?

Thanks!
Timwi

Jonathon Rossi

lukematon,
8.5.2009 klo 22.26.168.5.2009
vastaanottaja mono-...@googlegroups.com
Doesn't determining the variable name require the PDB? Never tried it before, but try loading the PDB into Cecil after the assembly.
--
Jono

gold...@gmx.de

lukematon,
9.5.2009 klo 3.16.199.5.2009
vastaanottaja mono-...@googlegroups.com
You have to load the PDB before modifying the assembly and save it to
disc with the assembly after modifying. The code should look something
like this:

AssemblyDefinition cecilAssembly =
AssemblyFactory.GetAssembly(assemblyName);
cecilAssembly.MainModule.LoadSymbols(); // this involves Cecil.Pdb.dll
or Cecil.Mdb.dll, base on what system you'r running it
// modify the assembly
cecilAssembly.MainModule.SaveSymbols();
AssemblyFactory.SaveAssembly(cecilAssembly, assemblyName);

Or at least it works for me like that. I've had some problems with
writing to the files becaue they're locked, though...
The code looks a bit strange as you don't have a direct reference to
Cecil.Pdb.dll or Cecil.Mdb.dll: they are loaded dynamically by Cecil.dll
based on the current system (MS.NET/Mono) to have portable code. The two
assemblies must be put at a place where they can be found by the .NET
runtime.

Simon

Timwi

lukematon,
9.5.2009 klo 7.34.199.5.2009
vastaanottaja mono-cecil
> You have to load the PDB before modifying the assembly and save it to
> disc with the assembly after modifying.

Thanks for your reply, but I've tried this and this doesn't appear to
be true. .NET Reflector can read the variable names even if I delete
the .pdb file for the relevant assembly. Therefore, the information
must be in the assembly itself. But even so, suppose I wanted to try
your method...

So I tried to find Mono.Cecil.Pdb on the web. Where can I download
this? The only place I could find is a SVN repository, so I would have
to either install SVN, or download every single .cs file individually.
Is there a proper source distribution for this?

Thanks again for your help.

Timwi

Jonathon Rossi

lukematon,
9.5.2009 klo 7.39.239.5.2009
vastaanottaja mono-...@googlegroups.com
Did you delete the pdb from a debug or release build?

You can checkout the source using a subversion client at:
http://anonsvn.mono-project.com/source/trunk/cecil
--
Jono

Jonathon Rossi

lukematon,
9.5.2009 klo 7.50.119.5.2009
vastaanottaja mono-...@googlegroups.com
I thought the debug assemblies might have had some extra metadata embedded somewhere, however when I remove the pdb Reflector goes back to using its own generated variable names from the type names as I expected.

Can you please check this again.
--
Jono

Yann Schwartz

lukematon,
9.5.2009 klo 7.58.309.5.2009
vastaanottaja mono-cecil
Hi Timwi,

Just like Jonathon said, you can see variable names in Reflector (and
Cecil) if you've explicitly loaded the symbol files (pdb). Reflector
does its own trick to guess at variable names when there's no pdb
avaliable (mainly, if the variable type is SomeFoo it will be foo, if
it's ints in loops it will be i,j,k, if it's a variable passed as an
argument to a method, the variable will take the name of the argument,
etc.) The guessing algorithm is so good it looks like actual code. But
by default, in Cecil, no pdb means default variable names...

Jb Evain

lukematon,
9.5.2009 klo 8.03.359.5.2009
vastaanottaja mono-...@googlegroups.com
Hey,

On 5/9/09, Timwi <ti...@gmx.net> wrote:
> Thanks for your reply, but I've tried this and this doesn't appear to
> be true. .NET Reflector can read the variable names even if I delete
> the .pdb file for the relevant assembly. Therefore, the information
> must be in the assembly itself. But even so, suppose I wanted to try
> your method...

You're wrong. What Jonathon says is true. The names of the local
variables are *only* stored in the debug symbols, which are pdb files
on .net, and mdb file on Mono.

You need to either get Mono.Cecil.Pdb from /cecil/pdb in Mono' svn.
Mono.Cecil.Mdb is in /mcs/class/Mono.Cecil.Mdb, and of course,
Mono.Cecil is in /mcs/class/Mono.Cecil.

Once you have the appropriate assemblies compiled and put along with
Mono.Cecil.dll, you just have to call ModuleDefinition.LoadSymbols
just after a GetAssembly call. Et voila, varible names will be
retrieved from the symbol file.

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

Timwi

lukematon,
9.5.2009 klo 11.53.419.5.2009
vastaanottaja mono-cecil
Thanks to everyone in this thread. I've solved it now.
Vastaa kaikille
Vastaa kirjoittajalle
Välitä
0 uutta viestiä