首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AccessViolationException的堆栈跟踪是否可信?

AccessViolationException的堆栈跟踪是否可信?
EN

Stack Overflow用户
提问于 2015-08-19 06:13:00
回答 2查看 760关注 0票数 3

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

另一方面,windows事件日志中的相关日志条目根本不显示堆栈。我们的应用程序也使用非托管库,我猜异常是由于错误使用它们(例如,oci)而不是显示的托管堆栈造成的。

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

代码语言:javascript
复制
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)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-27 19:13:58

堆栈跟踪顶部的方法的源代码是随时可得。您可以判断哪条特定的语句最有可能导致崩溃:

代码语言:javascript
复制
   keys = new TKey[count];

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

您需要一小部分崩溃的进程才能看到更多。这并不能真正帮助您,当然,崩溃的代码并不是造成崩溃的罪魁祸首。它也不是那种能很好地重复、对代码做小改动或让它处理不同数据的崩溃,它很可能是另一个新的操作符调用。

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

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

票数 2
EN

Stack Overflow用户

发布于 2015-09-27 18:28:21

AccessViolationException的堆栈跟踪是否指示对访问冲突负责的代码?答案是No

它只显示哪个调用检测到了访问冲突。随后的调用将失败,事实上,由于AccessViolationException不是默认可捕捉性你不应该抓住它,整个应用程序将死掉。这意味着内存被其中一些(并非详尽无遗的列表)破坏:

  • 非托管依赖关系的错误使用
  • 对GCHandle的不良使用
  • 车用不安全代码

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

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

下面的代码是在AccessViolationException中获取Console.WriteLine()的一种方法。然而,它也可以提高ExecutionEngineException

代码语言:javascript
复制
    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);   
            }
        }
    }
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32087755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档