欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Visual Studio 调试技巧

程序员文章站 2022-05-27 09:29:27
...

各种断点:

总结一下在vs中常用的调试技巧作为2018农历新年到来之前的最后一更。。。
作为宇宙中最强大的debug工具,vs有很多易用且功能强大的功能,但是要全面掌握则需要长时间的积累。

  1. 断点
    这个不说了,最常用的功能。这个要注意点的就是,在修改了源码之后,需要重新编译你的断点才能继续用,否则不生效。

  2. 调用堆栈 Call Stack
    通过该窗口可以看到函数的一级一级的调用过程,可以知道程序的执行路径。

  3. 函数返回值
    当通过F10单行运行时,在该函数被执行结束的时候,能在Autos窗口中看到函数的返回值

  4. 运行到光标所在行
    用腻了F10(Step Over), F11(Step Into), Shift+F11(Step Out)? 试一下Ctrl+F10(运行到光标所在行)。

  5. 想要查看变量在何处被修改?
    试一下将变量添加到 Watch 窗口中查看吧。如果变量只是个指针怎么查看呢?可以试着将指针变量在 Memory 窗口中查看,即查看内存。

  6. 想要重新执行一遍函数?
    在调试过程中时,直接 拖动 左边一个黄色的箭头到期望被执行的地方,然后继续调试即可。注意,这样改变程序的执行顺序可能会导致程序出现非期望的结果。

  7. 条件断点
    这个功能也非常有用,有时候放置一个断点会被频繁的触发,导致调试起来便较慢。我们只期望在变量等于某个值的时候触发断点,则可以通过条件断点来实现。如果变量是一个数值,则可以直接写条件, 例如num==1这种,如果变量是字符串,则需要写程这样 strcmp(newString._Bx._Ptr,"my value")==0 或者 unicode版本 wcscmp(newString._Bx._Ptr, L"my value")==0

  8. 数据断点(超级好用,强烈推荐)
    这个功能就是当某个地址的数据被修改后,自动会在该处打上断点!这个功能在debug的时候很强大。
    使用步骤就是,首先,在该数据被修改前的任意某处打上断点,然后取得该变量的地址(注1),然后再依次从菜单中找到 Debug->New Breakpoint->New Data Breakpoint ,将变量地址输入进去,再选择需要监控的数据大小(例如,int变量占4个字节;另外,好像目前只支持1,2,4字节这三种大小…)详见链接
    **注1:**如果变量不是指针变量,则不能直接获取其地址的值。可以通过获得变量的名称,然后在其前面加上取地址&符即可获取其地址,例如: &myPtr->myVar

  9. 异常断点,在程序抛出异常时,会自动打上断点。

  10. 想要查看一个变量的地址:在 Memory 窗口中 (或者在 Immediate Window 中)敲入 &my_var 即可。

查看类成员:

如果断点在类成员函数中,则 Watch Windows 中输入 this.

Visual Studio 调试技巧

这里也可以看出vc++编译器是如何布局一个类的内存的:

[this]->[基类对象]->[ VPTR (void**) ]->[该类的各个成员]

搜索:

使用正则表达式过滤搜索。
例如,想要搜索包含 strA 但是包含 strB 的字符串的所有行 (vs2012或更新版本):

^(?!.*strB).*strA.*$

Explanation:

^           # Anchor the search at the start of the line
(?!.*strB)  # Make sure that strB isn't on the current line
.*strA.*    # Match the entire line if it contains strA
$           # Anchor the search to the end of the line

如图:
Visual Studio 调试技巧

Debug模式下,鼠标悬浮看不到变量的值?

你可能打开了 visual studio 的优化选项:

  • Go to project, right click and choose properties
  • Configuration Properties->C/C+±>Optimization
  • select optimization , and change it from Maximize Speed (/O2) to Disabled (/Od)

see link: https://*.com/questions/17900797/add-watch-shows-undefined-identifier-visual-studio-2012-cpp/21525435

将std::cout输出到文件:

调试的时候,有时候不方便一步一步debug,可以将GUI程序的std::cin & std::cout重定向到文件

#include <iostream>
#include <fstream>
#include <string>

void f()
{
    std::string line;
    while(std::getline(std::cin, line))  //input from the file in.txt
    {
        std::cout << line << "\n";   //output to the file out.txt
    }
}
int main()
{
    std::ifstream in("in.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf
    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!

    std::ofstream out("out.txt");
    std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
    // 由于 std::cout 对象是全局的,只需要在程序的任意一处调用一次即可全局生效。
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!

    std::string word;
    std::cin >> word;           //input from the file in.txt
    std::cout << word << "  ";  //output to the file out.txt

    f(); //call function


    std::cin.rdbuf(cinbuf);   //reset to standard input again
    std::cout.rdbuf(coutbuf); //reset to standard output again

    std::cin >> word;   //input from the standard input
    std::cout << word;  //output to the standard input
}

例如,可以定义这么一个类:

#include <iostream>
#include <fstream>

class my_test_class
{
public:
	static void get_instance()
	{
		static bool flag = false;
		if (flag)
			return;
		flag = true;
		std::ofstream * pout;
		pout = new std::ofstream("out.txt");
		std::cout.rdbuf((*pout).rdbuf()); //redirect std::cout to out.txt!
	}

};

在想要重定向 std::cout 的代码前调用一次 my_test_class::get_instance() 即可。不要太在意new出来的对象没被delete哈,程序被关闭时会被清理掉的。

see link: https://*.com/questions/10150468/how-to-redirect-cin-and-cout-to-files

Attach到一个Process,但是不自动加载符号文件:

可能需要 select Native 模式:
Visual Studio 调试技巧

to be continued…

相关标签: 调试