我花了一整天研究这个,而且我不是更聪明的:
我有一个C#DLL,PInvokes C++ DLL中的方法.在调试模式下编译时我没有遇到任何问题,但在Release模式下编译时,我得到一个AccessViolationException.谷歌搜索这个问题告诉我,它可能是不合规的调用约定的问题.现在代码在C#中看起来像这样:
[return: MarshalAs(UnmanagedType.U1)]
[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern Boolean AMethod(Int32 mode, byte frame);
Run Code Online (Sandbox Code Playgroud)
在C++中:
extern "C" {
DLL_EXPORT bool AMethod(int mode, BYTE frame)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我已经设置C++项目使用VS2010中的__cdecl调用约定进行编译,但我仍然得到AccessViolationException,我不知道我还能做什么.我应该注意我的C++ DLL使用第三方DLL,我不知道他们使用什么调用约定.
任何帮助,将不胜感激!
哦,我的开发机器上没有例外,只在我的目标系统上.
我有一个Delphi表单,它提供了一个接口对象背后的功能,代码的其他部分也通过属于Form的属性获得引用.我无法将接口功能委托给子对象,因为窗体上的控件/组件提供了太多的功能.我不能使用TAggregatedObject或TContainedObject来链接传递给接口的对象的生命周期,因为TForm类不继承TinterfacedObject而Delphi不支持多重继承,所以我不能将TInterfacedObject混合到继承链中.如果表单被销毁而某些其他代码包含表单传递的一个接口引用,则这种情况可能导致访问冲突.谁能想到这个问题的好方法呢?
我一直在尝试在我的程序中追踪访问冲突时遇到问题.它是在第三次调用析构函数时发生的,恰好是析构函数完成时.
我花了好几个小时试图追踪这一点,所以我正在寻找有关我能做的事情的进一步建议.我正在用new和delete运算符创建类实例.Visual Studio输出窗口显示:
First-chance exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.
Unhandled exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.
有什么我可以做的,试图找出那些记忆位置的内容吗?
调用堆栈窗口显示以下内容(与我按时间顺序粘贴它的顺序相反,最早到最新):
Program.exe!Network::`scalar deleting destructor'() + 0x2b bytes C++
Program.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >() Line 754 + 0xf bytes C++
Program.exe!std::_String_val<wchar_t,std::allocator<wchar_t> >::~_String_val<wchar_t,std::allocator<wchar_t> >() Line 478 + 0xb bytes C++
Run Code Online (Sandbox Code Playgroud)
msvcp100d.dll!std :: _ Container_base12 :: _ Orphan_all()第214行+ 0x5字节C++
我对这些信息的最佳猜测是,有某种字符串变量引起了这个问题?有没有人对解释这些信息有任何建议?
任何其他建议也会有用,提前谢谢.
我在Windows 7下编码并使用Visual Studio 2010 Professional.
所以我有一个我生命中见过的最奇怪的虫子.我已经购买了一本DirectX 11书,附带了一些[示例代码]:http://www.d3dcoder.net/d3d11.htm 我很确定在某些时候我设法编译并运行每个示例应用程序,但现在,我在运行时出现"访问冲突写入位置0xCCCCCCCC"错误.
现在,这发生在以下一行:
ShadowsApp::ShadowsApp(HINSTANCE hInstance) : D3DApp(hInstance)
{
mMainWndCaption = L"Shadows Demo"; <- Crashes here !!!
mLastMousePos.x = 0;
mLastMousePos.y = 0;
...
}
Run Code Online (Sandbox Code Playgroud)
mMainWndCaption在.h中被声明为这样
std::wstring mMainWndCaption;
Run Code Online (Sandbox Code Playgroud)
并在ShadowsApp继承自的类的构造函数中使用默认值进行设置
D3DApp::D3DApp(HINSTANCE hInstance) :
mhAppInst(hInstance),
mMainWndCaption(L"D3D11 Application"),...
Run Code Online (Sandbox Code Playgroud)
我想,这已经很奇怪了......现在最奇怪的部分是当我在d3dApp.h中声明任何类型的ANY变量时,我不再有"访问冲突写入位置0xCCCCCCCC"错误,所有内容都构建并运行完美.作为一名C#程序员,这对我来说绝对没有意义.如何在类中声明一个随机变量可以"修复"这样的事情?!
任何建议将不胜感激:-)
我正在使用COM interop在使用VS2012/.NET 4.5/Win8.1的非托管应用程序中创建托管插件.所有的互操作似乎都没问题,但是当我关闭应用程序时,我得到了一个MDA异常,告诉我在发布完成期间RCW持有的COM对象时发生了AV.
这是调用堆栈:
clr.dll!MdaReportAvOnComRelease::ReportHandledException() + 0x91 bytes
clr.dll!**SafeRelease_OnException**() + 0x55 bytes
clr.dll!SafeReleasePreemp() + 0x312d5f bytes
clr.dll!RCW::ReleaseAllInterfaces() + 0xf3 bytes
clr.dll!RCW::ReleaseAllInterfacesCallBack() + 0x4f bytes
clr.dll!RCW::Cleanup() + 0x24 bytes
clr.dll!RCWCleanupList::ReleaseRCWListRaw() + 0x16 bytes
clr.dll!RCWCleanupList::ReleaseRCWListInCorrectCtx() + 0x9c bytes
clr.dll!RCWCleanupList::CleanupAllWrappers() + 0x2cd1b6 bytes
clr.dll!RCWCache::ReleaseWrappersWorker() + 0x277 bytes
clr.dll!AppDomain::ReleaseRCWs() + 0x120cb2 bytes
clr.dll!ReleaseRCWsInCaches() + 0x3f bytes
clr.dll!InnerCoEEShutDownCOM() + 0x46 bytes
clr.dll!WKS::GCHeap::**FinalizerThreadStart**() + 0x229 bytes
clr.dll!Thread::intermediateThreadProc() + 0x76 bytes
kernel32.dll!BaseThreadInitThunk() + 0xd bytes
ntdll.dll!RtlUserThreadStart() + 0x1d bytes
Run Code Online (Sandbox Code Playgroud)
我的猜测是应用程序已经销毁了它的COM对象,其中一些引用被传递给托管插件 - 而对RCW的IUnknown :: Release的调用让它变得繁荣.
我可以在输出窗口(VS)中清楚地看到应用程序已经开始卸载其中的一些dll.
'TestHost.exe': Unloaded …Run Code Online (Sandbox Code Playgroud) 使用:MSVS2012
码
elemalg.h
#include <vector>
#include <string>
#include <fstream>
class ElemAlg
{
private:
std::string difficultlyLevel, question, answerToRead;
std::vector<std::string> questions, answers;
std::vector<std::string> GetQuiz(int);
};
Run Code Online (Sandbox Code Playgroud)
elemalg.cpp
#include "elemalg.h"
std::vector<std::string> ElemAlg::GetQuiz(int difficulty)
{
if (difficulty == 1) { difficultyLevel = "algE"; }
if (difficulty == 2) { difficultyLevel = "algM"; }
if (difficulty == 3) { difficultyLevel = "algH"; }
if (difficulty == 4) { difficultyLevel = "algVH"; }
std::ifstream fin(difficultyLevel + ".txt");
while (std::getline(fin, question)) { questions.push_back(question); }
fin.close();
std::ifstream fin2(difficultyLevel + …Run Code Online (Sandbox Code Playgroud) 我有一个ac#(.net 4.0)winforms应用程序,每天每天工作8小时,在XP SP 3上运行.它在大多数情况下工作正常,有时持续数月.然后它似乎陷入了一个糟糕的咒语,并且每天一次,连续几天,在不同的时间,出现访问冲突异常.我已经尝试查看转储文件,并捕获访问冲突异常以查看堆栈; 无论哪种方式,我得到几乎相同的堆栈:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr wndProc, IntPtr hWnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.NativeWindow.DefWndProc(Message& m)
at System.Windows.Forms.ToolTip.WndProc(Message& msg)
at System.Windows.Forms.ToolTip.ToolTipNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(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(IntPtr 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.Application.Run(Form mainForm)
Run Code Online (Sandbox Code Playgroud)
我很难解决这个问题,因为堆栈跟踪不是很有用.首先,我甚至不确定我是否可以信任堆栈跟踪:程序是否到达那里(看起来它正在尝试显示一些工具提示,这当然是可能的)因为内存已经损坏,或者程序确实应该合法地那里,但有些数据内存已损坏.其次,假设堆栈跟踪是正确且值得信赖的,我没有找到一种方法来弄清楚什么是破坏内存...我们没有做任何一致的事情来触发访问冲突...应用程序日志没有显示任何在此之前其他被捕获的异常...事件日志不会与访问冲突同时显示任何条目...有关如何进一步诊断此问题的任何提示?
更新2011-10-11:我已经捕获了异常,但围绕Application.Run()方法.那时似乎为时已晚太多了.如果由于硬件/驱动程序错误而发生此异常并且未指示应用程序的内存已损坏 - 是否还有其他地方可以捕获异常(并显示它,然后让应用程序继续)?
更新2012-03-04:我再次获得异常,这次显示一个相当简单的表单(只包含一个文本框和一个ok按钮).我使用的是TextBox.AppendText().我恰巧正在同时浏览这条评论 …
我有一个很大的问题,我实际上认为我已经解决了它。我有一个使用 QNetworkAccessManager 的应用程序。这个QNAM位于一个类中。当我在此 QNAM 上执行请求时,所有请求都在一个包装器中完成,该包装器保存回复并对其执行重试逻辑
例如,如果我在构造函数中有一个 putBlob(继承自 baseRequest),我会传递对 QNAM 的引用。我在其上执行请求并保存指向回复的指针。然后回复将是包装器子项,因此 QNAM 不再拥有它的所有权。包装器是保存 QNAM 的原始类的子类。
类有一个 QNAM,以及子级“putBlobRequest”,其子级有“QNetworkReply*”
现在的问题是,当用户想要取消时,应该删除主对象及其中的所有内容。包装器还应该中止其 QNetworkReply 并断开连接(以便它不会调用 finish())
我的 baseRequest 析构函数(它保存 QNetworkReply 并且是它的父级)看起来像这样:
if(_reply) {
if(_reply->isRunning()) {
_reply->disconnect(SIGNAL(finished()));
_reply->disconnect(SIGNAL(uploadProgress(qint64, qint64)));
_reply->abort();
}
}
Run Code Online (Sandbox Code Playgroud)
当包装器在保存它的类中被杀死时,删除就完成了。(对吗?)
这有时有效,但有时我会遇到巨大的访问冲突,并且所有内容都会因以下调用堆栈而崩溃:
QtCored4.dll!QObject::disconnect(const QObject * sender, const char * signal, const QObject * receiver, const char * method) Line 2891 + 0x8 bytes C++
QtNetworkd4.dll!QNetworkReplyImpl::abort() Line 874 + 0x18 bytes C++
FrameworkAzure.dll!BaseRequest::~BaseRequest() Line 129 + 0xa bytes C++
FrameworkAzure.dll!PutBlobRequest::~PutBlobRequest() Line 24 + 0x5e bytes C++ …Run Code Online (Sandbox Code Playgroud) 我在以下代码中收到意外的访问冲突错误:
program Project65;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils;
type
ITest = interface
end;
TTest = class(TInterfacedObject, ITest)
end;
var
p: ^ITest;
begin
GetMem(p, SizeOf(ITest));
p^ := TTest.Create; // AV here
try
finally
p^ := nil;
FreeMem(p);
end;
end.
Run Code Online (Sandbox Code Playgroud)
我知道接口应该以不同的方式使用.但是我正在研究使用这种方法的遗留代码库.而且我很惊讶地发现,保留SizeOf(ITest)内存并将ITest放在那里是不够的.
现在有趣的是,如果我改变第一行
GetMem(p, 21);
Run Code Online (Sandbox Code Playgroud)
比AV消失了.(20个字节或更少的失败).对此有何解释?
(我使用的是Delphi XE2 Update 4 + HotFix)
请不要评论代码是多么可怕或建议如何正确编码.请回答为什么有必要保留21个字节而不是SizeOf(ITest)= 4?
简而言之,我有一个C#应用程序执行大量mciSendString调用(通过dllimport)来控制wav文件播放(基本上是打开,播放,暂停,停止,状态,关闭).运行一段时间后,应用程序崩溃,恕不另行通知"访问冲突".
即使我从我的vs2012运行应用程序,视觉工作室也没有抓住异常.即使有'强行突破异常'选项,我也没有运气从vs2012调试这个.所以我设置WER来生成崩溃转储,我使用windbg和psscor2.dll插件来调试它.
然后按顺序,使用以下命令,这是我得到的(为了可读性而缩短为必要的):
$>.ecxr
eax=00000001 ebx=00000000 ecx=00000401 edx=00000000 esi=049725b8 edi=00000002
eip=4e88159e esp=0a4efa38 ebp=0a4efa54 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010216
<Unloaded_mciwave.dll>+0x159e:
4e88159e ?? ???
Run Code Online (Sandbox Code Playgroud)
$>〜*KB
# 19 Id: 105c.28cc Suspend: 1 Teb: 7ef06000
Unfrozen
user32!NtUserGetMessage+0x15
user32!GetMessageA+0xa1
winmm!mciwindow+0x102
kernel32!BaseThreadInitThunk+0xe
ntdll!__RtlUserThreadStart+0x70
ntdll!_RtlUserThreadStart+0x1b
# 30 Id: 105c.15f8 Suspend: 0 Teb: 7ef1b000 Unfrozen
ntdll!ZwWaitForMultipleObjects+0x15
KERNELBASE!WaitForMultipleObjectsEx+0x100
kernel32!WaitForMultipleObjectsExImplementation+0xe0
kernel32!WaitForMultipleObjects+0x18
kernel32!WerpReportFaultInternal+0x186
kernel32!WerpReportFault+0x70
kernel32!BasepReportFault+0x20
kernel32!UnhandledExceptionFilter+0x1af
ntdll!__RtlUserThreadStart+0x62
ntdll!_EH4_CallFilterFunc+0x12
ntdll!_except_handler4+0x8e
ntdll!ExecuteHandler2+0x26
ntdll!ExecuteHandler+0x24
ntdll!RtlDispatchException+0x127
ntdll!KiUserExceptionDispatcher+0xf
WARNING: Frame IP not in any known …Run Code Online (Sandbox Code Playgroud)