如何在 Visual Studio 调试器外部运行程序时调试访问冲突?
Set the Just-in-time debugging option and run your program stand-alone until the access violation occurs. Then, in the Access Violation dialog box, you can click Cancel to start the debugger.
如何调试C++访问冲突?
如果在取消引用多个指针的代码行上遇到访问冲突,则很难找出导致访问冲突的指针。 在 Visual Studio 中,异常对话框显式命名导致访问冲突的指针。
例如,鉴于以下代码,应获得访问冲突:
#include <iostream>
using namespace std;
class ClassC {
public:
void printHello() {
cout << "hello world";
}
};
class ClassB {
public:
ClassC* C;
ClassB() {
C = new ClassC();
}
};
class ClassA {
public:
ClassB* B;
ClassA() {
// Uncomment to fix
// B = new ClassB();
}
};
int main() {
ClassA* A = new ClassA();
A->B->C->printHello();
}
如果在 Visual Studio 中运行此代码,应会看到以下异常对话框:
如果无法确定指针导致访问冲突的原因,请通过代码跟踪以确保正确分配了导致问题的指针。 If it is passed as a parameter, make sure that it is passed correctly, and you aren't accidentally creating a shallow copy. 然后,通过为相关指针创建数据断点,确保未在程序中的其他地方修改值,来验证这些值是否无意中更改。 For more information about data breakpoints, see the data breakpoint section in Using Breakpoints.
如何找出指针是否损坏了内存地址?
检查堆损坏。 大多数内存损坏是由于堆损坏造成的。 请尝试使用全局标志实用工具(gflags.exe)或 pageheap.exe。 请参阅 GFlags 和 PageHeap。
若要查找修改内存地址的位置::
在0x00408000设置数据断点。 请参阅设置数据更改断点(仅限本机C++)。
When you hit the breakpoint, use the Memory window to view memory contents starting at 0x00408000. For more information, see Memory Windows.
如何找出谁正在传递错误的参数值?
若要解决此问题,请执行以下操作:
设置函数开头的位置断点。
Right-click the breakpoint and select Condition.
In the Breakpoint Condition dialog box, click on the Condition check box. See Advanced Breakpoints.
在文本框中输入表达式,
Var==3
其中Var
参数的名称包含错误值,并且3
是传递给该表达式的坏值。Select the is True radio button, and click the OK button.
现在再次运行该程序。 当参数具有值
3
时Var
,断点会导致程序在函数的开头停止。使用“调用堆栈”窗口查找调用函数并导航到其源代码。 有关详细信息,请参阅 “如何:使用调用堆栈窗口”。
调用函数数百次时,如何知道哪个调用失败?
示例:我的程序在调用特定函数时失败。 CnvtV
程序可能在失败之前调用该函数数百次。 如果我设置了 CnvtV
位置断点,程序就会在每次调用该函数时停止,我不希望这样做。 我不知道导致调用失败的条件,因此无法设置条件断点。 我该怎么办?
You can set a breakpoint on the function with the Hit Count field to a value so high that it will never be reached. In this case, because you believe the function CnvtV
is called a couple hundred times, you might set Hit Count to 1000 or more. 然后运行程序并等待调用失败。 如果失败,请打开“断点”窗口并查看断点列表。 此时会显示所设置 CnvtV
的断点,后跟剩余的命中计数和迭代数:
CnvtV(int) (no condition) when hit count is equal to 1000 (currently 101)
现在,你知道该函数在 101 次调用中失败。 如果重置命中计数为 101 的断点并再次运行程序,程序会在调用 CnvtV
导致程序失败时停止。
在哪里可以找到 Win32 错误代码?
WINERROR.H in the INCLUDE directory of your default system installation contains the error code definitions for the Win32 API functions.
You can look up an error code by typing the code in the Watch window or the QuickWatch dialog box. For example:
0x80000004,hr
如何在单步执行应用时保持焦点?
示例:我的程序存在窗口激活问题。 通过调试器单步执行程序会干扰我重现问题的能力,因为我的程序不断失去焦点。 是否有办法避免失去焦点?
如果你有第二台计算机,请使用远程调试。 可以在主机上运行调试器时在远程计算机上运行程序。 有关详细信息,请参阅 “如何:选择远程计算机”。
如何调试 Windows API 函数?
若要在加载 NT 符号的 Windows API 函数上设置断点,
In the function breakpoint, enter the function name together with the name of the DLL where the function resides (see the context operator). 在 32 位代码中,使用函数名称的修饰形式。 To set a breakpoint on MessageBeep, for example, you must enter the following.
{,,USER32.DLL}_MessageBeep@4
若要获取修饰的名称,请参阅 查看修饰的名称。
可以测试修饰的名称,并在反汇编代码中查看它。 在 Visual Studio 调试器中的函数上暂停时,右键单击代码编辑器或调用堆栈窗口中的函数,然后选择 “转到反汇编”。
在 64 位代码中,可以使用未编码的名称。
{,,USER32.DLL}MessageBeep