使用Windbg动态调试排查软件启动不了的问题

目录

1、问题说明

2、初步分析

3、使用Windbg启动程序进行动态调试

4、进一步分析

5、何时使用Windbg静态分析?何时使用Windbg进行动态调试?

6、最后


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       早上测试同事反映,安装新编译出来的版本后程序始终启动不起来,之前的版本都是正常的,就今天新出的版本有问题。于是用Windbg启动程序,快速分析了一下,很快定位了问题。下面来分享一下这个问题的完整排查过程。

1、问题说明

       测试同事安装完早上编译出来的软件版本,启动软件后一直没有反应,软件界面始终没有跳出来(应该显示软件的登录界面),到系统的任务管理器中查看进程一直在的,但就是没弹出软件界面。程序启动时没有报错,估计是软件底层模块出问题了。

目前软件的处理逻辑是,程序启动时会去初始化底层的模块,底层初始化完成后给上层回调一个初始化完成消息,上层在收到这个消息时会弹出软件登录界面。

2、初步分析

       以前我们遇到过这类问题,原因是底层在初始化时遇到问题导致长时间初始化没有完成,上层一直没收到初始化完成的通知消息,所以一直没显示软件界面。不知道这次是不是类似的问题?还有一种可能是,程序启动时调用的底层模块初始化接口一直没有返回,可能底层发生了死锁,导致接口卡住,一直没有返回,直接导致软件UI主线程卡死,也不会弹出软件主界面。

       这些都是猜测,需要详细分析后才能查出具体的原因。分析该问题的方式一般有两种,一种是查看运行日志,看看流程卡在那一块了;另一种是直接上Windbg调试器,用Windbg直接启动程序,分析启动时的运行轨迹。

3、使用Windbg启动程序进行动态调试

       启动Windbg,在工具栏中点击File -> Attach to a Process...,在弹出的窗口中找到目标exe程序的路径:

选中exe程序,然后点击确定,这样Windbg就将程序启动起来了。

      程序启动起来后,Windbg会附加上去,附加成功后Windbg会中断下来,如下所示:

输入g命令,将当前的中断给跳过去。但跳过去以后,显示几行信息后就不再跳动了:

似乎看不到啥有用的信息。

       软件界面线程是软件主线程,对应的线程号为0,于是使用~0s切换到UI主线程:

看到了ntdll!ZwWaitForSingleObject,这个是在等待某个内核对象,估计是UI线程一直在等待对象,估计是底层发生死锁了。

4、进一步分析

       于是输入kn命令查看UI主线程的函数调用堆栈,如下:

从调用堆栈中可以看出调用了WaitForSingleObject接口,因为没有加载pdb文件,所以调用堆栈中看不到有效的函数名。

函数调用堆栈中即使能看到函数名,一般都是导出接口的函数名,不是真实的函数名,相对于函数的偏移也比较大。比如getapistate+0x7b287这样的偏移,偏移值0x7b287很大,一般情况下函数不会太长,不会出现这么大的偏移值,所以一般出现较大的偏移值时显示的不是真实的函数名。

对于dll动态库,导出接口的符号对外才是可见的,很多时候是相对于导出函数的偏移,偏移可能会比较大。也有可能现对于模块名的偏移,比如libcurl++0x52396。如果要看具体的函数名,则需要拿到对应模块的pdb文件,Windbg加载pdb文件后就能显示具体的函数名了。

       从函数调用堆栈中可以看到,有哪些模块,然后使用lm命令查看二进制模块的时间戳,然后再到文件服务器上找对应时间点的pdb文件。拿到这些模块的pdb文件后,放到一个文件夹中,然后将该文件夹的路径设置到Windbg中,然后重新输入kn命令查看函数调用堆栈,就能看到具体的函数名了:

这样就能确定当前问题的具体原因了。从详细的函数调用堆栈信息可以看出,程序启动时调用底层初始化的接口,然后底层模块调用WaitForSingleObject接口去获取锁,一直拿不到锁,所以函数一直没返回,导致上层的UI线程卡住了,所以软件界面一直没显示出来。于是将问题反馈给底层模块的开发维护人员,让他们去排查发生死锁的原因。

维护底层模块同事最近对底层某个模块的代码进行了重构,在处理某个线程的代码时处理的有问题,所以导致了多线程死锁!

5、何时使用Windbg静态分析?何时使用Windbg进行动态调试?

       使用Windbg分析C++软件异常问题时,可以进行静态分析,也可以进行动态调试。 一般情况下,有dump文件生成时,则使用Windbg静态分析dump文件;没有dump文件时,则要尝试使用Windbg去动态调试目标进程。有时dump文件中的信息不足以分析出问题时,也可以尝试使用Windbg去动态调试。

       对于包含异常上下文信息的dump文件,一般是程序中安装的异常捕获模块感知到异常崩溃自动生成的,但并不是所有的异常异常捕获模块能感知到,感知不到也就无法生成dump文件了。程序发生异常崩溃时,如果程序中安装的异常捕获模块没有捕获到,则可以尝试到系统日志中去查看系统有没有生成dump文件。如果系统没有生成,可以尝试将Windbg挂到目标进程上进行动态调试,待复现异常崩溃时,Windbg就会中断下来,就可以进行分析了。

       对于系统生成dump文件的案例,可以参见我之前的案例文章:
使用Windbg分析从系统应用程序日志中找到的系统自动生成的dump文件去排查问题icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/132024253       关于使用Windbg静态分析dump文件的一般步骤,可以参见我之前的文章:
使用Windbg静态分析dump文件的一般步骤及要点详解icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/130873143      关于使用Windbg动态调试目标进程的一般步骤,可以参见我之前的文章:

使用Windbg动态调试目标进程的一般步骤及要点详解icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131029795       有些软件运行异常并没有产生崩溃,比如死循环、死锁(本文中的问题就是死锁引发的)等,是没有dump文件的,需要使用Windbg进行动态调试分析。

       关于何时使用Windbg静态分析、何时使用Windbg进行动态调试,可以参见我之前写的文章:

何时使用Windbg静态分析?何时使用Windbg动态调试?icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131806819

6、最后

       本文通过Windbg启动目标程序进行动态调试,快速定位了问题,这也充分体现了在某些场景下使用Windbg动态调试的优势。希望本文分享的内容,能给大家提供一个借鉴或参考。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中创建文件夹,删除文件夹

Linux中创建目录:mkdir 文件夹, 比如:mkdir test 删除文件夹:rm -rf 文件夹, 比如:rm -rf soft vi强制不保存退出命令:q!

YOLOv5算法改进(12)— 替换主干网络之Swin Transformer

前言:Hello大家好,我是小哥谈。Swin Transformer是一种基于Transformer的深度学习模型,它在视觉任务中表现出色。与之前的Vision Transformer(ViT)不同,Swin Transformer具有高效和精确的特性,并…

合宙Air724UG LuatOS-Air LVGL API控件--复选框 (Checkbox)

复选框 (Checkbox) 复选框主要是让用户进行一些内容选择,或者同意用户协议。 示例代码 – 复选框回调函数 function event_handler(obj, event) if event lvgl.EVENT_VALUE_CHANGED then print(“State”, lvgl.checkbox_is_checked(obj)) end end – 创建复选框…

图像处理简介

目录 基本术语 1 .图像(image) 1.1 像素(Pixel) 1.2 颜色深度(Color Depth) 1.3 分辨率(Resolution) 1.4 像素宽高比(Pixel Aspect Ratio) 1.5 帧率(FPS) 1.6 码率(BR) 1. …

sql各种注入案例

目录 1.报错注入七大常用函数 1)ST_LatFromGeoHash (mysql>5.7.x) 2)ST_LongFromGeoHash &#xff08;mysql>5.7.x&#xff09; 3)GTID (MySQL > 5.6.X - 显错<200) 3.1 GTID 3.2 函数详解 3.3 注入过程( payload ) 4)ST_Pointfromgeohash (mysql>5.…

day28 异常

to{}catch{} try{}catch{}的流传输 try {fis new FileInputStream("file-APP\\fos.txt");fos new FileOutputStream("fos.txt");int a ;while ((a fis.read())! -1){fos.write(a);}System.out.println(a); } catch (IOException e) {e.printStackTrace()…

关于Maxwell与Kafka和数据库的监控

1.Maxwell的配置 其实就是配置两端的配置信息,都要能连接上,然后才能去传输数据 config.properties #Maxwell数据发送目的地&#xff0c;可选配置有stdout|file|kafka|kinesis|pubsub|sqs|rabbitmq|redis producerkafka # 目标Kafka集群地址 kafka.bootstrap.servershadoop102…

机器学习概念

目录 一、人工智能、机器学习、深度学习的关系 二、什么是深度学习&#xff1f; 2.1 深度学习常用算法 一、人工智能、机器学习、深度学习的关系 人工智能、机器学习和深度学习的关系如下所示。 二、什么是深度学习&#xff1f; 深度学习( DL, Deep Learning) 是机器学习 …

【操作记录】pytorch_geometric安装方法

pytorch_geometric安装方法 github地址 主要不要直接pip install安装&#xff0c;会由于依赖无法安装而失败 点击here手动安装依赖 选择对应的pytorch版本&#xff0c;我的是Win10 Python3.8.3Pytorch1.8.1CUDA10.2 手动下载四个依赖包本地安装&#xff1a; 主要不要直接&am…

【深度学习】ChatGPT

本文基于Andrej Karpathy(OpenAI 联合创始人&#xff0c;曾担任特斯拉的人工智能和自动驾驶视觉主管)在Microsoft Build 2023上的演讲整理而成&#xff08;完整的视频在文末&#xff0c;直接拖到文章底部&#xff09;&#xff0c;主要分为2大部分&#xff1a; 1.如何训练GPT(可…

Git和Github的基本用法

目录 背景 下载安装 安装 git for windows 安装 tortoise git 使用 Github 创建项目 注册账号 创建项目 下载项目到本地 Git 操作的三板斧 放入代码 三板斧第一招: git add 三板斧第二招: git commit 三板斧第三招: git push 小结 &#x1f388;个人主页&#xf…

一文了解tcp/ip协议的运行原理

接触代理ip的人都了解https/sock5等ip协议&#xff0c;那么TCP/IP 协议又是什么&#xff1f; 一、什么是TCP/IP 协议&#xff1f; TCP/IP 协议实际上是一系列网络通信协议的一个统称&#xff0c;他负责具体的数据传输工作&#xff0c;核心的两个协议包括TCP以及IP&#xff0c…

搭建STM32F407的Freertos系统(基于STM32CubeMX)

本人长期开发Linux、Windows上应用软件&#xff0c;一直以来MCU开发有所接触&#xff0c;但较少&#xff08;最近项目需要&#xff0c;小公司么&#xff0c;都得会&#xff0c;被逼的&#xff09;&#xff0c;好在有STM32CubeMX这样工具&#xff0c;貌似就是我想要的工具。 本次…

自然语言处理实战项目16- 基于CPU的大语言模型的实战训练全流程指导,模型调优与评估

大家好,我是微学AI,今天给大家介绍一下自然语言处理实战项目16- 基于CPU的生成式大语言模型的实战训练全流程详细讲解,模型调优与评估。该流程涵盖了数据准备、数据预处理、词表构建、模型选择与配置、模型训练、模型调优和模型评估等步骤。通过不断迭代和优化,可以提高模型…

C++信息学奥赛1184:明明的随机数

#include <bits/stdc.h> using namespace std; int main() {int n; // 数组长度cin >> n; // 输入数组长度int arr[n]; // 定义整数数组&#xff0c;用于存储输入的整数// 输入数组元素for (int i 0; i < n; i){cin >> arr[i];}int e 0; // 计数器&…

数据结构体--5.0图

目录 一、定义 二、图的顶点与边之间的关系 三、图的顶点与边之间的关系 四、连通图 五、连通图的生成树定义 一、定义 图&#xff08;Graph&#xff09;是由顶点的又穷非空集合合顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G&#xff08;V&#xff0c;E&…

【UIPickerView案例03-点餐系统之随机点餐 Objective-C语言】

一、先来看看我们这个示例程序里面,随机点餐是怎么做的 1.点击:“随机点餐”按钮 大家能想到,它是怎么实现的吗 1)首先,点击”随机点餐“按钮,的时候,你要让这个pickerView,进行随机选中,那么,得监听它的点击 2)然后呢,让pickeView选中数据, 3)然后呢,把那个…

Leetcode54螺旋矩阵

思路&#xff1a;用set记录走过的地方&#xff0c;记下走的方向&#xff0c;根据方向碰壁变换 class Solution:def spiralOrder(self, matrix: list[list[int]]) -> list[int]:max_rows len(matrix)max_cols len(matrix[0])block_nums max_cols * max_rowscount 1i 0j…

详解mysql事务,事务并发安全问题的复现以及大事务的优化

好文推荐&#xff1a; 2.5万字详解23种设计模式 springboot 实现延时队列&#xff08;超级实用&#xff09; 2.5万字讲解DDD领域驱动设计 文章目录 1. 事务定义2. 事务特性&#xff08;ACID&#xff09;3. 事务并发问题4. 事务隔离级别5. 基础命令6. 脏读复现7. 不可重复读复现…

网络服务第二次作业

[rootlocalhost ~]# vim /etc/httpd/conf.d/vhosts.conf <Virtualhost 192.168.101.200:80> #虚拟主机IP及端口 DocumentRoot /www/openlab #网页文件存放目录 ServerName www.openlab.com #服务器域名 </VirtualHost> …