Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.AccessViolationException on overridden abstract method

a bit confused as to why I'm having an issue. It's taken me sometime but having broken the issue down to it's simplest case I get the following strange (to my eyes anyway) behaviour.

I have a base class:

public abstract class FailedSubmitterBase
{

    public FailedSubmitterBase(UserApplicationToken userApplicationToken)
    {
    }

    public abstract int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails,
        string crmUsername, string crmSuperUsername);
}

and a child instance:

public class CoreFailedSubmitter : FailedSubmitterBase
{
    private string _emptyNarrativeString = "Failed to post to CS - Unspecified Error";

    protected UserApplicationToken _userApplicationToken;

    public CoreFailedSubmitter(UserApplicationToken userApplicationToken) : base(userApplicationToken)
    {
        _userApplicationToken = userApplicationToken;
    }
        /**/
    public override int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails, string crmUsername, string crmSuperUsername)
    {
        return 0;
    }
}

when I call this thus:

CoreFailedSubmitter failedSubmitter = new CoreFailedSubmitter(_userApplicationToken);

return failedSubmitter.ResubmitFailed(request, csItinerary, impersonatedUser, basketItem, crmResponseDetails, crmUsername, crmSuperUsername);

I get System.AccessViolationException:

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

I've replicated it (while debugging) on several machines so I don't believe it is an actual memory issue.

What I don't understand is that if I simply remove the abstract method it works fine e.g.:

public abstract class FailedSubmitterBase
{

    public FailedSubmitterBase(UserApplicationToken userApplicationToken)
    {
    }
 }


public class CoreFailedSubmitter : FailedSubmitterBase
{
    private string _emptyNarrativeString = "Failed to post to CS - Unspecified Error";

    protected UserApplicationToken _userApplicationToken;

    public CoreFailedSubmitter(UserApplicationToken userApplicationToken) : base(userApplicationToken)
    {
        _userApplicationToken = userApplicationToken;
    }
        /**/
    public int ResubmitFailed(ProviderRequest request, Access.CentralServices.CSService.Itinerary csItinerary,
            ImpersonatedUserDetails impersonatedUser, BasketItem basketItem, CRMResponseDetails crmResponseDetails, string crmUsername, string crmSuperUsername)
    {
        return 0;
    }
}

Why does having the abstract method cause this to fail with this exception? I can't see any reason for it. What am I missing?

Update

By re-factoring my code a bit I removed the abstract class and replaced it with an interface. This works. For all intents and purposes though the interface and abstract class are doing the same thing. I can't really understand why this fails like it does. The only thing that stands out to me is this class Access.CentralServices.CSService.Itinerary csItinerary. This is a auto generated SOAP class, but again, this is simply a normal class isn't it really?

like image 548
Liam Avatar asked Oct 27 '14 11:10

Liam


1 Answers

Something has corrupted the memory. The reason that you don't see that when removing the abstract class is that there's no Virtual Call being made, thus, no indirect memory access (pointer) is necessary.

Now, what has corrupted your memory? From your description, considering the problem is always reproducible, then it's deterministic. So whatever you did leading up to the method call is corrupting memory. My guess would be either whatever you did inside those classes or in order to build the objects of those classes:

UserApplicationToken 
ProviderRequest 
ImpersonatedUserDetails 
BasketItem 
CRMResponseDetails 

So you should look into them with care. As @usr stated on comments, safe CLR code should not produce access violations, so either you found a problem with the CLR / compiler (VERY unlikely) or one of those classes you are using is the culprit. Another guess: those tokens and impersonations wouldn't happen to be calling on native Win32 libs, would they? Interop is the same as calling unsafe code.

like image 200
Bruno Brant Avatar answered Nov 15 '22 01:11

Bruno Brant