C# AccessViolationException的Stacktrace是否可信

C# AccessViolationException的Stacktrace是否可信,c#,clr,access-violation,C#,Clr,Access Violation,在我们的一个服务中引发了AccessViolationException。我们注册了AppDomain.CurrentDomain.UnhandledException,并从调用堆栈下面的事件中获得。事件在2秒内在三个不同线程上引发了三次,并且具有完全相同的堆栈。所以一切都应该清楚 另一方面,windows事件日志中的相关日志项完全没有显示堆栈。我们的应用程序也使用非托管库,我猜想异常是由误用它们(例如oci)而不是所示的托管堆栈引起的 我可以相信报告的堆栈就是导致问题的堆栈吗?或者这只是一个有

在我们的一个服务中引发了AccessViolationException。我们注册了AppDomain.CurrentDomain.UnhandledException,并从调用堆栈下面的事件中获得。事件在2秒内在三个不同线程上引发了三次,并且具有完全相同的堆栈。所以一切都应该清楚

另一方面,windows事件日志中的相关日志项完全没有显示堆栈。我们的应用程序也使用非托管库,我猜想异常是由误用它们(例如oci)而不是所示的托管堆栈引起的

我可以相信报告的堆栈就是导致问题的堆栈吗?或者这只是一个有根据的猜测

System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Linq.EnumerableSorter`2.ComputeKeys(TElement[] elements, Int32 count)
   at System.Linq.EnumerableSorter`1.Sort(TElement[] elements, Int32 count)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__0.MoveNext()
   at System.Linq.Enumerable.<TakeIterator>d__3a`1.MoveNext()
   at System.Data.Services.QueryResultInfo.MoveNext()
   at System.Data.Services.DataService`1.SerializeResponseBody(RequestDescription description, IDataService dataService, IODataResponseMessage responseMessage)
   at System.Data.Services.DataService`1.HandleRequest()
   at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody)
   at SyncInvokeProcessRequestForMessage(Object , Object[] , Object[] )
   at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
   at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
   at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
   at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
   at System.Runtime.InputQueue`1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
   at System.Runtime.InputQueue`1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
   at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
   at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult result)
   at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult result)
   at System.Runtime.AsyncResult.SyncContinue(IAsyncResult result)
   at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
   at System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state)
   at System.ServiceModel.Channels.SharedHttpTransportManager.EnqueueContext(IAsyncResult listenerContextResult)
   at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult listenerContextResult)
   at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
   at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
   at System.Net.ListenerAsyncResult.IOCompleted(ListenerAsyncResult asyncResult, UInt32 errorCode, UInt32 numBytes)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
System.AccessViolationException:尝试读取或写入受保护内存。这通常表示其他内存已损坏。
at System.Linq.EnumerableSorter`2.ComputeKeys(远程通讯[]元素,Int32计数)
在System.Linq.EnumerableSorter`1.Sort处(TElement[]元素,Int32计数)
在System.Linq.OrderedEnumerable`1.d_u0.MoveNext()中
在System.Linq.Enumerable.d_u3a`1.MoveNext()中
在System.Data.Services.QueryResultInfo.MoveNext()中
在System.Data.Services.DataService`1.SerializeResponseBy(请求描述、IDataService数据服务、IodataResponseMessageResponseMessage)
at System.Data.Services.DataService`1.HandleRequest()
位于System.Data.Services.DataService`1.ProcessRequestFormMessage(StreamMessageBody)
在SyncInvokeProcessRequestFormMessage(对象,对象[],对象[])处
位于System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象实例、对象[]输入、对象[]输出)
位于System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&rpc)
位于System.ServiceModel.Dispatcher.ImmutableDispatcheRuntime.ProcessMessage5(MessageRpc&rpc)
位于System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&rpc)
位于System.ServiceModel.Dispatcher.MessageRpc.Process(布尔isOperationContextSet)
位于System.ServiceModel.Dispatcher.ChannelHandler.DispatchedReleasePump(RequestContext请求、布尔cleanThread、OperationContext currentOperationContext)
位于System.ServiceModel.Dispatcher.ChannelHandler.HandlerRequest(RequestContext请求,OperationContext currentOperationContext)
位于System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult结果)
在System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult结果)中
在System.Runtime.AsyncResult.Complete(布尔同步完成)
在System.Runtime.InputQueue`1.AsyncQueueReader.Set(项)上
在System.Runtime.InputQueue`1.EnqueueAndDispatch(项项项,布尔值canDispatchOnThisThread)
在System.Runtime.InputQueue`1.EnqueueAndDispatch(T项,操作dequeuedCallback,布尔canDispatchOnThisThread)
位于System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType项、Action dequeuedCallback、Boolean canDispatchOnThisThread)
位于System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult结果)
位于System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult结果)
在System.Runtime.AsyncResult.SyncContinue(IAsyncResult结果)时
位于System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor ReplyChannelAcceptor,Action dequeuedCallback,AsyncCallback回调,对象状态)
位于System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
位于System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext上下文、操作acceptorCallback、AsyncCallback回调、对象状态)
位于System.ServiceModel.Channels.SharedHttpTransportManager.EnqueueContext(IAsyncResult listenerContextResult)
位于System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult listenerContextResult)
在System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult结果)中
在System.Net.LazyAsyncResult.Complete(IntPtr userToken)中
在System.Net.ListenarSyncResult.IOCompleted(ListenarSyncResult异步结果,UInt32错误代码,UInt32个字节)
在System.Threading.\u IOCompletionCallback.PerformiCompletionCallback(UInt32错误代码,UInt32个字节,本机重叠*pOVERLAP)

备注:从windows事件日志中的异常代码猜测,我认为这是一个“真实的”windows AccessViolationException(0xc000005),而不是一个抛出新AccessViolationException(0xe043452)

AccessViolationException的堆栈跟踪是否指示了负责访问冲突的代码?答案是否定的 它只显示检测到访问冲突的呼叫。随后的调用将失败,事实上整个应用程序将死亡,因为
AccessViolationException
不是并且是。 这意味着内存被以下部分损坏(不是详尽的列表):

  • 非托管依赖项的错误使用
  • GCHandle使用不当
  • 错误的不安全代码
您对非托管依赖项的潜在误用的猜测可能是AccessViolationException的根本原因

请记住,内存损坏不是确定性的:即使它正在发生,运行时也不会总是检测到它

以下代码是在
Console.WriteLine()
中获取
AccessViolationException
的一种方法。但是,它也会引发执行引擎异常

    class Program
    {
        static void Main(string[] args)
        {
            AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
            Thread.CurrentThread.Name = "Main";
            ThreadPool.QueueUserWorkItem(Corrupt, Thread.CurrentThread);
            ThreadPool.QueueUserWorkItem(RunMethod);
            Console.ReadLine();
        }

        private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Console.WriteLine(e.ExceptionObject);
        }

        private static void Corrupt(object state)
        {
            unsafe
            {
                var thread = (Thread)state;
                fixed (char* str = thread.Name)
                {
                    char* increment = str;
                    char* decrement = str;
                    while (true)
                    {
                       *(decrement--) = 'f';
                        *(increment++) = 'b';
                        Thread.Sleep(10);
                    }
                }
            }
        }

        [HandleProcessCorruptedStateExceptions ]
        public static void RunMethod(object state)
        {
            try
            {
                while (true)
                {
                    Console.WriteLine("I'm Alive");
                    Thread.Sleep(5000);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);   
            }
        }
    }

位于堆栈跟踪顶部的方法的源代码为。您可以判断哪个特定语句最有可能导致崩溃:

   keys = new TKey[count];
这会抵消在堆栈跟踪中看不到的代码,您只会得到托管代码堆栈帧的转储。所以,是的,它是可靠的,AVE是一个“硬”的