使用WinDbg进行动态调试

news2024/11/28 8:49:14

前言

  • 本文章主要介绍如何使用WinDbg进行动态调试。如果程序崩溃后,没有记录dump文件,或者程序启动时发生异常,比如常见的 应用程序无法正常启动(0xc000007b) 报错,都可以使用WinDbg动态调试功能来定位问题。文章最后,对WinDbg常用命令进行了总结。
  • 对WinDbg不熟悉的可以参考我的另一篇WinDbg入门教程 WinDgb安装和使用

什么时候使用WinDbg进行动态调试

  • 程序崩溃后没有生成dump文件
  • 使用visual studio调试时发生异常,看不到完整的调用堆栈
  • 程序启动时发生异常错误,比如比较常见的 应用程序无法正常启动(0xc000007b)

WinDbg动态调试步骤

  • 测试程序
    •   #include <windows.h>
        #include <stdio.h>
        
        void myfunc() {
        	printf("join to myfunc...\n");
        
        	//这里程序会崩溃
        	char* p = NULL;
        	memcpy(p, "hello word", strlen("hello word"));
        
        	printf("end myfunc");
        }
        
        void myMath(int a, int b) {
        	int sum = 0;
        	sum = a + b;
        	printf("sum = %d\n", sum);
        
        	myfunc();
        
        	int minus = 0;
        	minus = a - b;
        	printf("sum = %d\n", sum);
        }
        
        int main() {
        
        	myMath(10, 20);
        	system("pause");
        	return 0;
        }
      
  • 使用WinDbg动态调试程序
    • 先启动我们的程序,打开WinDbg,选择File->Attach to a Process,然后选择要调试的目标进程。这里会看到当前运行的所有进程,选择你要调试的进程即可。
      在这里插入图片描述

    • 如果要调试程序无法正常启动,或者说启动后会直接退出,那么也可以直接使用WinDbg打开程序进行调试,选择 File->Open Executable,选择要调试的程序打开即可。

    • 运行后默认会终端,在命令行输入g命令,可以继续运行
      在这里插入图片描述
      在这里插入图片描述

    • 通过上面测试程序可以知道,程序运行后会崩溃,从调试信息可以看到,发生Access violation,即内存访问违规。

    • 使用kn命令,可以看到具体的堆栈信息,并且打印了的行号。
      在这里插入图片描述

    • 如果这里的堆栈没有函数和行号信息,是因为没有加载pdb文件,选择File->Symbol File Path将pdb所在目录添加进去即可。

    • 使用lm命令可以查看pdb文件是否加载上了,使用lm vm 模块名可以看到更详细的信息。如果pdb文件的完整路径打印出来了,说明加载成功了。
      在这里插入图片描述
      在这里插入图片描述

    • 如果pdb文件加载失败,第一个原因就是可执行程序和pdb文件不一致,也就是说可执行程序可能改过代码了,但pdb文件还是之前的。还有一个原因就是可执行程序和pdb文件时间戳不一致,也就是说代码是一致的,但可执行程序生成时间和pdb生成时间不一致。如果还有其他问题导致pdb文件加载失败,可以使用 .reload /f 可执行程序名 强制加载pdb文件。

    • 可以通过 File->Source File Path将源代码路径设置进行,就可以在WinDbg中使用源代码调试了
      在这里插入图片描述

    • 那么相比于使用Visual Studio调试,WinDbg有什么好处呢。比如我们写完程序,放到客户电脑上,程序运行异常了,从日志和dump文件都分析不出问题,而且开发机还复现不了问题。这个时候就只能在客户电脑上调试了。那如果使用Visual Studio调试,我们不仅要去搭建环境,而且还要将代码拷贝到客户电脑上,实际场景肯定是不现实的。这个时候就可以使用WinDbg来进行调试了,只需要在客户电脑上安装一个WinDbg,并把对应程序的pdb文件拷贝过去,就可以现场进行调试了。

通过WinDbg导出dump文件

  • 如果程序崩溃了,但我们程序又没有记录dump文件的功能,可以通过 .dump /ma dump文件名 命令将dump文件导出,事后进行分析。
    在这里插入图片描述

应用程序无法正常启动(0xc000007b)分析

  • 这种报错一般是由于可执行程序的依赖库位数不匹配导致的,比如我这个可执行程序依赖的vcruntime140d.dll是64位,我打包发布的时候,拷了一个32位的库进去,运行时就会报这个错误。
    在这里插入图片描述
    在这里插入图片描述
  • 那实际项目中,可执行程序依赖的库是很多的,我们不知道哪一个依赖库出现了问题,就可以使用WinDbg来进行动态调试。
    在这里插入图片描述
  • 使用WinDbg调试时可以看到,加载vcruntime140d.dll时出现了错误,这样我们就能准确定位到是哪个依赖库出问题了。

WinDbg常用命令

  • g
    • 跳过当前中断,继续运行
  • .ecxr
    • 切换到发生异常的线程中。如果是动态调试,会直接切换到异常的线程中,因此不需要执行此命令。
  • kn/kv/kp
    • 查看当前线程的函数调用堆栈
  • lm
    • 查看二exe或者二进制文件的信息,lm vm fileDump 可以查看fileDump模块的详细信息。
  • .reload
    • 加载pdb文件,比如 .reload /f fileDump.exe , 强制加载 fileDump.exe的pdb文件
  • ~
    • 查看当前进程所有线程信息
  • ~ns
    • 切换到n号线程中
  • !analyze
    • 详细分析当前异常,完整命令为 !analyze -v
  • .dump
    • 导出dump文件,比如 .dump /ma F:\0001.dmp
  • bp/bl/bc
    • bp : 添加断点,比如 bp fileDump!main,给fileDump模块中的main函数设置断点
    • bl : 列出当前所有断点
    • bc : 清除断点
  • r
    • 查看当前线程所有寄存器的值
  • .cls
    • 清屏
  • .effmach
    • 切换当前进程的上下文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/992445.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用go实现一个循环队列

目录 队列数组队列的“假溢出”现象循环队列三种判断队列空和满的方法无下标&#xff08;链式&#xff09;有下标&#xff08;顺序&#xff09;长度标记 go用顺序表实现一个循环队列队列的链式存储结构 队列 队列&#xff08;queue&#xff09;是只允许在一端进行插入操作&…

物联网世界的无线电报之MQTT详解

文章目录 1. 前言1.1. 物联网与MQTT的关系1.2. MQTT的重要性及应用场景 2. MQTT基础2.1. MQTT的定义与起源2.2. MQTT的工作原理2.3. MQTT的协议格式2.4. 用java造个轮子 3. 深入理解MQTT3.1. MQTT的主要组件3.1.1. Publisher&#xff08;发布者&#xff09;3.1.2. Subscriber&a…

RTSP流媒体服务器EasyNVR视频平台以服务方式启动异常却无报错,该如何解决?

EasyNVR是基于RTSP/Onvif协议的安防视频云服务平台&#xff0c;可实现设备接入、实时直播、录像、检索与回放、云存储、视频分发、级联等视频能力服务&#xff0c;可覆盖全终端平台&#xff08;电脑、手机、平板等终端&#xff09;&#xff0c;在智慧工厂、智慧工地、智慧社区、…

【2023微博评论爬虫】用python爬上千条微博评论,突破15页限制!

文章目录 一、爬取目标二、展示爬取结果三、爬虫代码四、同步视频五、获取完整源码 您好&#xff0c;我是 马哥python说&#xff0c;一枚10年程序猿。 一、爬取目标 前些天我分享过一篇微博的爬虫&#xff1a; 马哥python说&#xff1a;【python爬虫案例】爬取微博任意搜索关…

【网络编程】IO多路复用

IO多路复用是一种高效的I/O处理方式&#xff0c;它允许单个进程能够同时监视多个文件描述符&#xff08;sockets、文件等&#xff09;&#xff0c;并在其中任何一个文件描述符准备好进行I/O操作时进行处理。它的核心在于使用少量的线程或进程来管理多个I/O操作&#xff0c;以提…

【JavaSpring】spring接口-beanfactory和applicationcontext与事件解耦

beanfactory 1.applicationcontext的父接口 2.是Spring的核心容器 功能 表面只有getBean&#xff0c;但实现类默默发挥了巨大作用 1.管理所有bean 2.控制反转 3.基本的依赖注入 applicationcontext 功能 1.继承了MessageSource&#xff0c;有了处理国际化资源的能力 …

【C++】继承基础知识一遍过

目录 一&#xff0c;概念 二&#xff0c;继承定义 1. 继承格式 2. 访问限定符与继承方式的关系 3. 继承父类成员访问方式的变化 小结&#xff1a; 三. 父类与子类对象赋值转化 四&#xff0c;继承作用域 1.特点 2. 测试题 五&#xff0c;派生类不一样的默认成员函…

【nacos】2.1.1持续输出事件警告日志

nacos-server 2.1.1 持续输出事件警告日志,修复NamingTraceEvent连续打印日志。这是 2.1.1 beta 功能跟踪事件。如果没有订阅者处理TraceEvent&#xff0c;将打印此日志。2.1.1版本中忽略它&#xff0c;我们将在2.1.2版本中对其进行增强。 WARN There are no [com.alibaba.nac…

Linux系统中驱动之设备树的platform驱动实现

每日一个简单的驱动&#xff0c;日久方长&#xff0c;对Linux驱动就越来越熟悉&#xff0c;也越来容易学会写驱动程序。今日进行设备树下的platform设备驱动。 前面一篇我们讲解了传统的、未采用设备树的 platform 设备和驱动编写方法。最新的 Linux 内核已经支持了设备树&…

c语言练习45:模拟实现内存函数memcpy

模拟实现内存函数memcpy 针对内存块&#xff0c;不在乎内存中的数据。 拷贝内容有重叠的话应用memmove 模拟实现&#xff1a; 代码&#xff1a; 模拟实现memcpy #include<stdio.h> #include<assert.h> void* my_memcpy(void* dest, const void* src, size_t num…

【计算机基础知识3】IP 地址和子网掩码、DNS、HTTP

目录 前言 一、IP地址和子网掩码 1. IP地址的概念 2. IP地址的分类 3. 子网掩码的概念 4. 子网掩码的用途 二、域名系统&#xff08;DNS&#xff09; 1. DNS的作用 2. 域名解析过程 3. 如何配置和管理域名解析 三、HTTP&#xff08;超文本传输协议&#xff09; 1. H…

Pytest系列-测试用例前后置固件setup和teardown的介绍和使用(2)

简介 在unittest框架中&#xff0c;有两个前置方法&#xff0c;两个后置方法&#xff0c;还有两个模块方法&#xff0c;分别是 setup()&#xff1a;每个用例执行之前都会自动调用setupClass()&#xff1a;在类中所有的测试方法执行前会自动执行的代码&#xff0c;只执行一次t…

华为云中对象存储服务软件开发工具包(OBS SDK) C语言介绍

华为云的OBS介绍&#xff1a;摘自华为云官网&#xff1a;https://support.huaweicloud.com/obs/index.html 华为云的对象存储服务(Object Storage Service&#xff0c;OBS)是一个基于对象的海量存储服务&#xff0c;为客户提供海量、安全、高可靠、低成本的数据存储能力。 …

华为云云耀云服务器L实例评测|在Docker环境下部署Statping服务器监控工具

华为云云耀云服务器L实例评测&#xff5c;在Docker环境下部署Statping服务器监控工具 一、前言1.1 云耀云服务器L实例简介1.2 Statping简介1.3 Statping特点 二、本次实践介绍2.1 本次实践简介2.2 本次环境规划 三、购买云耀云服务器L实例3.1 购买云耀云服务器L实例3.3 查看云耀…

商汤科技AGI这些年:上半场「基建」,下半场「变现」

【潮汐商业评论/原创】 纵观一次次科技革命引领的生产力变革&#xff0c;都绝非一蹴而就&#xff0c;而是在不断的技术突破中&#xff0c;找到产业的落脚点&#xff0c;再回归到社会应用中去。 当下的人工智能也是如此。今年以来&#xff0c;大模型和生成式AI作为重要的科技突…

OpenCV项目实战(1)— 如何去截取视频中的帧

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。针对一段视频&#xff0c;如何去截取视频中的帧呢&#xff1f;本节课就给大家介绍两种方式&#xff0c;一种方式是按一定间隔来截取视频帧&#xff0c;另一种方式是截取视频的所有帧。希望大家学习之后能够有所收获&#x…

无涯教程-JavaScript - IMSIN函数

描述 IMSIN函数以x yi或x yj文本格式返回复数的正弦。复数的正弦为- $$\sin(x yi) \sin(x)\cosh(y) \cos(x)\sin(y)i $$ 语法 IMSIN (inumber)争论 Argument描述Required/OptionalInumberA Complex Number for which you want the sine.Required Notes Excel中的复数仅…

python-55-打包exe执行

目录 前言一、pyinstaller二、实践打包exe1、遇坑1&#xff1a;Plugin already registered2、遇坑2&#xff1a;OSError 句柄无效 三、总结 前言 你是否有这种烦恼&#xff1f; 别人在使用你的项目时可能还需要安装各种依赖包&#xff1f;别人在使用你的项目&#xff0c;可能…

Bean 的生命周期总结

目录 一、Bean生命周期的五个阶段 Bean的初始化 二、PostConstruct 和 PreDestroy 各自的效果 三、 实例化和初始化的区别 四、为什么要先设置属性在进⾏初始化呢&#xff1f; 一、Bean生命周期的五个阶段 Java 中的公共类称之为 Bean 或 Java Bean&#xff0c;而 Spring 中的…

深度学习的数值问题

文章目录 梯度下降临界点、驻点、拐点、鞍点、顶点&#xff08;曲线&#xff09;、曲率近似优化预测最佳步长 梯度下降 往斜率的反方向走。 临界点、驻点、拐点、鞍点、顶点&#xff08;曲线&#xff09;、曲率 临界点&#xff1a;在数学中&#xff0c;临界点是指函数的导数为…