runtime: IOCompletionCallback of ThreadPoolBoundHandle causes the app to crash

I’m using pinvoke to wrap windivert into dotnet library with a prototype method like this:

[DllImport(library, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool WinDivertRecvEx(
    WinDivertHandle handle,
    SafeHandle pPacket,
    int packetLen,
    ref int pRecvLen,
    ulong flags,
    ref WinDivertAddress pAddr,
    int* pAddrLen,
    NativeOverlapped* lpOverlapped); 

My csharp code is as follows: https://github.com/xljiulang/WindivertDotnet/blob/async-task/WindivertDotnet/WindivertOperation.cs https://github.com/xljiulang/WindivertDotnet/blob/async-task/WindivertDotnet/WindivertRecvOperation.cs

After the application has been running for a few minutes, the program throws a crash exception:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Runtime.CompilerServices.TaskAwaiter`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].GetResult()
   at App.Program+<Main>d__0.MoveNext()
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[[System.Threading.Tasks.VoidTaskResult, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext(System.Threading.Thread)
   at System.Runtime.CompilerServices.TaskAwaiter+<>c.<OutputWaitEtwEvents>b__12_0(System.Action, System.Threading.Tasks.Task)
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action, Boolean)
   at System.Threading.Tasks.Task.RunContinuations(System.Object)
   at System.Threading.Tasks.Task`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TrySetResult(Int32)
   at System.Threading.Tasks.TaskCompletionSource`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].TrySetResult(Int32)
   at System.Threading.Tasks.TaskCompletionSource`1[[System.Int32, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].SetResult(Int32)
   at WindivertDotnet.WindivertOperation.SetResult(Int32)
   at WindivertDotnet.WindivertRecvOperation.SetResult(Int32)
   at WindivertDotnet.WindivertOperation.IOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)

Before the process disappeared, I dump the process down as dump file, can anyone help me? Thanks a lot.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (9 by maintainers)

Most upvoted comments

Yes, but NativeMemory is dotnet6’s exclusive api.

@AaronRobinsonMSFT Thank you very much for your help! According to your tips, I seem to have found the cause of the problem: Pointer of addrLength. Because the new value needs to be written to this Pointer during IO callback, it cannot point to the addrLength variable in the method, but should be a fixed value and free after IO callback.

1