可以信任AccessViolationException的Stacktrace

时间:2015-08-19 06:13:01

标签: c# clr access-violation

我们的一项服务中引发了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)

作为评论:从Windows事件日志中的异常代码中猜测我认为它是一个“真正的”Windows AccessViolationException(0xc000005)而不是throw new AccessViolationException(0xe043452)

2 个答案:

答案 0 :(得分:2)

AccessViolationException的堆栈跟踪是否指示负责访问冲突的代码?答案是 它只显示哪个呼叫检测到访问冲突。后续调用将失败,实际上整个应用程序将会死亡,因为 <@security.authorize access="hasRole('ROLE_USER') or hasRole('ROLE_ADMIN')"> 不是catchable by defaultyou should not catch it。 这意味着内存被其中一些(非详尽列表)破坏了:

  • 使用非托管依赖项
  • 使用GCHandle
  • Buggy不安全代码

您对可能滥用非托管依赖项的猜测可能是AccessViolationException的根本原因。

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

以下代码是AccessViolationException中获取AccessViolationException的方法。但是,它也可以提升Console.WriteLine()

ExecutionEngineException

答案 1 :(得分:2)

堆栈跟踪顶部方法的源代码是readily available。您可以确定哪种特定语句最有可能发生崩溃:

   keys = new TKey[count];

这会引发您在堆栈跟踪中看不到的代码,您只能获得托管代码堆栈帧的转储。所以,是的,它是可靠的,AVE是处理器抛出的“硬”,它只是没有向你展示一切。

您需要一个崩溃进程的小型转储来查看更多内容。并不是说这实际上对你有帮助,当然崩溃的代码不对崩溃负责。它也不是那种重复出现的崩溃,对代码进行小的更改或让它处理不同的数据,这可能是另一个新的操作员调用。

  

我们的应用程序也使用非托管库

这使我不得不解释为寻找可能破坏GC堆的非托管代码。不要指望在接下来的一个月左右完成任何事情,对不起。