System.AccessViolationException on overridden abstract method
Asked Answered
B

1

7

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?

Beforetime answered 27/10, 2014 at 11:28 Comment(8)
Are you using unsafe code or an unmanaged library anywhere? Can you post an executable repro? State the CLR version.Quesnay
No, no unsafe code. It's .net 4.0 debugged though visual studio 2013 as shown in the tags. I've worked around it for the time being by using an interface.Beforetime
What is UserApplicationToken?Flush
In case you don't know: Safe managed code should not be able to produce access violations. This is a potential security problem. The CLR is hardened against this. That's why it is likely that something in your process is doing something unsafe and you crash later in time. Create an executable repro. Copy the relevant classes into a new project or delete stuff until the problem disappears. This is a bug that should be reported to Microsoft.Quesnay
Any threads involved?Determinant
This was my first thought @Determinant , but no, no threading.Beforetime
@Liam: Good to know. Most of the time I got this was due to native components not being threadsafe (looking at SqlCeConnection!). Are there any COM stuff there? Correct apartment state?Determinant
No Com, all native lib's. It's a simple web app. I've been meaning to spend a bit of time with the objs passed in but I've been busy and ultimately I have a work around for the time being.Beforetime
P
1

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.

Pine answered 28/10, 2014 at 20:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.