none
AccessViolationException and random crashes using P/Invoke RRS feed

  • Question

  • Hello,

    I have been having sporadic crashes in my .NET 4.0 application that uses one of our native DLLs via P/Invoke. I think I've done my homework, did some reading, verified signatures to prevent stack corruption but even so, crashes still occur. Help would be extremely appreciated.

    Thanks in advance!

    On the native side
    ---------------------

     

    #define DLLEXPORT extern "C" __declspec(dllexport)
    
    DLLEXPORT bool EnumKaiDevices(char * sDeviceVector, int nSize) {
      /* Some Code */
      return true;
    }
    

    Managed side
    ----------------

     

    [DllImport(DBX_KAI_LIB, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.I1)]
    private static extern bool EnumKaiDevices(StringBuilder sDeviceVector, int nSize);
    
    public static bool EnumKaiDevices(out string sDeviceList) {
    	StringBuilder sbDeviceList = new StringBuilder(DEVICELISTSTRINGSIZE);
    	if (false == EnumKaiDevices(sbDeviceList, DEVICELISTSTRINGSIZE)) {
    		sDeviceList = null;
    		return false;
    	}
    
    	sDeviceList = sbDeviceList.ToString();
    	return true;
    }
    

    One of the exceptions seen in Event Viewer
    -------------------------------------------------

     Application: KioskControl.exe

    Framework Version: v4.0.30319

    Description: The process was terminated due to an unhandled exception.

    Exception Info: System.AccessViolationException

    Stack:

       at Microsoft.Win32.Win32Native.CoTaskMemAlloc(Int32)

       at System.Runtime.InteropServices.Marshal.AllocCoTaskMem(Int32)

       at KaiDiagnostic.MKaiDiagWrapper.EnumKaiDevices(System.Text.StringBuilder, Int32)

       at KaiDiagnostic.MKaiDiagWrapper.EnumKaiDevices(System.String ByRef)

       at KioskControl.KaiMonitor.GetDeviceNameList()

       at KioskControl.KaiMonitor.OnLoop()

       at dbox.ServiceBase.WorkerThread()

       at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)

       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)

       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

       at System.Threading.ThreadHelper.ThreadStart()

    Thursday, June 23, 2011 2:00 PM

Answers

  •  

    Hi,

     

    According to your description, I note that you allow a stringbuilder object to the unmanaged method. May I know whether the value will be changed in the unmanaged method?

     

    Because the unmanaged just return a BOOL type, I think that it is not necessary to pass a managed stringbuilder object to unmanaged method. You can try to modify the unmanaged method as below:

    DLLEXPORT bool EnumKaiDevices( int nSize) {

    char * sDeviceVector  /* Some Code */
     
    return true;
    }

     

    You can allow the memory space only in unmanaged memory, after using it, release it. So the access exception between managed memory and unmanaged memory could be avoided.

     

    I hope this can help you.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Proposed as answer by Paul Zhou Friday, July 1, 2011 5:58 AM
    • Marked as answer by Paul Zhou Tuesday, July 5, 2011 4:51 AM
    Monday, June 27, 2011 10:29 AM