原文链接地址:http://blog.csdn.net/Donjuan/article/details/4649372

讲完Visual Studio调试之断点技巧篇以后,翻翻以前看得一些资料和自己写的一些文章,发现还有几个关于中断程序的技巧在前面的文章里面遗漏了,决定还是在这里总结一下。当然啦,如果你知道这些技巧,忽略这篇文章好了,:)

在程序启动的时候将调试器附加上去

可能有人会对这个问题有一些争议,因为大部分情况下我们只需要在调试器(Debugger)里面直接启动被调试程序(Debuggee)就可以在程序启动前调试程序了。

但有些情况下,你是不能控制被调试程序(Debuggee)在什么时候启动的。例如在DCOM环境里面,DCOM客户端(Client)可以通过调用CoCreateInstanceEx(…, CTX_LOCAL_SERVER, …)启动DCOM服务器(Server),启动DCOM服务器的过程是在COM库中进行的, 你没有办法将在DCOM服务器的WinMain函数之前将你的调试器附加(Attach)上去。Windows提供了一个功能就是在一个程序启动的时候,自动将设置好的调试器附加到这个新启动的程序上去。这里我就是要介绍这个功能:

或者说你需要调试一个Windows服务的启动部分,在服务启动的时候,让调试器附加上去岂不是比在Start()函数里面打印很多跟踪信息要好很多?

在程序启动的时候将调试器附加上去实际上是Windows操作系统提供的功能,呃……当然,调试器之所以能工作,也是CPU和操作系统通力合作的结果,:)。因此你需要修改一些操作系统里面的设置:

1. 打开注册表编辑器(regedit.exe).

2. 找到键值HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Image File Execution Options/。

3. 新建一个键(Key),键名就是你要调试的程序的文件名,例如notepad.exe。

4. 然后在这个新建的键值(Key)下,在我们的例子里,这个键值是notepad.exe。新建一个字符串值(String Value)Debugger,值设置为你喜欢的调试器:

a. 如果选择Visual Studio的话,就是D:/Program Files/Microsoft Visual Studio 9.0/Common7/IDE/devenv.exe(假设你的Visual Studio安装在D盘)

b. 选择Windbg的话,就是c:/debuggers/windbg.exe(假设你的Windbg拷贝在c:/debuggers/目录里)。

设置好了以后,启动notepad.exe,这个时候你选择的调试器就会被Windows先启动起来,然后在notepad.exe的入口处中断。换句话说,所有的程序,都可以使用这种方法在启动的时候自动激活调试器,当然啦,如果你已经修复了你的问题,不需要调试器在程序启动之前启动的话,在注册表里面删掉那个键值就好了。

如何设置验尸调试(POSTMORTEM DEBUGGER)

首先先讲一下什么叫做验尸调试,大家应该都有这个体验,当一个程序突然崩溃的时候,Windows会不失时机弹出一个对话框,问你是否要发送错误报告给微软。其实这个对话框叫做Watson, 是Windows自带的一个非常简单的调试器,它的工作就是将程序的内存拷贝下来保存到一个文件当中。这个过程就是验尸调试的准备步骤,因为程序加载进内存以后,术语叫做进程,当进程崩溃的时候,就是意外死亡嘛,当然进程正常结束那叫做自然死亡。一般我们只对意外死亡的进程比较感兴趣,就跟电视里警匪片里面描写的那样,一个无辜的配角死掉了,警察第一步总是要保护现场,带尸体回去 ,让法医验尸。进程意外死亡的时候,Windows区别进程是否是意外死亡的方式很简单,就是看进程里面是否有未处理的异常。Windows也提供了一个选项,可以让你把犯罪现场--进程发生异常的时候的内存保留下来(进程的尸体),你可以在晚一点的时候来慢慢分析这个内存(比如看一看堆栈,一些变量什么的)--这个过程就叫做验尸。

验尸调试对下面这种情况很有帮助:

1. 重现很难重现的bug,比如说你有一个bug是随机出现,但是每次出现都会把程序搞死,与其绞尽脑汁去回忆重现步骤,还不如直接把犯罪现场保留下来,慢慢分析。

启动非托管程序的验尸调试功能

跟在程序启动时将调试器附加上去类似,验尸调试实际上也是Windows提供的功能,启动验尸调试,你需要修改下面的注册表设置:

在//HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/AeDebug里面,分别创建下面两个键:

如图所示:

里面的键值说明一下:

  1. Debugger:指定了用来执行验尸调试的调试器文件名的完整路径,-p和-e是调试器的一些命令行参数,而%ld则是一个占位符,Windows会把死亡的进程的PID替换%ld这个值(读者如果熟悉批处理编程的话,就应该知道%ld实际上是批处理程序的参数的声明方式)。vsjitdebugger.exe是Visual Studio用来处理验尸调试的调试器名称,如果你安装了Visual Studio,VS的安装程序应该会自动为你设置好这个键。
  2. Auto:如果值是1的话,那么windows就会自动在进程死亡的时候,启动调试器;如果为0的话,就会打开一个对话框问你是否要执行验尸调试—但是Windows 7如果是这个选项的话,会直接禁用验尸调试,因此我推荐将Auto的值总是设置成1。

备注:对于偏好windbg的读者,你有两个方案将Windbg设置成默认的验尸调试程序:

  1. 直接执行  windbg –I   这个命令,注意I要大写。
  2. 将Debugger的键值设置为:"c:/Debuggers/windbg.exe" -p %ld -e %ld –g

设置好了以后,我们可以写一个测试程序来试一下刚才的设置:

Test.cpp

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

int *p = NULL;

// 触发一个异常

*p = 0;

return 0;

}

使用命令cl.exe /Zi test.cpp编译好程序以后,执行test.exe,你应该就可以看到类似下面的现象了:

启动托管程序的验尸调试功能

然而,上面的设置仅对native程序有效,如果要设置托管程序的默认验尸调试器,在//HKEY_LOCAL_MACHINE/Software/Microsoft/.NETFramework里面,分别创建下面两个键:

使用上面的设置,你应该可以做所有非Winform托管程序的验尸调试了。

启动Winform程序的验尸调试功能

然而,当你的Win form程序崩溃(Crash)的时候,你会发现你设置的默认验尸调试器没有运行起来,原因是因为Win form程序默认禁用了即时调试(JIT Debug)的功能。因此要设置Win form程序的默认验尸调试器,你除了做上面的步骤以外,你还要将Win form程序的即时调试功能打开。打开的方法:

1. 修改你机器的machine.config文件,这样机器上所有的Win form程序都会将这个即时调试功能打开。在<configuration>里面添加下面一行:

<system.windows.forms jitDebugging="true" />

2. 修改单独程序的的app.config文件打开单个Win form程序的即时调试功能。在<configuration>里面添加下面一行:

<system.windows.forms jitDebugging="true" />

例如:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <system.windows.forms jitDebugging="true" />

</configuration>

使用Visual Studio的RPC调试功能同时调试COM程序的客户端和服务端

参看我以前的文章:

http://blog.csdn.net/Donjuan/archive/2009/01/23/3851586.aspx

Visual Studio调试之断点技巧篇补遗的更多相关文章

  1. Visual Studio调试之断点技巧篇

    原文链接地址:http://blog.csdn.net/Donjuan/article/details/4618717 函数断点 在前面的文章Visual Studio调试之避免单步跟踪调试模式里面我 ...

  2. Visual Studio调试之断点进阶篇

    Visual Studio调试之断点进阶篇 在上一篇文章Visual Studio调试之断点基础篇里面介绍了什么是断点,INT 是Intel系列CPU的一个指令,可以让程序产生一个中断或者异常.程序中 ...

  3. Visual Studio调试之断点基础篇

    Visual Studio调试之断点基础篇 我曾经问过很多人,你一般是怎么调试你的程序的? F9, F5, F11, F…… 有很多书和文章都是介绍怎么使用Visual Studio编写WinForm ...

  4. VISUAL STUDIO 调试

    调试术语 Visual Studio调试之断点基础篇 Visual Studio调试之断点进阶篇 不能设置断点的检查步骤 Visual Studio调试之断点技巧篇 Visual Studio调试之断 ...

  5. Visual Studio调试之避免单步跟踪调试模式

    Visual Studio调试之避免单步跟踪调试模式 写完Visual Studio调试之断点进阶篇之后,想分享一下我常用的一些调试技巧,后面发现写之前,一些背景知识需要介绍一下. 下面是几篇今年2月 ...

  6. Visual Studio调试之符号文件

    原文链接地址:http://www.cnblogs.com/killmyday/archive/2009/10/14/1582882.html 前面在不能设置断点的检查步骤和Visual Studio ...

  7. [转]Visual Studio调试之符号文件

    http://www.cnblogs.com/killmyday/archive/2009/10/14/1582882.html 前面在不能设置断点的检查步骤和Visual Studio调试之断点进阶 ...

  8. 12个Visual Studio调试效率技巧

    在这篇文章中,我们假定读者了解VS基本的调试知识,如: F5 开始使用调试器运行程序 F9 在当前行设置断点 F10 运行到下一个断点处 F5 从被调试的已停止程序恢复执行 F11 步进到函数内(如果 ...

  9. Visual Studio 调试技巧[Command Window & Immediate Window ](Tips)

    Visual Studio 调试技巧[Command Window & Immediate Window ](Tips) 1. immediate window 定义的一些 alias (// ...

随机推荐

  1. 【PHP】PHP常用数组(Array)函数整理

    整理了一份PHP开发中数组操作大全,包含有数组操作的基本函数.数组的分段和填充.数组与栈.数组与列队.回调函数.排序.计算.其他的数组函数等. 一.数组操作的基本函数 数组的键名和值 array_va ...

  2. Linux 系统无法登录?你的程序有问题吧!

    今天遇到一个问题,有个用户连接不上服务器(无法ssh远程连接) su: failed to execute /bin/bash: Resource temporarily unavailable 谷歌 ...

  3. flask(列表实现)

    在 index/views.py 中定义视图函数 在查询的时候,如果用户分类id传0,则不添加分类查询条件 @index_blu.route('/newslist') def get_news_lis ...

  4. iScroll实现下拉刷新上拉加载

    前言 初学iscroll这个控件,给我的一个感觉还是蛮不错的. 什么是iScroll:是目前最成熟的自定义滚动解决方案之一,在移动端和PC有很好的兼容性.iScroll官方提供了5个不同的版本 isc ...

  5. UVA11988 Broken Keyboard (a.k.a. Beiju Text)【数组模拟链表】

    参考:https://blog.csdn.net/lianai911/article/details/41831645 #include <iostream> #include <c ...

  6. C++ vector二维数组

    C++ 构建二维动态数组 int **p; p = ]; //注意,int*[10]表示一个有10个元素的指针数组 ; i < ; ++i) { p[i] = ]; } 这样就构成10*5的数组 ...

  7. springboot升级到2.x需要改动的地方

    由于需要跟进技术发展的脚步,对原有项目springboot进行2.0升级,但升级并不是说改一下版本就完事了,springboot2.0变动比较多,详细变化可以百度一下,下面针对升级springboot ...

  8. 浅析 Linux 初始化 init 系统,Systemd

    原文地址:http://www.ibm.com/developerworks/cn/linux/1407_liuming_init3/ Systemd 的简介和特点 Systemd 是 Linux 系 ...

  9. Fiddler 发送post 请求失败

    今天服务端同事,让我发一个post 请求.然后呢,一直有问题.告诉我签名失败. 后来换了其他的在线模拟post,都是可以的. 后来找到原因了, post 请求,必须要有Content-Type 和 C ...

  10. 剁了xp,醉了win7

    装完win7,安装各种软件完毕,重启,然并卵.  cpu,内存飙升!! svchost.exe这个进程内存发疯了一样往上飙升 从 几十兆  到占用1个多G, 纳尼, 总共物理内存才2G. ╮(╯▽╰) ...