Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Code for trimming assemblies crashes with a problem on generics (0.9.4 and 0.9.5)
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  2 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
blez  
View profile  
 More options Aug 13 2012, 10:44 am
From: blez <essen...@gmail.com>
Date: Mon, 13 Aug 2012 07:44:04 -0700 (PDT)
Local: Mon, Aug 13 2012 10:44 am
Subject: Code for trimming assemblies crashes with a problem on generics (0.9.4 and 0.9.5)

I tried to make a simple code pruner, but it fails with generic methods. So
I tried to skip all generic types, but it still throws exception.

Here's my code:

            var a = AssemblyDefinition.ReadAssembly(@"C:\test.exe");
            var mainModule = a.MainModule;

            bool print = false;

            // 1. get a list of all methods
            List<string> AllMethods = new List<string>();
            foreach (var type in mainModule.Types) {
                if (!type.HasMethods) continue;
                if (type.HasGenericParameters || type.IsGenericInstance) continue;

                foreach(var method in type.Methods) {
                    AllMethods.Add(method.FullName);
                    if (print) Console.WriteLine("> " + method.FullName);
                }
            }

            Console.WriteLine("TOTAL METHODS WITHOUT TRIM: " + AllMethods.Count.ToString());

            // 2. get all referenced methods

            foreach (var type in mainModule.Types) {
                if (print) Console.WriteLine(type.FullName);

                foreach (var method in type.Methods) {
                    if (print) Console.WriteLine("\t" + method.FullName);

                    if (method.HasBody) {
                        foreach (var inst in method.Body.Instructions) {
                            if (inst.Operand != null) {
                                string operand = inst.Operand.ToString();

                                if (operand.Contains("(") && !operand.Contains("!")) { // "!" for generic parameter
                                    if (print) Console.WriteLine("> " + operand);
                                    AllMethods.Remove(operand);
                                }
                            }

                        }
                    }
                }
            }

            Console.WriteLine("TOTAL METHODS AFTER TRIM: " + AllMethods.Count.ToString());

            // 3. remove all unreferenced

            foreach (var type in mainModule.Types) {

                List<MethodDefinition> MethodsToBeRemoved = new List<MethodDefinition>();
                foreach (var method in type.Methods) {
                    if (AllMethods.Contains(method.FullName)) {
                        MethodsToBeRemoved.Add(method);
                    }
                }

                foreach (var method in MethodsToBeRemoved) {

                    if (method.FullName.Contains("ctor")) continue;
                    if (method.FullName.Contains("Main")) continue;

                    type.Methods.Remove(method);
                    if (print) Console.WriteLine("REMOVING " + method.FullName);
                }
            }

            a.Write(@"C:\test_out.exe");

            Console.WriteLine("DONE");

-----------------

This gives me this exception:

System.NullReferenceException was unhandled
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=Mono.Cecil
  StackTrace:
       at Mono.Cecil.GenericInstanceMethod.get_FullName()
       at Mono.Cecil.MemberReference.ToString()
       at System.Text.StringBuilder.AppendFormat(IFormatProvider provider,
String format, Object[] args)
       at System.String.Format(IFormatProvider provider, String format,
Object[] args)
       at System.String.Format(String format, Object arg0)
       at
Mono.Cecil.MetadataBuilder.CreateForeignMemberException(MemberReference
member)
       at Mono.Cecil.MetadataBuilder.LookupToken(IMetadataTokenProvider
provider)
       at Mono.Cecil.Cil.CodeWriter.WriteOperand(Instruction instruction)
       at Mono.Cecil.Cil.CodeWriter.WriteInstructions()
       at
Mono.Cecil.Cil.CodeWriter.WriteResolvedMethodBody(MethodDefinition method)
       at Mono.Cecil.Cil.CodeWriter.WriteMethodBody(MethodDefinition method)
       at Mono.Cecil.MetadataBuilder.AddMethod(MethodDefinition method)
       at Mono.Cecil.MetadataBuilder.AddMethods(TypeDefinition type)
       at Mono.Cecil.MetadataBuilder.AddType(TypeDefinition type)
       at Mono.Cecil.MetadataBuilder.AddTypeDefs()
       at Mono.Cecil.MetadataBuilder.BuildTypes()
       at Mono.Cecil.MetadataBuilder.BuildModule()
       at Mono.Cecil.MetadataBuilder.BuildMetadata()
       at Mono.Cecil.ModuleWriter.<BuildMetadata>b__0(MetadataBuilder
builder, MetadataReader _)
       at Mono.Cecil.ModuleDefinition.Read[TItem,TRet](TItem item, Func`3
read)
       at Mono.Cecil.ModuleWriter.BuildMetadata(ModuleDefinition module,
MetadataBuilder metadata)
       at Mono.Cecil.ModuleWriter.WriteModuleTo(ModuleDefinition module,
Stream stream, WriterParameters parameters)
       at Mono.Cecil.ModuleDefinition.Write(Stream stream, WriterParameters
parameters)
       at Mono.Cecil.ModuleDefinition.Write(String fileName,
WriterParameters parameters)
       at Mono.Cecil.AssemblyDefinition.Write(String fileName,
WriterParameters parameters)
       at Mono.Cecil.AssemblyDefinition.Write(String fileName)
       [...]

--------

Any help?


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jb Evain  
View profile  
 More options Aug 14 2012, 6:30 am
From: Jb Evain <jbev...@gmail.com>
Date: Tue, 14 Aug 2012 12:30:06 +0200
Local: Tues, Aug 14 2012 6:30 am
Subject: Re: [mono-cecil] Code for trimming assemblies crashes with a problem on generics (0.9.4 and 0.9.5)
Hey,

On Mon, Aug 13, 2012 at 4:44 PM, blez <essen...@gmail.com> wrote:
> Any help?

You're probably removing a generic method that is instantiated in a
method you're not removing. Apparently that confuses Cecil greatly.

In the ends, it depends on what you want to achieve. If you want to
delete all the code in an assembly to just have method stubs, it's
quite easy, you simply remove all the instructions of all the methods.

If you want to remove code that is not executed, it's better to use
the Mono.Linker.

Jb


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »