.NET external unmanaged library function throws uncatchable exception

1

I'm using OpenNetCF library in my WindowsCE .NET Compact Framework 3.5 application. The problem is that when I call one of its functions (NetworkInterface.GetAllNetworkInterfaces() to be specific), it randomly throws uncatchable exception and crashes my application:

ExceptionCode: 0x80000002
exceptionAddress: 0x03F928C4
at NativeMethods.WZCDeleteIntfObj(INTF_ENTRY& Intf)
at INTF_ENTRY.Dispose()
at GetAllNetworkInterfaces()

I've search the web and this bug is reported in bug tracer of the OpenNetCF community. Unfortunately, nobody has fixed it yet and I'm pretty sure that nobody is going to fix it. I've got the source code so probably I have to do it myself. I will be happy if I will managed to just catch the exception, without crashing the application.

The method that throws the exception is actually a native method imported in following way:

        //---------------------------------------
        // WZCDeleteIntfObj: cleans an INTF_ENTRY object that is
        // allocated within any RPC call.
        // 
        // Parameters
        // pIntf
        //     [in] pointer to the INTF_ENTRY object to delete
        [DllImport("wzcsapi.dll")]
        public static extern void
            WZCDeleteIntfObj(
            ref INTF_ENTRY Intf);

What can I do to catch the exception from this method?

c#
.net
windows-ce
asked on Stack Overflow Feb 9, 2011 by kmalmur • edited Feb 9, 2011 by kmalmur

4 Answers

1

I faced the similar problem while using the OpenNetCF library in Windows compact framework. The uncatchable native exception was thrown randomly and it crashed the entire application. While investigating the probable causes for this issue, I could get to know that it could be due to memory leaks due to which the system would have ran out of memory or data misalignment.

I called GC.Collect() to reclaim all memory that is inaccessible before calling OpenNETCF.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() method. And this resolved the issue and I didn’t get any native exception thereafter.

GC.Collect() method forces the system to try to reclaim the maximum amount of available memory. All objects, regardless of how long they have been in memory, are considered for collection; however, objects that are referenced in managed code are not collected.

answered on Stack Overflow Jun 27, 2014 by Aishwaryameenakshi • edited Jun 27, 2014 by Matas Vaitkevicius
0

I tend to make all PInvoke calls private, and wrap them in a public method which carries out the Exception catching:

class MyWrappingClass{
    [DllImport("wzcsapi.dll")]
    private static extern void WZCDeleteIntfObj(ref INTF_ENTRY Intf);

    public void useWZCDeleteIntfObj(ref INTF_ENTRY Intf){ //you may wish to use a better method name
        //you may wish to put some guards here, to check that Intf is valid before passing it to the native library.
        try{
             WZCDeleteIntfObj( Intf );
        }catch(ExternalException e){ //try to catch more specific exception types, such as SEHException.
            //handle the exception
        }
    }
}

Any managed code then uses:

MyWrappingClass wrapper = new MyWrappingClass();
wrapper.useWZCDeleteIntfObj( Intf );

MyWrappingClass also serves as a handy place to put helper methods and methods that abstract away some of the underlying PInvoke calls, making dealing with native libraries easier.

answered on Stack Overflow Feb 9, 2011 by Iain Sproat • edited Feb 9, 2011 by Iain Sproat
0

Try using managed C++ to catch the exception as a C++/C exception, and then rethrow as a CLR exception. When pInvoke gets too hard, managed C++ is often a good option.

answered on Stack Overflow Feb 9, 2011 by Ian Ringrose
0

I ran into the same problem. NativeException can not be caught in a c# try/catch. At least not on .NET CF 3.5.

The error thrown is a DataType unalignment exception. which is an error that can occur on e.g. ARM processors, because ARM architecture requires data to be aligned correctly in memory. I looked through the OpenNetCF.Net code, but could not find unalignment issues, maybee i is a bug in the Windows WZZ API causing the error.

I ended up trying to catch the exception in C. The native exception is a SEH exception. Which is the Windows way of implementing exceptions in C. This Means that C++ try/catch wont catch it. The way to catch it is with a __try/__except block.

So I ended up creating a C++ project (Code below). Creating a native DLL which calls WZCDeleteIntfObj in wzcsapi.dll. The code just catch and ignore the exception. Then i retrieved the OpenNet code from codeplex, and modified it to use my native dll as wrapper around wzcsapi's WZCDeleteIntfObj method. Results looks promising, i do however not know if this will cause a memory leak instead.

WZCWrapper.h

#include "stdafx.h"

#define WZCWrapper_API __declspec(dllexport)

typedef struct
{
    DWORD   dwDataLen;
    LPBYTE  pData;
} RAW_DATA, *PRAW_DATA;

typedef struct
{
    LPWSTR          wszGuid;
    LPWSTR          wszDescr;
    ULONG           ulMediaState;
    ULONG           ulMediaType;
    ULONG           ulPhysicalMediaType;
    INT             nInfraMode;
    INT             nAuthMode;
    INT             nWepStatus;
    DWORD           dwCtlFlags;
    DWORD           dwCapabilities;
    RAW_DATA        rdSSID;
    RAW_DATA        rdBSSID;
    RAW_DATA        rdBSSIDList;
    RAW_DATA        rdStSSIDList;
    BOOL            bInitialized;
} INTF_ENTRY, *PINTF_ENTRY;

WZCWrapper.dll

#include "stdafx.h"
#include "WZCWrapper.h"

typedef void (__cdecl *MYPROC)(PINTF_ENTRY);

static HINSTANCE wzcApiDll;
static BOOL initialized;
static MYPROC WZCDeleteIntfObj;

WZCWrapper_API VOID DLL_WZCDeleteIntfObj(PINTF_ENTRY pIntf) {
    if (!initialized){
        wzcApiDll = LoadLibrary(TEXT("wzcsapi.dll"));
        WZCDeleteIntfObj = (MYPROC) GetProcAddress(wzcApiDll, TEXT("WZCDeleteIntfObj"));
        initialized = TRUE;
    }
    __try
    {
        WZCDeleteIntfObj(pIntf);
    }
    __except (GetExceptionCode() == STATUS_DATATYPE_MISALIGNMENT) {
    }
    // FreeLibrary(wzcApiDll); // will release dll (we should not use this, keeping the dll open, as we need it again
}

WZCWrapper.def

LIBRARY "WZCWrapper"
EXPORTS
WZCDeleteIntfObj=DLL_WZCDeleteIntfObj

Modified Part of WZC.C from OpenNetCF.Net

//---------------------------------------
// WZCDeleteIntfObj: cleans an INTF_ENTRY object that is
// allocated within any RPC call.
// 
// Parameters
// pIntf
//     [in] pointer to the INTF_ENTRY object to delete
[DllImport("WZCWrapper.dll")]
internal static extern void
    WZCDeleteIntfObj(
    ref INTF_ENTRY Intf);
answered on Stack Overflow Aug 17, 2015 by Smolf

User contributions licensed under CC BY-SA 3.0