Forums

Bug with a .NET DLL, not sure how to trace

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

Bug with a .NET DLL, not sure how to trace

Postby CodexArcanum » Thu Apr 29, 2010 5:00 pm

I'm getting an old build error relating to my use of libtcod-net. It's a roguelike engine wrapper, the core DLL is written in C and there's a .net wrapper. Now, I understand this isn't Cobra's problem but for three things:
1) The error message is really not helping me out here.

G:\Projects\Cobra\libtcobra>cobra trybuild
error: COBRA INTERNAL ERROR / BadImageFormatException / Could not load file or a
ssembly 'file:///G:\Projects\Cobra\libtcobra\libtcodWrapper.dll' or one of its d
ependencies. An attempt was made to load a program with an incorrect format.
Compilation failed - 1 error, 0 warnings
Not running due to errors above.


2) I can build it in Visual Studio and use it, so there's no problem I can find inherent to the wrapper.

3) It was building earlier on my WIndows XP box. But on my Windows 7 box, I get that error.

Now, is there any way I can get a more details explanation of the error (I tried the verbosity flags to no avail) or does anyone have an idea on correcting this?
CodexArcanum
 
Posts: 21

Re: Bug with a .NET DLL, not sure how to trace

Postby Charles » Thu Apr 29, 2010 9:08 pm

You say you can use it in Visual Studio, but also mention that you can use it on XP, but not Win 7. In Visual Studio, are you able to use it on both XP and Win 7 or just XP?

Regarding a more detailed explanation of the error, there isn't going to be any directly from the Cobra compiler. The compiler itself is a .NET program and when it attempts to load the assembly, the BadImageFormatException occurs. The reason why is internal to the .NET standard library that loads the DLL and not the compiler.

The docs at MSDN point to at least 4 possible causes. It's unfortunate that they don't give a different exception and/or state.

Let me know on the above question.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Bug with a .NET DLL, not sure how to trace

Postby CodexArcanum » Fri Apr 30, 2010 12:52 am

In Visual Studio, I'm able to build the project containing that library in both XP and Win7, and run the demo program that uses the library. I'm also able to build and run other Cobra programs on both computers.

Looking over the MSDN article, it may be a 64-bit issue. My home computer is Win7 64-bit while my work computer is 32-bit XP. Unfortunately I'm also using VS2005 and .NET 2 at work but .NET 4 and VS2010 at home, so that adds another compounding to the issue. I should also mention that I tried loading the original dll (from a binary release by the author) first, then tried building it myself in VS2010, neither one worked. The original binary release is the library that Cobra could use just fine on WinXP. I haven't yet tried the other way around (the newly built library on WinXP).

Going over the possible causes one by one:
1. I haven't used any .NET utilities, unless Cobra itself falls into this category. It recommends modifying the PATH to change which version of the tool is used, so I'm thinking that's not the cause.
2. There are unmanaged DLLs involved. The wrapper library takes advantage of a C library, which itself uses SDL and zlib1. But these work fine on the other computer, so I don't think that would be the issue.
3. A 32-bit assembly is loaded as a 64-bit one. This feels likely to me, though I'm not sure what would cause it to load the library incorrectly. Would Cobra somehow be choosing 64-bit framework over 32-bit?
4. The last possibility is that an early version of the framework is loading a later version assembly. It seems to be the opposite case here though. At worst I'd be using 4.0 to load a 2.0 library, but I'm guessing that Cobra knows to use the 2.0 stuff.

So I'm guessing it must have something to do with the 64-bit versions. I sometimes think 64-bit computing is far more trouble than it's worth. :|
CodexArcanum
 
Posts: 21

Re: Bug with a .NET DLL, not sure how to trace

Postby CodexArcanum » Fri Apr 30, 2010 1:18 am

Ok, it was definately the 64-bit issue and I've found a "solution" of sorts. First up, this post clued me onto the possible solution, and then this blog entry has some further thoughts on a similar issue.

The basic problem is that everything in the framework gets run as 64-bit, which is normally not a big deal, but becomes a problem when calling into native libraries as the wrapper is doing. Then it has to match up with either 32-bit or 64-bit. The simple fix is to go to C:\Windows\Microsoft.NET\Framework64\v2.0.50727 and call
Code: Select all
ldr64 setwow
to force the system into always using 32-bit .NET. To clear the flag and go back to 64-bit, you call
Code: Select all
ldr64 set64
.

After I set my machine into 32-bit mode, the Cobra compiler worked perfectly and my program ran. Unfortunately the binary file won't run once the flag is reset, even if it was built in 32-bit mode. So my program will be stuck as 64-bit incompatible until I can track down a final solution to the problem (which may be as useless as "find 64-bit native libraries"), but at least I can build and work on it again.


Thanks for helping me track down the exception in MSDN, I feel kind of lazy for not having thought to do that myself. I hope the solution I found helps anyone else who might have this issue.


EDIT:

On-going discoveries: I tried rebuilding the wrapper library to target x86 platforms in VS to force the application into 32-bit mode. Turns out this setting was already on, so I tried "Any CPU" instead. With that option, Cobra can successful build the library into the application, but then the app itself crashes with this error:
Unhandled Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: obj
at Cobra.Lang.CobraImp.GetPropertyValue(Object obj, String propertyName)
at Game.Dispose()
at Program.Main()
at MainWrapper.Main()


The relevant bit of code is:
Code: Select all
var scon
var con as RootConsole?

def run
        .con = RootConsole.getInstance
        .scon = RootConsole.getNewConsole(46, 20)

def dispose
        .con.dispose
        .scon.dispose


So trading one problem for another. Don't think just changing the platform is going to do the trick here. :(
CodexArcanum
 
Posts: 21

Re: Bug with a .NET DLL, not sure how to trace

Postby Charles » Fri Apr 30, 2010 2:43 am

Thanks, that's great info.

Regarding your edit, can you guard the last two statements to avoid nil/null?
def dispose
if .con, .con.dispose
if .scon, .scon.dispose

I think it's the last one that is choking as the exception includes "Cobra.Lang.CobraImp.GetPropertyValue" which I happen to know is part of the dynamic machinery, and only your .scon is dynamic.

Let me know. Maybe Cobra's dynamic binding needs a more obvious "NullReferenceException" like what "obj.foo" gives for static typing when "obj" is nil/null.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Bug with a .NET DLL, not sure how to trace

Postby CodexArcanum » Fri Apr 30, 2010 11:44 am

Late last night I tried setting up the guards on it as you recommended, and I didn't get the null/nil error again. The program still crashed from the other problem mind you, but I didn't get an exception about it. So I'm guessing the dll loading is still throwing exceptions, but at least my disposal code and using statements are working correctly!
CodexArcanum
 
Posts: 21

Re: Bug with a .NET DLL, not sure how to trace

Postby Charles » Sat May 01, 2010 1:37 am

Given that got far enough for that code to execute, I don't think the DLL loading is what's crashing. I think you're left with the 32bit/64bit/native issues after the DLL is loaded.

Poking around the project pages like the Issues and the forums, other people seem to be struggling as well. Maybe there is useful info there.

Good luck.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Bug with a .NET DLL, not sure how to trace

Postby CodexArcanum » Tue May 04, 2010 4:01 pm

Hey, I finally found what I think is the correct solution to this problem. So I mentioned before that one can set the mode .NET CLR tries to run programs in, which will correct this issue. Looking at the C# fixes to this error, it seems the problem occurs when a 64-bit assembly tries to load a 32-bit native DLL. You get around this in C# by building against the x86 platform, instead of x64 or Any. "Any" is the default, and will run in whatever is native to the machine, 64-bit in my case.

So anyway, long story short, you have to tell the .NET compiler to build for x86, like this:
cobra -sharp-args:"/platform:x86" Main


or I can just put this on my .cobra file: @args -sharp-args:"/platform:x86"

Woot!
CodexArcanum
 
Posts: 21

Re: Bug with a .NET DLL, not sure how to trace

Postby Charles » Wed May 05, 2010 4:01 am

Excellent! Thanks for following this through and sharing what you found. I have added this to the new Troubleshooting wiki page. Feel free to edit the entry for this problem as I may not have perfectly captured the final form in which the solution should be presented.
Charles
 
Posts: 2515
Location: Los Angeles, CA


Return to Discussion

Who is online

Users browsing this forum: No registered users and 49 guests