This project is read-only.
2
Vote

MrefBuilder /internal+ crashes on DundasWinGauge.dll

description

I can't document my project's internals because MrefBuilder v2.4.10520.1 fails with “unknown access level” when run against two Dundas control assemblies with internals enabled. This is with DundasWinGauge assembly version 2.0.2.201, and DundasWinChart assembly version 5.5.1.1711.
 
Dundas have granted me permission to upload the assemblies for troubleshooting purposes.
 
C:>mrefbuilder /internal+ DundasWinChart.dll > nul
 
Unhandled Exception: System.InvalidOperationException: Unknown access level for DC01.ar.a(System.String)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.GetVisibility(Member api)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.WriteMemberData(Member member)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.WriteMember(Member member, TypeNode type)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.VisitMember(Member member)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitMembers(MemberList members)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitType(TypeNode type)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.VisitType(TypeNode type)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitTypes(TypeNodeList types)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitNamespace(Namespace space)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.VisitNamespace(Namespace space)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitNamespaces(NamespaceList spaces)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.VisitNamespaces(NamespaceList spaces)
at Microsoft.Ddue.Tools.Reflection.ApiVisitor.VisitApis()
at Microsoft.Ddue.Tools.MRefBuilder.Main(String[] args)
 
C:>mrefbuilder /internal+ DundasWinGauge.dll > nul
Unhandled Exception: System.InvalidOperationException: Unknown access level for Dundas.Gauges.WinControl.bn.a(System.String)
at Microsoft.Ddue.Tools.ManagedReflectionWriter.GetVisibility(Member api)

file attachments

comments

SelormeyPaul wrote Oct 28, 2008 at 3:20 PM

You are trying to document an obfuscated code, and this will most likely not work depending on the type of obfuscation used.

EWoodruff wrote Oct 28, 2008 at 4:18 PM

Obfuscation aside, MRefBuilder should still not crash. At the very least it should catch the exception and do something such as assume private for visibility and issue a warning.

davedev wrote Oct 28, 2008 at 6:11 PM

The problem appears to be that MRefBuilder doesn't support privatescope visibility, which is added by the obfuscator. Without looking at the MRefBuilder source code, it seems possible that this issue would require major refactoring to get it working correctly against obfuscated assemblies given that privatescope visibility allows for members with duplicate signatures. Therefore, if MRefBuilder identifies members internally via their signatures and not their metadata tokens then adding support for this scenario may be a major change.

From the description on MSDN:

PrivateScope: Indicates that the member cannot be referenced.

http://msdn.microsoft.com/en-us/library/system.reflection.methodattributes.aspx

garthrk wrote Oct 28, 2008 at 11:20 PM

I'm not trying to document obfuscated code, Paul. I'm trying to document my own code.

Sandcastle uses the same MrefBuilder options for all assemblies in or referenced by the project (work item #2969). If I want to document my internals, Sandcastle will call MrefBuilder with /internals+. If one of the referenced assemblies is obfuscated, MrefBuilder crashes and I can't get my documentation.

I don't mind whether MrefBuilder ignores the member. I do, however, need it to not crash.

garthrk wrote Oct 29, 2008 at 12:29 AM

Adding

else if (!api.IsVisibleOutsideAssembly) return ("obfuscated");

to GetVisibility before the final else seems to do the trick. I'm having trouble figuring out how to test api.Attributes against System.Reflection.MethodAttributes.PrivateScope.

SelormeyPaul wrote Oct 30, 2008 at 6:45 AM

garthrk: I'm not trying to document obfuscated code.
You are.
garthrk: If I want to document my internals, Sandcastle will call MrefBuilder with /internals+.
Yes, dependent fields you are using are internal to your assembly, and they happen to be obfuscated.

garthrk: else if (!api.IsVisibleOutsideAssembly) return ("obfuscated");
The "obfuscated" is not supported by the current reflection schema, so you are on your own here.
If you need to discuss, post to the dicussion section.

EWoodruff wrote Oct 31, 2008 at 2:53 AM

For a patched version of MRefBuilder.exe that fixes this issue, download the PatchedMRefBuilder.zip file and extract it into the C:\Program Files\Sandcastle\ProductionTools folder. For questions or discussions, see the discussion thread: http://www.codeplex.com/Sandcastle/Thread/View.aspx?ThreadId=38907

wrote Oct 31, 2008 at 2:53 AM

garthrk wrote Oct 31, 2008 at 6:00 AM

Paul, either I don't understand what you mean when you tell me I am trying to document obfuscated code, or you don't understand what I mean. Let's figure it out:

None of my namespaces are obfuscated.

Sandcastle require that all referenced assemblies be included in the project file.

Some of those assemblies are obfuscated.

I have told Sandcastle to not document the namespaces exported by those assemblies.

Do you still believe that I am trying to documented obfuscated code? If so: how did you reach that conclusion?

Yours,
Garth.

garthrk wrote Oct 31, 2008 at 6:02 AM

Thanks, Eric.

SelormeyPaul wrote Oct 31, 2008 at 8:31 AM

Hello Garth,
The command line you gave: C:>mrefbuilder /internal+ DundasWinGauge.dll
means you are documenting the DundasWinGauge.dll.

Let me get this clear...
Garth: Sandcastle require that all referenced assemblies be included in the project file.
Are you using the obfuscated dll as dependencies (with the /dep: option) or directly as part of your "project file"?
Best regards,
Paul.

EWoodruff wrote Oct 31, 2008 at 4:26 PM

If you don't want dependencies documented, add them using the /dep switch (MRefBuilder command line) or the Dependencies property in SHFB. That prevents them from being documented but still allows them to be found for references and for inherited info in the class members pages. I assumed that was the case in your project and that the example was just to illustrate the problem.

However, it's still possible that if one of your types derives from a type that causes the original problem due to obfuscated private members it would still fail when it looked at the base type for inheritance info, etc. As such, I think the fix is still relevant.

SelormeyPaul wrote Oct 31, 2008 at 5:07 PM

Eric: As such, I think the fix is still relevant.
Not in this case, what is causing the problem is a static class, it cannot be a private member of any class.

wrote Jan 28, 2009 at 1:45 PM

wrote Feb 22, 2013 at 1:40 AM