vs调试补遗

2024-02-04 17:18
文章标签 调试 vs 补遗

本文主要是介绍vs调试补遗,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

讲完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 ValueDebugger,值设置为你喜欢的调试器:

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里面,分别创建下面两个键:

 

名称

类型

键值

Debugger

REG_SZ

"C:"Windows"system32"vsjitdebugger.exe" -p %ld -e %ld

Auto

REG_SZ

1

 

如图所示:


 

里面的键值说明一下:

1.       Debugger:指定了用来执行验尸调试的调试器文件名的完整路径,-p-e是调试器的一些命令行参数,而%ld则是一个占位符,Windows会把死亡的进程的PID替换%ld这个值(读者如果熟悉批处理编程的话,就应该知道%ld实际上是批处理程序的参数的声明方式)。

 

vsjitdebugger.exeVisual Studio用来处理验尸调试的调试器名称,如果你安装了Visual StudioVS的安装程序应该会自动为你设置好这个键。

 

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里面,分别创建下面两个键:

 

名称

类型

键值

DbgManagedDebugger

REG_SZ

"C:"Windows"system32"vsjitdebugger.exe" PID %d APPDOM %d EXTEXT "%s" EVTHDL %d

DbgJITDebugLaunchSetting

REG_DWORD

2

使用上面的设置,你应该可以做所有非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 StudioRPC调试功能同时调试COM程序的客户端和服务端

参看我以前的文章:
http://blog.csdn.net/Donjuan/archive/2009/01/23/3851586.aspx

标签:  Debug,  调试

这篇关于vs调试补遗的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/678248

相关文章

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

起点中文网防止网页调试的代码展示

起点中文网对爬虫非常敏感。如图,想在页面启用调试后会显示“已在调试程序中暂停”。 选择停用断点并继续运行后会造成cpu占用率升高电脑卡顿。 经简单分析网站使用了js代码用于防止调试并在强制继续运行后造成电脑卡顿,代码如下: function A(A, B) {if (null != B && "undefined" != typeof Symbol && B[Symbol.hasInstan

php 7之PhpStorm + Nginx + Xdebug运行调试

操作环境: windows PHP 7.1.10 PhpStorm-2017.2.4 Xdebug 2.5.4 Xdebug helper 1.6.1 nginx-1.12.2 注意查看端口占用情况 netstat -ano //查看所以端口netstat -aon|findstr "80" //查看指定端口占用情况 比如80端口查询情况 TCP 0.0.0.0:8

【2025】基于Python的空气质量综合分析系统的设计与实现(源码+文档+调试+答疑)

博主介绍:     ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生完成毕业项目和技术提升。 技术范围:     我熟悉的技术领域涵盖SpringBoot、Vue、SSM、HLMT