使用Windbg动态调试排查软件启动不了的问题
目录
1、问题说明
2、初步分析
3、使用Windbg启动程序进行动态调试
4、进一步分析
5、何时使用Windbg静态分析?何时使用Windbg进行动态调试?
6、最后
VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)
https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)
https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)
https://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文件去排查问题
https://blog.csdn.net/chenlycly/article/details/132024253 关于使用Windbg静态分析dump文件的一般步骤,可以参见我之前的文章:
使用Windbg静态分析dump文件的一般步骤及要点详解
https://blog.csdn.net/chenlycly/article/details/130873143 关于使用Windbg动态调试目标进程的一般步骤,可以参见我之前的文章:
使用Windbg动态调试目标进程的一般步骤及要点详解
https://blog.csdn.net/chenlycly/article/details/131029795 有些软件运行异常并没有产生崩溃,比如死循环、死锁(本文中的问题就是死锁引发的)等,是没有dump文件的,需要使用Windbg进行动态调试分析。
关于何时使用Windbg静态分析、何时使用Windbg进行动态调试,可以参见我之前写的文章:
何时使用Windbg静态分析?何时使用Windbg动态调试?
https://blog.csdn.net/chenlycly/article/details/131806819
6、最后
本文通过Windbg启动目标程序进行动态调试,快速定位了问题,这也充分体现了在某些场景下使用Windbg动态调试的优势。希望本文分享的内容,能给大家提供一个借鉴或参考。
相关文章:
使用Windbg动态调试排查软件启动不了的问题
目录 1、问题说明 2、初步分析 3、使用Windbg启动程序进行动态调试 4、进一步分析 5、何时使用Windbg静态分析?何时使用Windbg进行动态调试? 6、最后 VC常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...&…...
Swift 技术 视频播放器滚动条(源码)
一直觉得自己写的不是技术,而是情怀,一个个的教程是自己这一路走来的痕迹。靠专业技能的成功是最具可复制性的,希望我的这条路能让你们少走弯路,希望我能帮你们抹去知识的蒙尘,希望我能帮你们理清知识的脉络࿰…...
PixelSNAIL论文代码学习(2)——门控残差网络的实现
文章目录 引言正文门控残差网络介绍门控残差网络具体实现代码使用pytorch实现 总结 引言 阅读了pixelSNAIL,很简短,就用了几页,介绍了网络结构,介绍了试验效果就没有了,具体论文学习链接 这段时间看他的代码,还是挺痛…...
WebGPU学习(9)---使用Pipeline Overridable Constants
使用Pipeline Overridable Constants WebGPU 的着色器语言是 WGSL,但与 GLSL 和 HLSL 不同,不支持 #ifdef 等宏。为了实现各种着色器变体,迄今为止,宏一直是着色器编程中非常重要的功能。那么应该如何处理没有宏的 WGSLÿ…...
javaweb入门版学生信息管理系统-增删改查+JSP+Jstl+El
dao public class StudentDao {QueryRunner queryRunner QueryRunnerUtils.getQueryRunner();//查询全部学生信息public List<Student> selectStudent(){String sql "select * from tb_student";List<Student> students null;try {students queryRunn…...
云原生Kubernetes:K8S概述
目录 一、理论 1.云原生 2.K8S 3.k8s集群架构与组件 二、总结 一、理论 1.云原生 (1)概念 云原生是一种基于容器、微服务和自动化运维的软件开发和部署方法。它可以使应用程序更加高效、可靠和可扩展,适用于各种不同的云平台。 如果…...
nmap的使用
目录 nmap简介 主要作用 nmap原理 namp使用 options nmap列举远程机器开放端口 普通扫描 扫描范围端口 对几个端口探测 对所有端口进行探测 指定协议探测端口 扫描对应协议的所有端口 端口状态 nmap识别目标机器上服务的指纹 服务指纹 识别目标机器服务信息 …...
Python爬虫-某网酒店数据
前言 本文是该专栏的第5篇,后面会持续分享python爬虫案例干货,记得关注。 本文以某网的酒店数据为例,实现根据目标城市获取酒店数据。具体思路和方法跟着笔者直接往下看正文详细内容。(附带完整代码) 正文 地址:aHR0cHM6Ly93d3cuYnRoaG90ZWxzLmNvbS9saXN0L3NoYW5naGFp …...
了解atoi和offsetof
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一、简介 二、深度剖析 1.atoi 2.offsetof 三、应用场景 一、简介二、深度剖析 1.atoi2.offsetof三、应用场景 一、简介 在C语言中,有许多…...
命令行编译VS工程
先输入以下命令,因为命令出错了,就会弹出帮助,如下: "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe" /help 反正就是Microsoft Visual Studio 的安装路径。 帮助界面如下:…...
Linux防火墙命令
开启防火墙 systemctl start firewalld关闭防火墙 systemctl stop firewalld # 暂时关闭防火墙 systemctl disable firewalld # 永久关闭防火墙(禁用开机自启) systemctl enable firewalld # 永久开启防火墙(启用开机自启)重启防火墙 systemctl restart firewalld重载规则 …...
大数据平台数据脱敏是什么意思?有哪些方案?
大数据平台包含了海量多样化数据,所以保障大数据平台数据安全非常重要,数据脱敏就是手段之一。今天我们就来简单聊聊大数据平台数据脱敏是什么意思?有哪些方案? 大数据平台数据脱敏是什么意思? 大数据平台数据脱敏简…...
前后端分离不存在会话,sessionid不一致问题
目录 1.使用拦截器解决跨域的示例: 2.使用redis,不使用session 前后端不分离项目我们可以通过session存储数据,但是前后端分离时不存在会话,每次请求sessionid都会改变,当值我们储存的数据不能取出来。 1.使用拦截器…...
Python 3+ 安装及pip配置
Python 3 安装及pip安装升级 1. 安装Python依赖2. 在Linux服务器下载3. 创建python链接4. 配置pip 服务器环境:Linux CentOS 7 内核版本3.10 Python版本:3.10.6 由于CentOS 7默认安装python2.7,使用yum可以查到最新的python3版本为3.6.8&…...
StarRocks入门到熟练
1、部署 1.1、注意事项 需要根据业务需求设计严谨的集群架构,一般来说,需要注意以下几项: 1.1.1、FE数量及高可用 FE的Follower要求为奇数个,且并不建议部署太多,通常我们推荐部署1个或3个Follower。在三个Followe…...
Zabbix Api监控项值推送:zabbix_sender
用法示例: zabbix_sender [-v] -z server [-p port] [-I IP-address] [-t timeout] -s host -k key -o value其中: -z 即 --zabbix-server,Zabbix server的主机名或IP地址。如果主机由proxy监控,则应使用proxy的主机名或IP地址-…...
Shell脚本开发:printf和test命令的实际应用
目录 Shell printf 命令 打印简单文本 Shell test 命令 1、文件测试 2、字符串比较 3、整数比较 逻辑运算: Shell printf 命令 当你使用Shell中的printf命令时,它可以帮助你格式化和输出文本。 打印简单文本 这将简单地打印字符串"Hello, …...
React笔记(三)类组件(1)
一、组件的概念 使用组件方式进行编程,可以提高开发效率,提高组件的复用性、提高代码的可维护性和可扩展性 React定义组件的方式有两种 类组件:React16.8版本之前几乎React使用都是类组件 函数组件:React16.8之后,函数式组件使…...
Hugging Face实战-系列教程4:padding与attention_mask
🚩🚩🚩Hugging Face 实战系列 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在notebook中进行 本篇文章配套的代码资源已经上传 上篇内容: Hugging Face实战-系列教程3:文本2分类 下篇内容: …...
睿趣科技:抖音开网店卖玩具怎么样
近年来,随着社交媒体平台的飞速发展,抖音作为一款短视频分享应用也迅速崭露头角。而在这个充满创业机遇的时代背景下,许多人开始探索在抖音平台上开设网店,尤其是卖玩具类商品,那么抖音开网店卖玩具究竟怎么样呢? 首先…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
