• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > 分享Visual Studio原生开发的10个调试技巧(2)

分享Visual Studio原生开发的10个调试技巧(2)

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-11

通过本文主要向大家介绍了visual studio技巧,visual studio,visual studio 2010,visual studio 2015,visual studio 2013等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

之前关于Visual Studio调试技巧的文章引起了大家很大的兴趣,以至于我决定分享更多调试的知识。以下的列表中你可以看到写原生开发的调试技巧(接着以前的文章来编号)。这些技巧可以应用在VS2005或者更新版本中(当然有一些可以适用于旧版本)。如果你继续,你可以知道每个技巧的详细信息。

技巧11:数据断点

  当数据所在内存位置变化时,调试器将会中断。然而,这是唯一可能在一个时间创建4这样的硬件的数据断点。数据断点只能在编译的过程中添加,可以通过菜单(编译>新断点>新数据断点)或者通过断点窗口来添加。

  您可以使用一个内存地址或地址表达式。即使你能看到堆栈上的两个值,我认为通常当堆上的值被改变时,这项功能才会有用。这对 识别内存损坏是一个很大的帮助。

  在下面的例子中,指针的值已经更改为所指向对象的值。为了能找出什么地方做的更改,我在指针值存储的位置设置了一个断点,如 &ptr (注意这是在指针初始化后发生的)。当数据更改后,以为着某人更改了指针的值,调试器终止,然后能发现哪些代码引起了这个改变。

技巧12: 线程重命名

  当你调试多线程应用是,Threads窗口会显示创建了哪些线程,以及当前的线程。线程越多,你就越难找到你要找的线程(特别是当同一段程序,被多个线程同时执行的时候,你就不知道当前执行的是哪个线程实例)

  调试器允许你给线程重新命名。用右键单击一个线程,并重命名。

  也可以以程式设计方式命名线程,虽然这有点棘手而且线程启动后必须去做的,否则调试器将以它的默认命名规定重新将其初始化,下面的函数显示了如何定义和使用一个线程。

typedef struct tagTHREADNAME_INFO
{
  DWORD dwType;    // 必须是两个字节的长度
  LPCSTR szName;    // 指针指向命名 (同一个地址空间)
  DWORD dwThreadID;  // 线程ID(-1调用线程)
  DWORD dwFlags;    // 保留待用,多数情况下为0
} THREADNAME_INFO;
 
void SetThreadName(DWORD dwThreadID, LPCSTR szThreadName)
{
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = szThreadName;
  info.dwThreadID = dwThreadID;
  info.dwFlags = 0;
 
  __try
  {
    RaiseException(0x406D1388, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info);
  }
  __except (EXCEPTION_CONTINUE_EXECUTION)
  {
  }
}
</div>

技巧13:指定线程设置断点

  对于多线程应用程序,另一个有用的技巧是在指定线程、进程甚至计算机设置断点。可以使用断点的Filer命令来实现这种功能。

  调试器允许你使用线程名、线程ID、进程名、进程ID和机器名的不同组合(使用AND、OR、NOT连接)。掌握如何设置线程名称也使得这种过滤技术操作更为简单。

技巧14:(不准确的)定时执行

  在我之前的文章中我曾提及在Watch窗口中使用伪变量。其中一个没有提及的是@clk,可显示一个计数器的值,用于获得两个断点之间代码执行所需要的大体时间,该值的单位为毫秒(ms)。但是,这种方法不能用于配置程序执行。你应该使用Visual Studio Profiler或者性能计时器来完成这些配置。

  通过在Watch窗口或者Immediate窗口中添加@clk=0来重置计时器。因此,若需要计算末段代码执行所需要的时间,做下列处理:

  • 在代码块起始位置设置断点
  • 在代码块结束位置设置断点
  • 在Watch窗口中添加@clk
  • 当第一个断点触发时,在Intermediate窗中中输入@clk=0
  • 运行程序,直到遇到代码块结束位置的断点,并在Watch窗口中查看@clk的值

  注意网上有技巧说需要在Watch窗口中添加两条表达式:@clk和@clk=0,据说可以每次在断点执行的位置重置计时器。这种技巧只能在较低版本的Visual Studio中使用,但是不能在高版本VS中使用,例如VS2005(作者做过测试,vs2005不支持这种技巧)以及更高版本。

技巧15:格式化数字

  当你使用Watch或者Quick Watch窗口查看变量时,显示这些数值是用默认的预定义可视化格式。当变量是数字时,显示形式按照他们的类型(int、float、double)来的,并且使用十进制显示。然而,你可以设置调试器在显示数字的使用使用不同的类型,或者使用不同的进制。

  改变变量显示类型可以在变量前添加以下前缀:

  • by —— unsigned char(unsigned byte)
  • wo —— unsigned short(unsigned word)
  • dw —— unsigned long(unsigned double word)

  改变变量显示的进制可以在变量前添加以下前缀:

  • d或i —— 有符号十进制数
  • u     —— 无符号十进制数
  • o     —— 无符号八进制数
  • x     —— 小写十六进制数
  • X     —— 大写十六进制数

技巧16:格式化内存数据

  除了数字,debugger还可以在Watch窗口中显示格式化的内存数据,最长为64字节。你可以在表达式(变量或者内存地址)后面添加下面的后缀来格式化数据:

  • mb或m —— 十六进制显示的16字节数据,后面跟着16个ASCII字符
  • mw —— 8字(WORD,通常1 WORD = 2 BYTE)数据
  • md —— 4个双字(DWORD,通常1 DWORD = 4 BYTE)数据
  • mq —— 2个四字(Quad WORD)数据
  • ma —— 64个ASCII字符
  • mu —— 2字节UNICODE字符

技巧17:在系统DLL调用处暂停

  有时在DLL的某个函数被调用时暂停是很有用,特别是系统DLL(比如kernel32.dll、user32.dll)。实现这种暂停需要使用原生debugger提供的上下文运算符。你可以设定断点位置、变量名或者表达式:

  • {[函数],[源代码],[模块]}断点位置
  • {[函数],[源代码],[模块]}变量名
  • {[函数],[源代码],[模块]}表达式

  大括号内可以是函数名、源代码及模块的任意组合,但是逗号不能省略。

  举个例子如果我们需要在CreateThread函数调用时暂停。这个函数是从kernel32.dll导出的,因此上下文运算符应该是这样子的:{,,kernel32.dll}CreateThread。然而,这样并不行,因为该运算符需要CreateThread修饰之后的名字。可以使用  DBH.exe来获得一个特定函数的修饰名(编译器编译生成)。

  下面是如何获得CreateThread的修饰名的方法:

C:\Program Files (x86)\Debugging Tools for Windows (x86)>dbh.exe -s:srv*C:\Symbo
ls*http://msdl.microsoft.com/Download/Symbols -d C:\Windows\SysWOW64\kernel32.dl
l enum *CreateThread*
Symbol Search Path: srv*C:\Symbols*http://msdl.microsoft.com/Download/Symbols
 
 index      address   name
   1      10b4f65 :  _BaseCreateThreadPoolThread@12
   2      102e6b7 :  _CreateThreadpoolWork@12
   3      103234c :  _CreateThreadpoolStub@4
   4      1011ea8 :  _Crea



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 分享Visual Studio原生开发的10个调试技巧(2)
  • Visual Studio调试技巧汇总
  • 分享Visual Studio原生开发的10个调试技巧

相关文章

  • 2017-05-11Asp.net中获取应用程序完整Url路径的小例子
  • 2017-05-11解决ASP.NET中的各种乱码问题总结
  • 2017-05-11读取XML并绑定至RadioButtonList实现思路及演示动画
  • 2017-05-11Asp.net自定义控件之单选、多选控件
  • 2017-05-11asp.net下利用JS实现对后台CS代码的调用方法
  • 2017-05-11asp.net 点缩略图弹出随图片大小自动调整的页面
  • 2018-08-20详解在Windows下如何使用AspNetCore Api 和consul
  • 2017-05-11Microsoft SQL Server 2005 Express 远程访问设置详述,100%成功篇
  • 2017-05-11弹出窗口,点击确定在删除数据的实现方法
  • 2018-08-20Asp.Net设计模式之单例模式详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • ASP.NET实现的简单易用文件上传类
    • 在ASP.NET 2.0中操作数据之三十九:在DataList的编辑界面里添加验证控件
    • ASP.NET学习路线(详细)
    • 详解ASP.NET七大身份验证方式以及解决方案
    • 在ASP.NET 2.0中操作数据之四十六:使用SqlDataSource控件检索数据
    • asp.net datalist 用法
    • ASP.NET Core环境设置教程(2)
    • DataGrid 动态添加模板列 实现代码
    • asp.net 安全、实用、简单的大容量存储过程分页第1/2页
    • ASP.NET MVC3手把手教你构建Web

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有