AccessViolationException in 2008 but not 2005

R

rmiller407

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.
 
M

Marc Gravell

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
 
R

rmiller407

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?
 
W

Willy Denoyette [MVP]

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.



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.
 
R

rmiller407

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
 
W

Willy Denoyette [MVP]

Marc Gravell said:
(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.
 
R

rmiller407

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
 
W

Willy Denoyette [MVP]

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.
 
R

rmiller407

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
 
M

Marc Gravell

One could argue why this works in V1.X and not in V2

2005 vs 2008 - both v2 and the same runtime, surely?
 
W

Willy Denoyette [MVP]

Marc Gravell said:
2005 vs 2008 - both v2 and the same runtime, surely?


Sure, my bad, I meant V2. and V2 SP1. Sorry for the confusion.

Willy.
 
W

Willy Denoyette [MVP]

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



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.
 
M

Marc Gravell

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
 
W

Willy Denoyette [MVP]

Marc Gravell said:
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.


Exactly, this means that , assuming the source code is the same, both runs
should fail/succeed, unless the generated IL is different.

Willy.
 
W

Willy Denoyette [MVP]

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



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.
 
R

rmiller407

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top