Noobie3001
Noobie3001

Reputation: 1251

C# Occasional AccessViolationException

I have a third party library that sometimes causes the AccessViolationException. I've marked the culprit line. I'd really like this method to fail gracefully so that my calling code can try it again in a short time, but at the moment, this exception brings down the whole application.

    public static PlayerModel GetModel(int instanceId)
    {
        try
        {
            // New player model.
            PlayerModel model = new PlayerModel();

            // Fill.
            model._flakyLibrary = new FlakyLibrary(instanceId); // **Sometimes crashes**
            model.instanceId = instanceId;

            // Return the new player model.
            return model;
        }
        catch
        {
            // Try again in a bit - the game is not fully loaded.
            return null;
        }
    }

One thought I had was to start a child process to run this bit of logic and have that crash gracefully if it needs to - I don't know how to do this, let alone have one process return this kind of object (my custom PlayerModel) to another process. I have exhausted searching Google and Stack Overflow (maybe I'm asking the wrong questions?).

Solution

Huge thanks to Theodoros. I've added the following attributes to the above method. The exception is now being caught.

[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]
    [System.Security.SecurityCritical]

P.S - I'm still fascinated to know about the multiple process solution if anyone knows what I should be researching? Many thanks again.

Another edit: I found a solution to using multiple processes: NamedPipeServerStream.

Upvotes: 4

Views: 3654

Answers (1)

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29213

An AccessViolationException is an exception typically raised when your process tries to access memory that's not its own. (Incidentally, a NullReferenceException is just an AccessViolationException at low addresses, served with a different name, to give you a hint as to what caused it.) Thus, it's reasonable to say that this is more or less what happens inside your program: a dereference of an invalid pointer (possibly a null pointer) or access beyond the boundaries of a particular buffer.

If you're not messing with pointers, your code is not responsible for the problem. The constructor you are invoking is responsible for doing something unsafe and invalid. If the library you're using is open source, you can go in and try to diagnose the problem yourself, by looking for suspicious behaviors like those described above. You can then go ahead and try to fix it (and possibly contribute your fix to the developers of that library).

If the above can't be done for any reason, there is a workaround. By default, managed code cannot catch an AccessViolationException, because it's a Corrupted State Exception (CSE), but you can opt-in to handling such exceptions either globally (by applying a fix described in another answer) or per method (by using the [HandleProcessCorruptedStateExceptions] attribute).

However, you'll have to understand the risks taken: your program will be attempting to recover from corrupted state. If you can, try not to use a library that forces you to do that at all.

Upvotes: 5

Related Questions