在使用Visual Studio进行debug的时候,设置断点是最常用的、不可或缺的技术之一。大多数情况下,我们只需要在Visual Studio里按F9键,设置一个普通断点即可。但是对于一些特殊情况,这一点可能就不太管用。典型的情况就是在次数很多的循环里,我们需要在特定条件下,程序中断执行。这时候要使用条件断点。条件断点的关键是设置一个表达式,当表达式条件为真时,中断执行。一般的情况下,这个表达式很好写,如对于整型变量i,只需写 i == 10,即可在i的值为10的时候中断执行。

但是对于一些复杂一点的代码,可能就没有那么简单了。下面是一段测试代码(仅供测试条件断点之用,会有内存泄漏等问题),如果要在有注释的代码行上设置条件断点,使注释里描述的条件满足时中断执行,那么这些条件表达式该如何写呢?你可以先自己试着先想一下,然后再看后面的答案。

// TestAtlVariant.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include "atlsafe.h"
using namespace std;
struct point
public:
	point(int i, int j) { this->i = i; this->j = j; }
	int i;
	int j;
// dummmy functions for test
void func(int i) {}
void func(string str) {}
void func(CComBSTR bstr) {}
void func(point * p) {}
int _tmain(int argc, _TCHAR* argv[])
	int iArray[3];
	string strArray[3];
	CComBSTR bstrArray[3];
	vector<string> strVec;
	vector<CComBSTR> bstrVec;
	vector<point*> pointVec;
	map<string, string> strMap;
	map<CComBSTR, CComBSTR> bstrMap;
	map<string, point*>  pointMap;
	iArray[0] = 1;
	iArray[1] = 2;
	iArray[2] = 3;
	strArray[0] = string("a1");
	strArray[1] = string("b2");
	strArray[2] = string("c3");
	bstrArray[0] = CComBSTR("a1");
	bstrArray[1] = CComBSTR("b2");
	bstrArray[2] = CComBSTR("c3");
	strVec.push_back("a1");
	strVec.push_back("b2");
	strVec.push_back("c3");
	bstrVec.push_back("a1");
	bstrVec.push_back("b2");
	bstrVec.push_back("c3");
	pointVec.push_back(new point(1,1));
	pointVec.push_back(new point(2,2));
	pointVec.push_back(new point(3,3));
	strMap.insert(pair<string, string>("a1", "a1"));
	strMap.insert(pair<string, string>("b2", "b2"));
	strMap.insert(pair<string, string>("c3", "c3"));
	bstrMap.insert(pair<CComBSTR, CComBSTR>("a1", "a1"));
	bstrMap.insert(pair<CComBSTR, CComBSTR>("b2", "b2"));
	bstrMap.insert(pair<CComBSTR, CComBSTR>("c3", "c3"));
	pointMap.insert(pair<string, point*>("a1", new point(1,1)));
	pointMap.insert(pair<string, point*>("b2", new point(2,2)));
	pointMap.insert(pair<string, point*>("c3", new point(3,3)));
	for(int i=0; i<3; i++)
		func(iArray[i]); // 1. iArray[i] == 2
	for(int i=0; i<3; i++)
		func(strArray[i]); // 2. strArray[i] == "b2"
	for(int i=0; i<3; i++)
		func(bstrArray[i]); // 3. bstrArray[i] == "b2"
	for(vector<string>::iterator strIter = strVec.begin(); strIter != strVec.end(); strIter++)
		func(*strIter); // 4. *strIter == "b2"
	for(vector<CComBSTR>::iterator bstrIter = bstrVec.begin(); bstrIter != bstrVec.end(); bstrIter++)
		func(*bstrIter); // 5. *bstrIter == "b2"
	for(vector<point*>::iterator pointVecIter = pointVec.begin(); pointVecIter != pointVec.end(); pointVecIter++)
		func(*pointVecIter); // 6. *pointerIter == 2
	for(map<string, string>::iterator strMapIter = strMap.begin(); strMapIter != strMap.end(); strMapIter++)
		func(strMapIter->first); // 7. strMapIter->first == "b2"
		func(strMapIter->second); // 8. strMapIter->second == "b2"
	for(map<CComBSTR, CComBSTR>::iterator bstrMapIter = bstrMap.begin(); bstrMapIter != bstrMap.end(); bstrMapIter++)
		func(bstrMapIter->first); // 9. bstrMapIter->first == "b2"
		func(bstrMapIter->second); // 10. bstrMapIter->second == "b2"
	for(map<string, point*>::iterator pointMapIter = pointMap.begin(); pointMapIter != pointMap.end(); pointMapIter++)
		func(pointMapIter->first); // 11. pointMapIter->first == "b2"
		func(pointMapIter->second); // 12. pointMapIter->second->i == 2
	return 0;

下面是在以上有注释的代码行上设置条件断点所需要的条件表达式:

1.       iArray[i] == 2
2.       (strArray[i])._Bx._Buf[0x00000000] == 'b' && (strArray[i])._Bx._Buf[0x00000001] == '2'
3.       *((bstrArray[i]).m_str+0) == 'b' && *((bstrArray[i]).m_str+1) == '2'
4.       (*(strIter)._Myptr)._Bx._Buf[0x00000000] == 'b' && (*(strIter)._Myptr)._Bx._Buf[0x00000001] == '2'
5.       *((*(bstrIter)._Myptr).m_str+0) == 'b' && *((*(bstrIter)._Myptr).m_str+1) == '2'
6.       (*(*(pointVecIter)._Myptr)).i == 2
7.       (((strMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000000] == 'b' && (((strMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000001] == '2'
8.       (((strMapIter)._Ptr->_Myval).second)._Bx._Buf[0x00000000] == 'b' && (((strMapIter)._Ptr->_Myval).second)._Bx._Buf[0x00000001] == '2'
9.       *((((bstrMapIter)._Ptr->_Myval).first).m_str+0) == 'b' && *((((bstrMapIter)._Ptr->_Myval).first).m_str+1) == '2'
10.    *((((bstrMapIter)._Ptr->_Myval).second).m_str+0) == 'b' && *((((bstrMapIter)._Ptr->_Myval).second).m_str+1) == '2'
11.    (((pointMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000000] == 'b' && (((pointMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000001] == '2'
12.    (*(((pointMapIter)._Ptr->_Myval).second)).i == 2

值得注意的是,如果直接使用注释里的表达式作为条件断点的条件表达式,是不行的。Visual Studio会给出错误提示,无法设置条件断点。

这些表达式看上去很复杂,手工很难直接写出来。秘诀在于,Visual Studio的Quick Watch可以帮我们写这些表达式。以最后一个断点为例,对pointMapIter显示Quick Watch窗口,在Value里找到我们要取的值,在Expression里就会显示相应的表达式。我们可以把这里显示的表达式拷贝出来,必要时略加修改,再加上比较条件,就可以作为条件断点表达式来使用。以上面的第2条为例,由于不能直接判断字符串相等,采用的方法是取出字符逐个比较。这种从QuickWatch窗口获取复杂的条件表达式的方法不仅对C++适用,对于其他编程语言,如C#,也是适用的。

示例如下:

code是std::string类型,断点条件设置为code.compare("300065")==0时会报错:"无法设置断点。此表达式有副作用,将不会对它进行计算"。 然后使用快速监视(Quick Watch)看code的值最终测试出好用的表达式为 

((code)._Bx._Buf)[0]=='3'&&((code)._Bx._Buf)[3]=='0'&&((code)._Bx._Buf)[4]=='6'&&((code)._Bx._Buf)[5]=='5'

1.       iArray[i] == 2
2.       (strArray[i])._Bx._Buf[0x00000000] == 'b' && (strArray[i])._Bx._Buf[0x00000001] == '2'
3.       *((bstrArray[i]).m_str+0) == 'b' && *((bstrArray[i]).m_str+1) == '2'
4.       (*(strIter)._Myptr)._Bx._Buf[0x00000000] == 'b' && (*(strIter)._Myptr)._Bx._Buf[0x00000001] == '2'
5.       *((*(bstrIter)._Myptr).m_str+0) == 'b' && *((*(bstrIter)._Myptr).m_str+1) == '2'
6.       (*(*(pointVecIter)._Myptr)).i == 2
7.       (((strMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000000] == 'b' && (((strMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000001] == '2'
8.       (((strMapIter)._Ptr->_Myval).second)._Bx._Buf[0x00000000] == 'b' && (((strMapIter)._Ptr->_Myval).second)._Bx._Buf[0x00000001] == '2'
9.       *((((bstrMapIter)._Ptr->_Myval).first).m_str+0) == 'b' && *((((bstrMapIter)._Ptr->_Myval).first).m_str+1) == '2'
10.    *((((bstrMapIter)._Ptr->_Myval).second).m_str+0) == 'b' && *((((bstrMapIter)._Ptr->_Myval).second).m_str+1) == '2'
11.    (((pointMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000000] == 'b' && (((pointMapIter)._Ptr->_Myval).first)._Bx._Buf[0x00000001] == '2'
12.    (*(((pointMapIter)._Ptr->_Myval).second)).i == 2
转自 https://blog.csdn.net/qwang24/article/details/4087423条件断点 在使用Visual Studio进行debug的时候,设置断点是最常用的、不可或缺的技术之一。大多数情况下,我们只需要在Visual Studio里按F9键,设置一个普通断点即可。但是对于一些特殊情况,这一点可能就不太管用。典型的情况就是在次数很多的循环里,我们需要... 鼠标移到断点位置右键,可进行"删除断点",“禁用断点”,“条件”,“操作”,"编辑标签"等操作; 条件: 为断点增设触发条件,如下图表示当i==5时触发;
VS Debug的条件断点 (深入浅出判断string)条件断点判断字符串相等错误案例错误案例1错误案例2错误案例3可执行写法正确用法1正确用法2分析string 条件断点 运行环境: Windows10 Visual Studio 2019 编译器默认C++ Debug的条件断点的打开方式:断点右键-选择条件 使用这种方式可以减少用修改源码来断点条件断点是在断点处的约束触发条件,并且可以设置断点忽略次数,条件断点在多线程上也能使用,可以线程ID用来分离线程(只在指定的线程中断点断点优先级:
  右击断点–编辑窗口左侧的红点,在上下文菜单上选择“Condition…”。   这时弹出一个对话框供你设置激活该断点所需的条件。比如:我们希望只有当局部变量paginatedDinners的尺寸小于10时,调试才中断。我们可以写出对应的表达式。   现在我再运行这个程序,实现搜索,只有返回值小于10时,程序运行才会被中断。对于大于10的值,该断点将被跳过。   记录到达断点次数   有时你希望,只有当第N次满足条件的运行到达断点时,才中断程序运行。例如:当第五次返回少于10的查
题描述:在调试前加了断点,但debug时红色的断点变成透明的圆圈加一个感叹号,执行到该处时也不会停止。 这个问题遇到过几次了,前几次都没怎么注意,有时候是因为复制粘贴了某段代码后就这样了,然后点击撤销到复制之前的状态,再点保存,之后再复制过来就ok。 实际这个问题是因为源文件和原始版本不同。解决方法有二: 一,在断点上右键,选择“位置”》勾选”允许源代码与原始版本不同; 二,点击...
<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/news_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:lines="1" android:ellipsize="
VS2005中,条件断点是一种非常有用的调试工具。条件断点允许程序员在特定条件满足时中断程序的执行。使用条件断点可以帮助程序员快速定位和调试代码中的问题。 要在VS2005中设置条件断点,首先需要处于调试状态。然后,在程序中选择需要设置条件断点的行,在右键菜单中选择"条件断点"选项。在弹出的对话框中,可以输入一个条件表达式。当这个条件表达式为真时,程序会在该断点处中断执行。 条件断点VS2005中的设置与普通断点有一些区别。此外,VS2005还提供了内存断点功能,对于破解分析等方面使用更为广泛。内存断点可以用于调试内存破坏、数组越界等问题。当某个内存数据的值突然改变时,通过设置数据断点,可以帮助程序员快速定位问题所在。 需要注意的是,在VS2005中,数据断点最多只能设置4个。因此,在使用数据断点时,需要合理选择和设置断点。 总之,条件断点VS2005中是一种方便而实用的调试工具,可以帮助程序员快速定位和解决代码中的问题。同时,内存断点也是一种常用的调试技术,在破解分析等方面有着广泛的应用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [VS2005的数据断点功能](https://blog.csdn.net/magictong/article/details/44655213)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]