.NET Forum / Languages / C# / February 2008
AccessViolationException in 2008 but not 2005
|
|
Thread rating:  |
rmiller407@gmail.com - 08 Feb 2008 12:34 GMT I am getting an AccessViolationException when calling an old legacy fortran dll from c# in vs2008 express, but the same code worked fine in vs2005.
If I create a vs2005 c# wrapper dll to call the old fortran dll, then I get the exception if I call that wrapper dll from a vs2008 console app, but not if I call it from a vs2005 console app. I've tried changing the vs2008 code to target the 2.0 framework, but I still get the exception. This is all done on the same machine.
I'm running Xpsp2, so I don't think it's the data execution prevention issue. I tried using editbin to change the nxcomp bit in console app exe anyway, but it didn't make any difference. I also tried explicitly excluding that console app exe from the dep through the control panel, and that didn't make any difference either.
I can call a couple of simple utility methods on the dll without getting the exception, but when I call the main processing method then it happens. The dll is old enough that I'm sure there really is a memory allocation or pointer problem in there. But I need to use it from vs2008 and I can't get the dll changed.
Any thoughts about what changed in vs2008 that might have caused this, and what I might be able to do to work around it?
If it helps, the call to the main processing method looks like this: [DllImport("foo.dll", EntryPoint = "foo")] protected static extern void foo(ref InputData inputData, ref OutputData outputData);
The InputData and OutputData are structures that include old fortran style fixed arrays and types. They're quite large, so I won't post the whole thing uless you think it's important. But here's a subset as an example:
[StructLayout(LayoutKind.Sequential)] public struct OutputData { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public char[] Version; public int ValidSolution; public int ErrorNo; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 500)] public char[] ErrorMessage; public int NumberOfUnits; }
Thanks in advance for your help.
Marc Gravell - 08 Feb 2008 12:49 GMT I can't advise on the interop, but if 2005 works, perhaps build a wrapper assembly (class library) in 2005 that does the interop; close 2005, open your main project in 2008 and add a reference to your shiny new class library. This should work if it is purely a compiler issue.
However, it could also be an SP1 issue (but then I'd expect both 2005 and 2008 on the same machine to fail).
Marc
rmiller407@gmail.com - 08 Feb 2008 12:52 GMT Thanks Marc, but I tried that. If I make a wrapper dll in vs2005, then it works fine if I call that wrapper from a vs2005 exe, but not if I call it from a vs2008 exe.
Any other ideas?
Marc Gravell - 08 Feb 2008 13:09 GMT Can I clarify; is this all on the same machine?
Marc
rmiller407@gmail.com - 08 Feb 2008 13:23 GMT Yes, it is all on the same machine.
Rob
Marc Gravell - 08 Feb 2008 13:42 GMT OK; that's odd.
... {stumped} ...
Willy Denoyette [MVP] - 08 Feb 2008 15:54 GMT >I am getting an AccessViolationException when calling an old legacy > fortran dll from c# in vs2008 express, but the same code worked fine [quoted text clipped - 44 lines] > > Thanks in advance for your help. Please post the complete exception message. Looks like an invalid pointer issue inside the Fortran function you are calling, or the addresses you are passing are invalid (not sure why you are passing the input structure by ref though), or the fortran code is accessing locations outside of the structure passed in (structure size error) .
Willy.
Marc Gravell - 08 Feb 2008 16:02 GMT (Cheers, I was kind-of hoping you might spot this one ;-p)
Willy Denoyette [MVP] - 08 Feb 2008 16:30 GMT > (Cheers, I was kind-of hoping you might spot this one ;-p) Well, all I know is that the OP is dealing with some invalid pointer issue. One could argue why this works in V1.X and not in V2, one of the the reasons might be that V2 is linked with the safe CRT library, and the interop layer enforces more strict pointer validation rules. So it's possible that this faulty code ran 'perfectly' well on V1.X but fails (as it should) on V2.
Willy.
rmiller407@gmail.com - 08 Feb 2008 16:50 GMT Thanks Willy. That makes sense, and that means I'm probably out of luck. I may have to try to reverse-engineer that old dll. :-(
Rob
Willy Denoyette [MVP] - 08 Feb 2008 17:21 GMT > Thanks Willy. That makes sense, and that means I'm probably out of > luck. I may have to try to reverse-engineer that old dll. :-( > > Rob Before you do that, could you post that piece piece of code that calls the function, including the part that creates the structure references. I really would like to know why you are passing both arguments by-ref, IMO the Fortran function, takes an IN and an OUT argument, so you might try by changing the caller side accordingly.
Willy.
rmiller407@gmail.com - 08 Feb 2008 18:06 GMT I can change the outputData parameter to pass as ref or as out and there is no difference in the results -- works fine in vs2005, AccessViolationException in vs2008. If I take the ref tag off of the inputData parameter then I get an AccessVoilationException in both vs2005 and vs2008.
Rob
Willy Denoyette [MVP] - 08 Feb 2008 19:56 GMT >I can change the outputData parameter to pass as ref or as out and > there is no difference in the results -- works fine in vs2005, [quoted text clipped - 3 lines] > > Rob Weird, most importantly because you are running this on the same system, that is, both versions run with the same CLR and JIT compiler (v2 SP1). Mind to post some of the caller's code, or a small but complete sample that illustrates the problem?
Willy.
Willy Denoyette [MVP] - 08 Feb 2008 22:05 GMT >I can change the outputData parameter to pass as ref or as out and > there is no difference in the results -- works fine in vs2005, [quoted text clipped - 3 lines] > > Rob Can you verify whether you have the "NX compatible" bit set in the optional headers of the VS2005 exe, you can do this by means of running dumpbin /headers | findstr "DLL characteristics". It should output exactly this:
540 DLL characteristics Which means "NX compat" is on and you can forget the remaining of this post. If the output differs, you may have a DEP issue caused by your Fortran DLL. In this case you can turn the "NX compatible" bit off (on the VS2008 exe) by running editbin /nxcompat:no <your.exe>
Willy.
rmiller407@gmail.com - 11 Feb 2008 12:16 GMT Running dumpbin /headers | findstr "DLL characteristics" on the exe didn't produce any output. I had tried running editbin /nxcompat:no on the exe before and it did not make any difference.
> Mind to post some of the caller's code, or a small but complete sample that > illustrates the problem? Would you mind if I just emailed an example project to you, Willy? The fortran dll comes from another company and I am not comfortable posting it all to a public site.
Rob
Willy Denoyette [MVP] - 11 Feb 2008 15:11 GMT > Running dumpbin /headers | findstr "DLL characteristics" on the exe > didn't produce any output. I had tried running editbin /nxcompat:no [quoted text clipped - 9 lines] > > Rob Ok, go ahead ;-)
Willy.
rmiller407@gmail.com - 11 Feb 2008 15:34 GMT I figured it out, and I feel like an idiot. The problem is that I have to pass a path to the fortran dll so it knows where to load its data files from. I had my vs2005 projects under c:\source, but my vs2008 test projects in the default directory deep under "documents and settings". All those extra directory characters in the vs2008 path overflowed the file path buffer in the fortran code and caused the pointer exception. If I run the vs2008 code out of a directory with a shorter path then it works fine. I figured it out when I was trying to put together an example project for Willy and could not understand why it behaved differently.
Thank you Marc and Willy for your help. Even though I figured it out myself, I may not have done so without your help. Much appreciated.
Rob
Marc Gravell - 08 Feb 2008 19:32 GMT > One could argue why this works in V1.X and not in V2 2005 vs 2008 - both v2 and the same runtime, surely?
Willy Denoyette [MVP] - 08 Feb 2008 19:49 GMT >> One could argue why this works in V1.X and not in V2 > > 2005 vs 2008 - both v2 and the same runtime, surely? Sure, my bad, I meant V2. and V2 SP1. Sorry for the confusion.
Willy.
Marc Gravell - 08 Feb 2008 20:00 GMT No problem (I do much worse ;-p)
But (and hence my specific questions to the OP) - my understanding (please correct me if I'm wrong) is that SP1 isn't side-by-side, so both 2005 and 2008 code would be running on SP1 (since it is the same machine). And the 2005 class library would seem to discount any compiler-specific wossit. Very interesting.
Marc
Willy Denoyette [MVP] - 08 Feb 2008 20:30 GMT > No problem (I do much worse ;-p) > [quoted text clipped - 3 lines] > machine). And the 2005 class library would seem to discount any > compiler-specific wossit. Very interesting. Exactly, this means that , assuming the source code is the same, both runs should fail/succeed, unless the generated IL is different.
Willy.
rmiller407@gmail.com - 08 Feb 2008 16:15 GMT Here's the exception message:
System.AccessViolationException was unhandled Message="Attempted to read or write protected memory. This is often an indication that other memory is corrupt." Source="OldFortranDllWrapper" StackTrace: at OldFortranDllWrapper.FortranDll.foo(InputData& inputData, OutputData& outputData) <snip> the rest of the stack trace is just my code down to this call </ snip> InnerException:
I agree that it is probably a bad pointer or memory allocation in the fortran dll. But it works when the calling c# exe was created in vs2005, but not in vs2008. Is vs2008 less forgiving of this type of thing, and if so is there a way of turning that off or working around this?
Rob
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|