There is a third-party library on the pros that takes the log from the device (a fingerprint scanner) and gives it to the managed code. The library periodically asks the device which users are loaded onto it and which are not loaded there by the user with fingerprints. The period of 1 hour. Parameters are passed correct.

The problem is in the occurrence of an error at an unpredictable point in time when the C ++ library crashes. More specifically, when trying to pick up the list of users downloaded to the device, even when the list of users and fingerprints has not changed.

I tried to add the attributes HandleCorruptState and catch AccessViolation, Win32Exception, ExternalException, Exception, individually and all taken together and nothing, the process just drops.

Version .NET 4.6.1.

PS I caught AccessViolation in the first place, because with the wrong parameters passed to the positive lib, she threw this exception. The output to the log when UnhandledException also exists and the logs are empty.

QUESTION: How to solve this problem? Either catch an exception, or somehow isolate the workspace so that it can be reloaded.

Code: https://pastebin.com/MZB9VwY9

  • one
    Write your own C ++ wrapper for this library, and use it in C # code. Exportable functions must be declared extern C - NewView

1 answer 1

Such a crash may occur when a managed heap is damaged. A heap can be damaged if you pass a managed array to the library, and it writes something beyond its boundaries. Or remembers the address and addresses to it when there already nothing lies. If you suspect a similar situation - try adding a method that catches exceptions, the attribute [HandleProcessCorruptedStateExceptions] - this will help to catch such a situation. But this is only a diagnostic tool, a program with a damaged heap is inoperative.

If the matter is true in heap damage, then you can do this.

First, you need to check (by reading the documentation) how long the library is going to keep the arrays passed to it. If it is longer than one method call, then it is necessary to allocate to it a copy of the array using Marshal.AllocHGlobal . The same applies to any link-passed structures.

Secondly, if there is a suspicion that all the calls are correct, and the problem is to go abroad, then you need to allocate memory through VirtualAlloc , leaving on both sides of the reserved page. This will help turn an array overflow into an immediate AccessViolationException that can be handled.


But crash of the C ++ library is not necessarily accompanied by an exception. Here are other possible ways:

std :: quick_exit , std :: exit , std :: abort , std :: terminate

And all - only standard methods, and in fact there is also WINAPI ...

If the library uses any of the above, it should be isolated into a separate child process, and restarted when it crashes. At the same time get rid of possible memory leaks on the side of the library. You can communicate with the child process via Remoting, WCF or via the binary binary protocol.

  • I myself thought about isolation in a separate process, but I also thought there could be a more elegant solution. Thank - Yegor Ohotin