在MS Visual C++中调试未处理的异常的正确方法

问题描述:

在Microsoft Visual Studio C++(native C++,Visual Studio 2015)中调试未知的未处理异常的正确方法是什么?
今天我收到了异常(文:Exception thrown: read access violation. this was 0x4.):在MS Visual C++中调试未处理的异常的正确方法

enter image description here

什么是按后显示的“破发”按钮的代码是距离标准Qt frameworkqscopedpointer.h代码:

enter image description here

现在我不知道这个问题的原因是什么。通常这是没有问题的,但是知道我已经运行了在VS 2012中始终正确运行的项目,现在我甚至不确定这是一个真正的错误,还是我只需要取消选中“抛出此异常类型时抛出” 。

我不能从点“走出”,并寻找调用堆栈也没有给出对问题的理解:
enter image description here

文:

Qt5Cored.dll!QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> >::data() Line 135 C++ 
    Qt5Cored.dll!qGetPtrHelper<QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > >(const QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData> > & p) Line 1014 C++ 
    Qt5Cored.dll!QWinOverlappedIoNotifier::d_func() Line 60 C++ 
    Qt5Cored.dll!QWinOverlappedIoNotifier::waitForAnyNotified(int msecs=1) Line 358 C++ 
    Qt5SerialPortd.dll!QSerialPortPrivate::waitForNotified(int msecs=1) Line 588 C++ 
    Qt5SerialPortd.dll!QSerialPortPrivate::waitForReadyRead(int msecs=1) Line 251 C++ 
    Qt5SerialPortd.dll!QSerialPort::waitForReadyRead(int msecs=1) Line 1309 C++ 
    MyProject.exe!UsualSep::send_cmd_and_receive_answer(const QByteArray & ba={...}, QByteArray & ans={...}, int nread=2) Line 797 C++ 
    MyProject.exe!UsualSep::isAvailable(bool & avbl=false) Line 204 C++ 
    MyProject.exe!UsualSep::on_workThread_started() Line 80 C++ 
    MyProject.exe!QtPrivate::FunctorCall<QtPrivate::IndexesList<>,QtPrivate::List<>,void,void (__thiscall UsualSep::*)(void)>::call(void(UsualSep::*)() f=0x00eb172b, UsualSep * o=0x007838d8, void * * arg=0x02bff91c) Line 501 C++ 
    MyProject.exe!QtPrivate::FunctionPointer<void (__thiscall UsualSep::*)(void)>::call<QtPrivate::List<>,void>(void(UsualSep::*)() f=0x00eb172b, UsualSep * o=0x007838d8, void * * arg=0x02bff91c) Line 520 C++ 
    MyProject.exe!QtPrivate::QSlotObject<void (__thiscall UsualSep::*)(void),QtPrivate::List<>,void>::impl(int which=1, QtPrivate::QSlotObjectBase * this_=0x029ee9d8, QObject * r=0x007838d8, void * * a=0x02bff91c, bool * ret=0x00000000) Line 143 C++ 
    Qt5Cored.dll!QtPrivate::QSlotObjectBase::call(QObject * r=0x007838d8, void * * a=0x02bff91c) Line 124 C++ 
    Qt5Cored.dll!QMetaObject::activate(QObject * sender=0x029ee9a0, int signalOffset=3, int local_signal_index=0, void * * argv=0x00000000) Line 3720 C++ 
    Qt5Cored.dll!QMetaObject::activate(QObject * sender=0x029ee9a0, const QMetaObject * m=0x670e5db0, int local_signal_index=0, void * * argv=0x00000000) Line 3595 C++ 
    Qt5Cored.dll!QThread::started(QThread::QPrivateSignal __formal={...}) Line 156 C++ 
    Qt5Cored.dll!QThreadPrivate::start(void * arg=0x029ee9a0) Line 384 C++ 
    ucrtbased.dll!774f8968() Unknown 
    [Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll] 
    ucrtbased.dll!774f867b() Unknown 
    kernel32.dll!74fc336a() Unknown 
    ntdll.dll!77169902() Unknown 
    ntdll.dll!771698d5() Unknown 

我的主要问题是而不是在这种特殊情况下做什么,但什么是调试这种例外的一般方法

+0

此时d无效。你应该检查堆栈跟踪程序中它被调用的地方以及为什么它在这个时候是无效的。我强烈建议评估这个问题,不要忽视它。 – Simon

如果异常有一个处理程序某处调用堆栈它可能是确定让它继续不分。但是,请务必确保您了解正在发生的事情。

如果调用堆栈指向您的代码,请从此处开始。我认为,在这种情况下,“MyProject.exe!UsualSep :: send_cmd_and_receive_answer ...”这是如何结束试图获取数据d?你认为你在这里设置?

我的一般方法是尝试将问题缩小为小型自包含函数,并将其包装在可以自动运行的测试中,这会重复出现问题。然后尝试修复它。也许你需要尝试isNull作为你的代码中的一个检查?

如果你检查“break when this exception type is thrown”,那么我猜测在下一次调试运行时,你会在抛出异常的时候打开调试器,这很可能会告诉你这个问题。

如果你处理异常当然它不再是一个错误。您可以通过在main中的try块中处理异常来进行调试,然后进行深入研究,以确定程序的哪一部分将其抛出。

在Qt中可能存在一个错误,而不是你自己的代码。如果是这样,它可能会是一个很模糊的东西 - Qt是测试大多数一般的真实世界使用 - 但它很难找到。但是堆栈跟踪表明你的函数send_cmd_and_receive_answer()有问题。最有可能的是它调用Qt与它不拥有的内存,或者换句话说它传递一个野指针。