Visualstudio调试技巧的总结与如何检测内存泄漏问题?
1、如何使⽤VS⾃带的功能函数来进⾏整个⼯程代码是否有内存泄漏问题:
参考博客: (_CrtSetDbgFlag函数的是例⼦)
注意:⾃⼰测试只有使⽤VS2017上才有⽤,使⽤Vs2013不能其效果。⽽且其是在debug模式下才会进⾏检测的。
#define _CRTDBG_MAP_ALLOC
#include<stdlib.h>
#include<crtdbg.h>
knees#include<stdio.h>
#include<tchar.h>
#include<vector>
//C++调⽤C语⾔的
extern "C"
{
#include"mallocMen.h"
}
using namespace std;
//加这个才会定位到第⼏⾏内存泄漏,并且泄漏多少字节,这个只针对new申请的空间⽣效#define new new(_CLIENT_BLOCK,__FILE__,__LINE__)
void detect_memory_leaks(bool on_off)
{
int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
if (!on_off)
flags &= ~_CRTDBG_LEAK_CHECK_DF;
else {
flags |= _CRTDBG_LEAK_CHECK_DF;
//下⾯这两个是指警告信息的输出模式,下⾯是指输出到控制台。
//没有设置则信息是输出到VS的⾃带的输出框⾥
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
}
_CrtSetDbgFlag(flags);
}
void testalloc()
{
/
/故意泄漏内存空间
next studiochar *p = new char[20];
mallMen(); //使⽤C语⾔的malloc进⾏内存空间申请
}
int _tmain(int argc, _TCHAR* argv[])
{
//这部分是测试Vs的单步调试时修改代码,选择单步调试时可以把修改的代码⽣效
vector<int> vecp;
vecp.push_back(3);
vecp.push_back(6);
vecp.push_back(4);
vecp.push_back(7);
int hh = vecp.front();
//其实这两种⽅法是⼀样的,只是detect_memory_leaks⾥
//进⾏设置内存泄漏检测⽅法1
#ifdef method1
detect_memory_leaks(true);
#endif
//设置内存泄漏检测⽅法2
#ifdef method2
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
testalloc();
return 0;
}
其中另⼀个mallocMen⾥定义mallMen()函数,其如下:
#include"mallocMen.h"
void mallMen()
{
int*pp = malloc(200, sizeof(int));
}
其输出结果如下:
其中第⼆个报的内存可以显⽰在某个⽂件夹跟⼤⼩,是因为定义了⼀个:
#define new new(_CLIENT_BLOCK,__FILE__,__LINE__)
调试技巧的总结,内容整理⾃互联⽹
调试是软件开发周期中的⼀个很重要的部分,有时很有挑战性,有时候则让程序员迷惑,有时候让程序员发疯,但是。可以肯定的是,对于任何不是太那个微不⾜道的程序来说,调试是不可避免的。近年来,调试⼯具的发展已经使得很多调试任务简单省时了。
本⽂总结了⼗个调试技巧,当你使⽤VS的时候可以节省你很多时间。
1. 悬停⿏标查看表达式
调试有时候很有挑战性,当你步⼊⼀个函数想看看哪块出错的时候,查看调⽤栈来想想值是从哪来的。另⼀些情况下,则需要添加⼀些监视表达式,或者查看局部变量列表,这通常还是花费⼀些时间的,但是。如果你把你⿏标指向你感兴趣的⼀个变量。你会发现事情简单多了。⽽且,类和结构体可以通过单击展开。这样。你就可以⽅便快捷的到你想查看的变量了。
sql2008连接不上本地服务器2. 实时改变值
调试器不仅仅是⼀个分析程序崩溃或是异常结果的⼯具了,许多bug都可以通过步⼊新写的函数,检查函数是否如期望的那样运⾏来预防。有时候你可能会好奇“如果条件为真函数会正确运⾏吗”⼤多数情况下,根本不需要改变代码重启挑起,仅仅把⿏标悬停到⼀个变量上,双击值然后输⼊⼀个新值就可以了。。
3.设置下⼀条语句
⼀个典型的调试情况就是通过单步跟踪分析为什么⼀个函数调⽤失败了。当你发现⼀个函数调⽤的另⼀个函数返回错误的时候你会怎么做?重启调试?有更好的⽅法。拖动这个黄⾊的语句标识到你想下⼀步执⾏的语句前就可以了。⽐如你刚才失败的那块,然后步⼊。简单,不是吗?
4.编辑然后继续
调试⼀个复杂的程序,或是⼀个插件的时候,在⼀个被调⽤很多次的函数处发现⼀个错误。但是不想浪费时间停下来,重新编译然后重新调试。没问题,仅仅在该处改正代码然后继续单步就可以。VS会修正程序然后继续调试不需要重启
注意,编辑然后继续有⼤量的已知限制,⾸先,64位代码是不⾏的。如果他如果为你的C#程序⼯作。就去⼯程设置的⽣成选项,然后⽬标平台为x86.不要担⼼。发布版的⽬标平台和调试的时候是分开的。可以被设置为任何平台。。
第⼆.编辑然后继续改变在⼀个⽅法⾥应该是局部的。。如果你改变了⽅法签名,添加⼀些新⽅法或是类。你就不得不重启程序了。或者撤销改变来继续。改变⽅法也包含lambda表达式隐式修改的⾃动⽣成的代理类,因此也不能继续。
5.⽅便的监视窗⼝
全局变量都是静态变量吗⼤概现代的调试器都有⼀个监视窗⼝,⽆论如何。VS允许你简单的添加或移除变量。单击空⾏,输⼊你的表达式按下回车,或者是在不需要的表达式上按下Delete键就可以删除了。
⽽且。从监视窗⼝你不仅仅可以看到“正常”的变量。你可以输⼊$handles 来追踪你的程序打开了多少句柄(可以⽅便的修复内存泄漏),输⼊$err 可以看到上⼀个函数的错误码,然后使⽤⼯具-错误信息可以看到更详细的描述,或者输⼊@eax(64位是@rax)来查看包含函数返回值的寄存器。
6.带注释的反汇编
使⽤交互式的反汇编模式可以使得优化程序的关键部分变得很容易,VS给出对应你代码每⼀⾏的汇编指令,并且运⾏单步运⾏。同时,可以在任何位置设置断点。⽽且,表达式的查看和修改也像在C++代码⾥⼀样
7.带有栈的线程窗⼝
调试多线程的程序是痛苦的。。或者也可以是很有趣的。取决于你的调试器。VS2010真正优美的特性是线程窗⼝的栈视图,通过窗⼝的调⽤栈你可以⽅便的总览线程。
8.条件断点
如果你尝试通过断点再现⼀个罕见的事件,该情况引发了⼀些严重的错误。你可以添加条件断点。定义⼀个断点的条件,然后如果条件不成⽴,VS会忽略该断点
9.内存窗⼝
有些bug由不正确的结构体定义引起,忽略的对齐属性等等。查看内存中的内容可以定位然后修复bug。VS提供了⼀个放百年的内存窗⼝,可以把值以8/16/32/64位的形式展⽰。还有浮点值。也允许实时改变他们。就像在⽂本编辑器⾥⼀样。
10.转到定义
这个特性不是直接关于调试的,⽽是关于浏览⼤项⽬的。如果你尝试到⼀些不是你⾃⼰写的代码中的错误,快速知道“这个类型是什
么”或者“这个函数是⼲嘛的”,可以节省很多时间,VS通过⼀个转到定义命令⽅便了你。
11.命令窗⼝
第⼗⼀的技巧已经建议过了。确实可以节省很多时间,VS⽀持命令窗⼝,可以通过,视图-其他窗⼝-命令窗⼝来启动。⼀旦激活,你可以输⼊不同的命令来⾃动化调试。举个例⼦。你可以通过如下命令 简单的模拟MFC COleDateTime 变量。
1?dt.Format("%Y-%m-%d %H:%M:%S")
许可
本⽂包括源代码和⽂件在CPOL下授权
----------------------------------------------------------------------------------------------------------------------------------------
[原⽂发表地址]:
[原⽂发表时间]:2010/8/19 10:48 AM
今天的博⽂包含了⼀些有⽤的能⽤于VS的调试技巧。 我的朋友(他写了很多很好的关于VS使⽤技巧和窍门的)最近向我强调了这些很好的技巧,⼤部分使⽤VS的开发⼈员好像不知道这些技巧(即使他们⼤部分都在产品开发组呆过⼀阵⼦)。 如果你还没有使⽤过这些技巧,希望这篇博⽂能帮你发现它们。 它们学起来很容易,能帮你节省很多时间。
运⾏到光标(Ctrl+ F10)
我经常看见⼈们是这样来调试应⽤程序的: 他们在应⽤程序需要调试的代码前设置⼀个断点,然后反复的敲F10/F11来逐步通过代码,直到到达他们真正想要研究的确切位置。有些时候他们需要仔细观察所跨过的每⾏代码,这样使⽤F10/F11 就很合理。 但是更普遍的是,他们只想快点进⼊他们真正关⼼的那⾏代码——这是使⽤F10/F11 就不是最好的选择了。
相反, 你可能想利⽤调试器⽀持的特性“运⾏到光标”。 只需简单地把你的光标放在代码中你想程序运⾏到的那⼀⾏,然后同时敲
Ctrl+F10。这样程序就会运⾏到光标所在的那⼀⾏, 然后执⾏中⽌,由调试器控制——这样就节约了
你反复敲击F10/F11到达那⾥的时间。即使你想运⾏到的那⾏代码不在当前调试的⽅法或类⾥,⽽是在⼀个独⽴的⽅法或类⾥,这也同样奏效。
条件断点
我们经常在可⽤性学习中见到另⼀个普遍的技巧:开发⼈员设置断点,运⾏程序,试着输⼊⼀些数据,当到达⼀个断点时,⼿⼯检查某种条件是不是成⽴,如果成⽴才决定进⼀步研究。 如果条件不符合他们想要的, 按F5继续执⾏程序,尝试另外⼀些输⼊,再⼿⼯重复同样的过程。
VS的条件断点功能提供了⼀个更加容易的⽅法来处理以上情况。 条件断点允许你只在某种明确指定的条件成⽴时才中⽌执⾏,由调试器控制。这帮你免于⼿动检查/恢复你的程序, 使得整个调试过程免去许多⼿⼯活,也不那么冗长乏味。
设置⼀个条件断点
设置⼀个条件断点⼗分简单,在代码⾥按F9为某⼀⾏设置⼀个断点:
然后右击断点——编辑器左边的红⾊圆圈,在右键菜单中,选择“条件…” :
将弹出以下对话框, 允许你指明某种条件,只有当这种条件成⽴时,断点才能达到。 例如:我们可以
通过写下⾯的表达式来指明,只有当paginatedDinners列表元素的个数⼩于10时,才中⽌程序,由调试器控制。
现在, 当我重新运⾏程序来研究⼀下, 调试器只在这个查返回值⼩于10时,才中⽌程序执⾏。 如果返回值不⼩于10 ,将不会触发断点。
命中次数功能
有时你只想在条件第N次成⽴时中⽌执⾏。例如:仅当第5次出现查返回值⼩于10时,才中⽌执⾏。你这样启⽤这个功能:右击断点, 选择“命中次数…”菜单命令。
将弹出以下对话框, 允许你指明程序中断的条件:条件被第N次满⾜时,或者条件被满⾜的次数是N的倍数时,或者条件被满⾜的次数⼤于等于N次时。
机器/线程/进程筛选器
jsp后端代码在哪你可以右击断点,选择“筛选器…”菜单命令, 来指明断点只在某台特定的机器,或某个特定的进程或线程中才能被触发。
nail down跟踪点——当击中断点时⾃定义⾏为
很多⼈不知道的⼀个调试功能是使⽤。 跟踪点是⼀个断点, 当它被击中时,某种⾃定义的宏会被触发执⾏。当你想研究你的应⽤程序⽽⼜不想中⽌执⾏程序时, 这个功能特别有⽤。
我将⽤⼀个简单的控制台程序来演⽰如何使⽤跟踪点。 下⾯是的递归实现:
在上⾯的应⽤程序中,针对特定的输⼊,我们使⽤Console.WriteLine()来输出最后的斐波那契数列。假如我们想在调试过程中研究斐波那契的递归过程——⽽不停⽌调试的执⾏? 跟踪点能帮我们很轻松地做到这⼀点。
设置跟踪点
你可以这样启⽤跟踪点:按F9在代码上设置⼀个断点, 右击断点,在右键菜单中选择“命中条件…”菜单命令:
将弹出以下对话框——允许你指定当断点触发时,进⾏何种操作:
如上所⽰,我们指定每次当断点的条件成⽴时,打印跟踪信息。注意我们指定了想要输出的局部变量“X” 的值作为输出信息的⼀部分。局部变量能通过{变量名}的语法被引⽤。 也有内嵌的命令(像$CALLER,$CALLSTACK, $FUNCTION等等)可以⽤来输出跟踪信息中常见的值。
上⾯对话框的底部, 我们也选中了“继续执⾏”单选框——表⽰我们不希望调试器暂停程序。 相反,程序会继续执⾏——只是我们⾃定义的跟踪信息会在每次断点条件满⾜时输出,就这点不同。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论