代码之家  ›  专栏  ›  技术社区  ›  RodH257

有关调试尝试使用WinForms读取或写入受保护内存异常的建议

  •  1
  • RodH257  · 技术社区  · 16 年前

    在某些背景下,此应用程序是一个打印应用程序,运行在Autodesk程序revit structure中。它是一个.NET外接程序。

    我一直被这些间歇性出现的异常所困扰,这真的很令人沮丧。如何调试这些?

    通常情况下,建议不要在revit加载项中使用多线程,我在这个特定实例中所做的就是从revit中读取一些信息,然后在缺少某些信息时显示一个对话框。我不知道为什么会导致accessvioldationexceptions

    Unhandled exception!: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.; StackTrace:    at CCmdUI.DoUpdate(CCmdUI* , CCmdTarget* , Int32 )
       at CTestCmdUI.computeEnabled(CTestCmdUI* , CCmdTarget* pTarget)
       at UIFrameworkServices.CommandHandlerService.canExecute(String strName)
       at UIFramework.CommandUtility.CanExecute(RibbonCommandItem btn)
       at UIFramework.RibbonGlobalHandler.CanExecute(Object parameter)
       at Autodesk.Windows.InternalCommands.CanExecuteGenericCommand(Object sender, CanExecuteRoutedEventArgs args)
       at System.Windows.Input.CommandBinding.OnCanExecute(Object sender, CanExecuteRoutedEventArgs e)
       at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
       at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
       at System.Windows.Input.CommandManager.OnCanExecute(Object sender, CanExecuteRoutedEventArgs e)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.RoutedCommand.CanExecuteImpl(Object parameter, IInputElement target, Boolean trusted, Boolean& continueRouting)
       at System.Windows.Input.RoutedCommand.CanExecute(Object parameter, IInputElement target)
       at MS.Internal.Commands.CommandHelpers.CanExecuteCommandSource(ICommandSource commandSource)
       at System.Windows.Controls.Primitives.ButtonBase.UpdateCanExecute()
       at System.Windows.Input.CommandManager.CallWeakReferenceHandlers(List`1 handlers)
       at System.Windows.Input.CommandManager.RaiseRequerySuggested(Object obj)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Form.ShowDialog(IWin32Window owner)
       at BWTools.ErrorDisplayer.DisplayErrorWithoutLogging(String message) in C:\devel\Revit Macros\2011\BWTools\ErrorDisplayer.cs:line 93
       at Plotting.Printers.FilePostProcessor.SetParameters(IDictionary`2 sheetLocations, ParameterGrabber grabber, FilePrintSettings settings) in C:\devel\Revit Macros\2011\PLT2\Plotting\Printers\FilePostProcessor.cs:line 277
       at Plotting.Printers.FilePostProcessor.ProcessSheets(IList`1 sheets, String extension, String finalLocation, ParameterGrabber grabber, FilePrintSettings settings) in C:\devel\Revit Macros\2011\PLT2\Plotting\Printers\FilePostProcessor.cs:line 37
       at Plotting.Printers.PdfPrinter.Print(PrintSelection selection, FilePrintSettings settings) in C:\devel\Revit Macros\2011\PLT2\Plotting\Printers\PdfPrinter.cs:line 68
       at Plotting.Printers.PdfPrinter.Print(PrintSelection selections, PrintSettings settings) in C:\devel\Revit Macros\2011\PLT2\Plotting\Printers\PdfPrinter.cs:line 112
       at Plotting.GuiControl.Print() in C:\devel\Revit Macros\2011\PLT2\Plotting\Gui\GuiControl.cs:line 148
       at Plotting.Gui.PrintingSplash.animationTimer_Tick(Object sender, EventArgs e) in C:\devel\Revit Macros\2011\PLT2\Plotting\Gui\PrintingSplash.xaml.cs:line 51
       at System.Windows.Forms.Timer.OnTick(EventArgs e)
       at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    

    因此,在按钮处,您可以看到我的filePostprocessor.setParameters方法是从中引发消息框的地方。但是,当这种情况发生时,许多其他事情都与引发事件有关(Windows窗体代码的一部分?)然后顶部有一些我不知道的欧特克的东西。

    我还注意到了“exceptionwrapper.internalrealcall”这一点对我有帮助吗,在我能看到的某个地方有一个真正的异常对我有一半的帮助吗?

    这里有什么我做错的地方吗?我的代码只是一些东西的单线程循环。

    我意识到这对你们来说并不是很多信息,你们可以说‘吊杆358线是你们的问题’,但是任何关于调试/避免这些类型错误的建议都是有帮助的。虽然我使用dsofile.dll在文件上设置了一些自定义属性,但我并没有做任何非托管的事情,但这只是我正在做的事情上面的几行代码,我认为它是单线程的?

    2 回复  |  直到 15 年前
        1
  •  1
  •   Jesse Collins    16 年前

    我想你可能在这里看到了一个重新进入的问题。该对话框将输出Windows消息,在本例中,这些消息将回调到Autodesk。欧特克可能不希望被召回——它可能处于糟糕的状态。

    您可以尝试为运行对话框创建一个新线程。

        2
  •  1
  •   Kratz    15 年前

    我不熟悉revit,但是在autocad中,如果创建临时图形对象,则必须将其添加到图形中,或者显式调用.dispose。关于.NET垃圾收集器如何在另一个线程上自动运行,而AutoCAD析构函数不是线程安全的。因此任何被.NET Garbase收集器清除的孤立的AutoCAD对象都会导致程序失败。这可能不是您的问题,但无论如何都要检查。

    否则,我还读到,这个错误可能是由于未管理代码中的函数调用格式不正确造成的,正如错误所暗示的那样,这会占用程序内存。你可能对此无能为力。因此,错误的棘手部分是,原因可能在很久以前就已经发生了,而抛出异常的位置仅仅是一个无辜的受害者,对于最初的损害是由什么函数调用的,你一无所知。

    我还阅读到,禁用编译器优化并在构建中包含调试信息可以掩盖这个问题。一些关于当调试信息包含在构建中时,内存损坏将覆盖调试元数据而不是程序数据的内容,因此不修复错误,而只是防止它造成损坏。

    推荐文章