Access Violation Exception Only During C# Unit Tests

Access Violation Exception Only During C# Unit Tests

I'm receving the following error when running my C# unit tests, which access Fortran code through a C++ wrapper:

AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

My code, however, runs fine when I am debugging or running in release mode.  This exception only occurs in the unit tests (in VS2010), so I'm wondering if maybe I am missing something that is required for the unit test to access my fortran code.

In C#:

MyWrapper wrapper = new MyWrapper();

fixed (sbyte* pbyte = cbyte)

{ wrapper.doFORTRAN(pbyte, size); }

In C++:

void MySimulator::MyWrapper::doFORTRAN(char* file, int length){

   DOFORTRAN(file, &length);

}

When running my application (not the unit tests), I can access my Fortran code without any problem once I get to DOFORTRAN in C++, and the application runs successfully.  However, when my unit tests get to DOFORTRAN, it crashes with an AccessViolationException, and I cannot get to the Fortran code.

Is there anything you can think of that could cause this, like maybe a setting I'm missing?  I am new to unit testing, so I appreciate any advice. 

 

 

8 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Show us the C++ declaration of DOFORTRAN, the Fortran declaration of the subroutine (the SUBROUTINE statement and all of the declarations in that subroutine including any directives, and all the compiler options used to compile the Fortran source. Also it would be helpful if you can determine where in the Fortran code the access violation is appearing - does the routine start executing or does it fail before that?

Might be a stack overflow - what happens if you add the /heap-arrays option to the Fortran compile options? (In Visual Studio this is Fortran > Optimization > Heap Arrays - set this to 0.)

Retired 12/31/2016

Hi Steve,

Thanks for the response.  It fails before executing the Fortran code in the unit tests.  I tried making the heap array changes like you suggested, but I'm still running into the same problem.

Here are my Fortran options (from Debug):

/nologo /debug:full /Od /heap-arrays0 /f77rtl /intconstant /warn:interfaces /fp:source /module:"Debug\\" /object:"Debug\\" /Fd"Debug\vc100.pdb" /traceback /check:bounds /libs:static /threads /c

Here is my C++ code:

// MySimulator.h

#include "stdafx.h"

#pragma once

namespace MySimulator {

public ref class MyWrapper{      public:  void doFORTRAN(char* filename, int length);         };

}

// This is the main DLL file.

#include "stdafx.h"

#include "MySimulator.h"

using namespace System;

#pragma unmanaged

extern "C" {

       void DOFORTRAN(char* filename, int* length);

}

#pragma managed

void MySimulator::MyWrapper::doFORTRAN(char* filename, int length){

       DOFORTRAN(filename, &length);

}

In Fortran:

      SUBROUTINE DOFORTRAN(filnam, ilen)

   

      INTEGER ilen

      CHARACTER filnam*ilen

 

      ...And Algorithms here...

Do you mean that it fails before DOFORTRAN is called at all? If so, then nothing on the Fortran side would be relevant.
 

Retired 12/31/2016

Sorry for the confusion.  I mean that when it calls DOFORTRAN in c++, it fails.  It crashes when trying to access the Fortran library it seems when running the unit tests, but it can access it fine when I run the actual application.

Can you see the failure if you run the unit test under the debugger? Can you show us the complete and exact text of the error message? What are the settings for C/C++ > Code Generation > Runtime Library and Fortran > Libraries > Runtime Library in your unit test build? Are these different from when you build the real application?

Retired 12/31/2016

By default, Fortran passes two argument for any character string; one is user defined/declared and is the address of the string,  and the other is a hidden length passed by value.

So for your declaration:

            SUBROUTINE DOFORTRAN (filename, length)

the subroutine is actually expecting 3 arguments, but you're only passing two.   The Fortran prolog code assumes the third argument was passed, and grabs whatever happens to be at that spot on the stack, and that's probably causing the actual problem.

Instead, please remove the LENGTH argument from the Fortran routine, and change the declaration in the C program to

void DOFORTRAN (char *filename, int length)

Then you will be passing the address of the filename, and the hidden length (by value) as expected by the Fortran routine.

 

You could 'use iso_c_binding' to set up the Fortran side to match your choice of C interface.  There, the length parameter would be explicit.

For example,

http://gcc.gnu.org/onlinedocs/gfortran/Interoperable-Subroutines-and-Fun...

shows how the standard C strncpy() works from Fortran (without going into detail about the special provision of Fortran to allow either a character string or an array of c_char).

Note that this was first implemented correctly in ifort 11.1.048.

Leave a Comment

Please sign in to add a comment. Not a member? Join today