根据问题现象、用户操作场景及日志打印去排查C++软件问题,必要时尝试去复现问题

目录

1、概述

2、通过现有信息无法定位问题时,则需要尝试去复现问题

3、非崩溃问题与崩溃问题的一般排查思路

3.1、非崩溃问题的排查思路

3.2、崩溃问题的排查思路

4、难以复现问题的可能原因总结

4.1、问题难以复现,可能和某种特殊的业务场景或操作场景有关

4.1.1、特殊操作场景案例1 

4.1.2、特殊操作场景案例2

4.1.3、特殊操作场景案例3

4.1.4、特殊操作场景案例4

4.2、问题难以复现,可能与客户的环境有关,只在客户环境中才能复现

4.2.1、客户环境案例1

4.2.2、客户环境案例2

4.2.3、客户环境案例3

4.2.4、客户环境案例4

4.2.5、客户环境案例5

5、最后


C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/125529931C/C++实战进阶(已更新到460多篇,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/140824370VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/124272585Windows C++ 软件开发从入门到精通(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_12695902.htmlC++软件分析工具从入门到精通案例集锦(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/131405795开源组件及数据库技术(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_12458859.html网络编程与网络问题分享(专栏文章,持续更新中...)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/category_2276111.html       最近在技术群里有人问,遇到软件异常或崩溃时,排查起来很吃力,不知如何去排查,想知道都有哪些常规且通用的排查思路和方法可以去参考,今天我们就来说说这方面的内容。

1、概述

       当收到软件发生问题的报告时,我们先要确认问题的现象是什么,发生问题时的场景是什么,以及当前用户在出问题前执行了什么操作。通过现象和用户执行的操作,尝试去找排查问题的线索。

       如果软件中有日志输出,则可以结合着日志去分析。查看软件的打印日志,不仅能看到程序代码的执行途径或轨迹,还可以看到打印出来的部分变量的值(变量的值可能是排查软件问题的关键线索),通过代码执行轨迹和相关变量的值去对照着代码分析。如果问题还是难以定位,则可能要尝试去复现问题。

如果要借助日志去分析,且在相关代码中没有日志或者日志不全,我们可以根据需要在代码中添加新的日志打印,然后去复现问题。

2、通过现有信息无法定位问题时,则需要尝试去复现问题

       通过当前的问题现象、出问题时用户执行的操作以及现有的其他信息(比如日志),无法定位问题时,则需要尝试去复现问题。

       测试人员或其他相关人员,可以根据出问题前用户执行的操作去尝试复现问题,或者根据现有的现象及出问题之前用户执行的操作去猜测引发问题的可能原因或场景,去尝试复现问题。

       有些问题,可能是用户反馈的,用户一般都不太专业,用户无法讲述问题场景以及执行了哪些操作,所以很难确定是执行了什么操作引起的。如果问题是测试人员发现的,则测试人员会下意识地回想之前执行了哪些操作,主动地去尝试找到复现的方法。对于较难排查或者找不到排查思路的问题,一般我们会让测试人员帮忙复现,尽量找到复现问题的办法。

有些测试人员在复现问题时比较有天赋,很多问题都能找到复现的方法。有时我们开发也要尝试从业务场景和开发的角度去复现问题,有时测试人员复现不了的,开发人员可以从另一个视角将问题复现出来。这些我们都是亲身经历过的,深有体会的!

       复现问题,找到复现问题的方法与操作步骤,是排查问题的一种重要且有效的辅助手段与方法。找到复现问题的操作步骤或场景,通过复现的步骤或场景可以确定问题与哪些操作有关,这样就能大概确定问题与哪些代码有关,这样就确定了代码的排查范围和方向,然后在查阅对应代码的过程中结合用户执行的操作(复现问题的步骤),找出代码中可能存在的逻辑控制错误或业务异常。能将问题复现出来,不仅有利于问题的快速排查,也便于代码修改后的问题验证。

       有些问题是在客户环境中出现的,但在公司测试环境中没出现过(可能是公司内部测试环境中没有覆盖到对应的场景),如果问题很难排查定位,我们可以尝试在公司环境中复现如果在公司环境中能复现,在公司环境中排查会比较方便。在公司环境中可以随意地查看日志,调试程序,抓网络包分析,调用公司的资源来攻关排查。

3、非崩溃问题与崩溃问题的一般排查思路

      从软件是否崩溃的角度,可以将软件异常问题分为非崩溃问题与崩溃问题。崩溃问题则是软件直接发生了崩溃。非崩溃性问题,则包含的比较广,比如业务流程上的异常、交互数据上的异常、死锁与死循环等。下面大概地讲讲非崩溃问题以及崩溃问题的一般排查思路。

       之前系统总结过引发C++软件异常的常见原因,可以查看我的文章:

引发C++软件异常的常见原因分析与总结(实战经验分享)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/124996473      之前也详细总结了排查C++软件异常的常见方法与手段,可以查看我的文章:

排查C++软件异常的常见思路与方法(实战经验总结)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/120629327

3.1、非崩溃问题的排查思路

       对于非崩溃问题(包括死锁与死循环等问题),一般是软件逻辑问题或者数据异常导致的,可以先结合着问题现象或场景以及出问题时用户执行的操作进行分析。如果有日志,则可以结合着日志分析。查看软件运行日志是排查这类问题的常见且有效的方法。必要时还要使用Process Explorer、Windbg等工具去辅助分析排查。

3.2、崩溃问题的排查思路

       对于崩溃问题引发崩溃的代码点,可能就在崩溃点附近也可能隐藏于代码的上下文中很多崩溃会有延后性,执行了引发问题的代码不会立即导致程序崩溃,而是在后续执行的代码中产生的崩溃,比如代码中将指针指向的内存释放了,但没有将指针置为NULL,后续在访问这个指针时因为访问了野指针产生了崩溃。

       对于崩溃问题(此处主要讨论软件发布后的崩溃问题,不方便使用IDE去调试代码),一般我们通过在程序中安装异常捕获模块去感知捕获软件运行过程中出现的异常,并自动生成包含异常上下文信息的dump文件。事后取来dump文件,使用Windbg打开,进行静态分析。在Windbg中查看崩溃的那条汇编指令以及崩溃时的函数调用堆栈等信息,对照着C++源码进行分析。这是分析软件异常崩溃的最常用方法

       有时引发的崩溃的点,就在崩溃时的函数调用堆栈中,这类问题比较好排查。有时引发崩溃的点并不在当前的函数调用堆栈中(崩溃的延后性),引发崩溃的点位于相关代码的上下文中,这时就需要结合问题的现象或场景以及出问题时用户执行的操作,去查看代码上下文,找出引发问题的可疑点或线索,进行逐步的排查。如果需要的话,也可以查看日志打印,去查看代码的执行途径和相关变量的值去辅助分析。

       如果软件崩溃或闪退时没有生成dump文件(软件中安装的异常捕获模块,只能捕获到大部分异常,没法捕获到所有的异常),即软件中安装的异常捕获模块没有感知到软件异常。此时,可以尝试到系统的应用程序日志中查看,程序发生崩溃,系统肯定是知道的,看看系统有没有自动生成包含异常上下文的dump文件。以前在项目中遇到过,软件中安装的异常捕获模块没有感知到异常,但系统帮我们生成了dump文件,我们直接拿系统生成的dump文件去分析,相关案例查看我的文章:

使用Windbg分析从系统应用程序日志中找到的系统自动生成的dump文件去排查程序崩溃问题icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/132024253       如果系统也没有生成dump文件,则需要将调试器Windbg附加到软件进程上和软件一起跑,去复现问题。当崩溃复现后,调试器会自动中断下来,此时就可以查看崩溃时的函数调用堆栈去分析了。

       之前对软件崩溃或闪退且没有生成dump文件的问题的排查方法进行过系统的总结可以查看我的文章:

C++程序发生闪退且没生成dump文件问题的排查经验总结与分享icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/142907923

       关于如何使用Windbg分析dump文件、如何使用Windbg动态调试目标进程以及何时使用Windbg静态分析与何时使用Windbg进行动态调试,可以查看我的文章:
使用Windbg分析dump文件的一般步骤及要点详解icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/130873143使用Windbg调试目标进程的一般步骤及要点详解icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/135484906何时使用Windbg静态分析?何时使用Windbg动态调试?icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/131806819

4、难以复现问题的可能原因总结

       有些问题很好复现,但有些问题则较难复现。从多年的项目实践经历来看,问题难以复现,可能有以下几个原因:

1)可能和某种特殊的业务场景或操作场景有关;
2)可能与客户的环境有关,只在客户环境中才能复现或才好复现。

下面对这两点原因进行详细的展开,并给出相关的项目问题实例。

4.1、问题难以复现,可能和某种特殊的业务场景或操作场景有关

       某些代码在日常执行时不会执行到,只有在个别业务场景下或者特殊的场景下才会执行到。

4.1.1、特殊操作场景案例1 

       某次平台DCS白板服务器出异常,导致客户端的DCS业务模块与DCS服务器断链,然后客户端不断地尝试重连,但一直连不上。客户端的DCS业务模块是通过libwebsockets开源库和平台DCS服务器通信,我们实现服务器重连的代码实现的有问题。代码中对libwebsockets库若干接口调用的控制策略有问题,导致程序出现了死循环,导致程序占用了较高的CPU资源,导致客户系统运行变慢。该实战问题案例对应的文章链接:

使用Process Explorer查看线程的函数调用堆栈去排查程序高CPU占用问题icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/132830803

4.1.2、特殊操作场景案例2

       某次平台的某个服务器有异常,客户端连接上后会频繁的断链,断链后客户端又自动发起重连,重连上后调用某个接口,接口中使用GDI对象去生成图片,但这段操作GDI对象的代码有GDI资源泄漏。当时测试人员在对软件进行长时间的拷机测试,因为客户端在不断的重连,导致这段有GDI对象泄漏的代码被频繁地执行,在长时间运行之后,进程占用的GDI对象总数接近或达到进程1万个GDI对象的上限,导致界面绘制异常,程序接着出现闪退。在正常情况下,服务器不会不断的断开客户端的连接,客户端就不会不停地重连,这段有GDI对象泄漏的代码也不会被频繁地执行,这个问题就不会暴露出来。该实战问题案例对应的文章链接:

使用GDIView工具排查GDI对象泄漏导致程序UI界面绘制异常的问题icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/128625868

4.1.3、特殊操作场景案例3

       某天平台在升级导致部分业务服务器不可用,客户端内部会触发灾备,发起对服务器的重连,我们在处理底层上来的重连通知消息时代码有缺陷,出现了进行memcpy时访问了空指针的问题(memcpy的源地址为空),导致程序产生崩溃。

4.1.4、特殊操作场景案例4

       最近测试发现的一个问题,当前客户端正在发送桌面桌面共享,用户找到软件主界面中的会议挂断按钮退出会议,结果会残留一个会议视频窗口,且窗口无法关闭。用户一般很少这样操作,一般会先关闭桌面共享再去点击退出会议,不会在发送桌面共享的状态下退出会议,所以这个问题一直没暴露出来。之前公司内部在用软件时报过几次类似的问题,说退出会议后,会残留一个视频窗口且窗口也没法关闭,当时没法复现这个问题,没有排查问题的思路,一直没解决。这次测试人员发现了这个问题,并找到必现的办法(确定了问题场景)。所以结合这次测试发现的问题场景,猜测之前公司内部反馈的问题可能是在这个场景下出现的:出问题的用户,参加了视频会议,并发起了桌面共享进行讨论,会议讨论完后会议也要结束了,该端用户没有关闭桌面共享,会议被管理员结束了,这种场景下就出了残留视频窗口的问题。正好此次测试人员发现这个问题,所以将之前遗留的老大难问题也一并给解决了。

4.2、问题难以复现,可能与客户的环境有关,只在客户环境中才能复现

       可能和客户机器系统的软硬件环境、客户系统中复杂的组网环境有关,这些问题在公司测试环境中没出现过(在公司测试环境中很难复现),项目中我们多次遇到。

4.2.1、客户环境案例1

       客户机器上的USB摄像头名称比较长,导致程序中的buffer长度不够被越界,导致程序崩溃。该实战问题案例对应的文章链接:

通过查看Windbg中变量值去定位C++软件异常问题icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/125731044

4.2.2、客户环境案例2

       客户端软件在客户笔记本上运行时使用笔记本内置的摄像头(不是通用的品牌摄像头),采集出来的图像显示出来时有闪烁、也有绿边。经排查,是在处理视频数据时污染了数据导致显示出来的图像出现异常。

4.2.3、客户环境案例3

       某个项目中服务器程序在客户复杂的组网环境下出现业务交互上的问题。比如某客户网络中部分网络节点下禁止发送广播,且采用IP与MAC地址绑定的机制,导致不满足条件的服务器设备网络通信出现问题,发到网络上的数据包被网络设备拦截或丢弃,没法到达目的地,导致平台业务出现异常。

4.2.4、客户环境案例4

       某个项目中客户网络中某个节点下硬终端发送出来的视频图像有严重的卡顿和丢包后来抓包分析发现,该节点下的路由器做了重定向的配置,当有数据发给网络设备要发出去时,网络设备给发送方回了一个重定向的消息,让发送方不要从当前的默认网关出去,从该消息中携带的IP地址出去。发送方收到该重定向消息,将由硬件设备中的Linux系统的系统协议栈去响应。但我们的硬件终端处于安全考虑,将终端中的系统协议栈的重定向属性给关闭了,导致硬件中断发出的音视频数据还是从默认的网关发出去,而从这个默认网关出去的数据就会有明显的丢包问题。

       此处讲到的两个网络实战问题排查案例,可以查看我的文章:

【网络进阶】网络问题排查实例集锦(实战经验分享)icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/124643918

对于网络相关问题,主要通过在客户端或者服务器侧抓网络包去分析。对于软件UI或者业务上的问题,在有日志的情况下,主要通过运行日志去排查。查看软件运行过程中的打印日志,是排查软件问题的常用方法之一。从运行日志中,不仅能看到程序的执行途径或轨迹,还可以在日志中将相关变量的值打印出来,主要通过代码执行轨迹和相关变量的值去对照着代码分析。当问题发生时,如果在相关代码中没有日志或者日志不全,我们则要根据需要去在代码中添加新的日志,然后去复现问题。在问题相关的代码中添打印日志之后,可能问题难以复现,只能等到下次复现时才能去查看日志分析。所以,有个完备的日志系统对于软件是非常重要的。

4.2.5、客户环境案例5

       在某个项目中第三方安全软件的注入模块有内存泄漏,直接影响到我们的软件。客户机器上安装了第三方安全软件,安全软件为了监控我们软件的通信数据,会通过某个注入模块注入到我们的客户端软件中。但该安全软件的注入模块有内存泄漏,因为其注入到我们的软件进程中,运行在我们的软件进程中,直接导致我们软件进程发生内存泄漏,持续泄漏一段时候因为内存耗尽程序发生闪退。相关案例可以查看我之前写的文章

第三方模块远程注入到C++软件中引发软件异常的若干实战案例分享icon-default.png?t=O83Ahttps://blog.csdn.net/chenlycly/article/details/140742772

5、最后

       排查问题时,我们先看看问题的现象或场景以及出问题时用户执行了哪些操作,将这些信息结合着代码进行分析。也可以查看软件打印出的日志去辅助分析。如果通过现有信息无法排查出问题,则可能需要去复现问题了。如果问题能复现,则通过复现问题的操作步骤与场景去分析排查问题。

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

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

相关文章

《JVM第3课》运行时数据区

无痛快速学习入门JVM,欢迎订阅本免费专栏 运行时数据区结构图如下: 可分为 5 个区域,分别是方法区、堆区、虚拟机栈、本地方法栈、程序计数器。这里大概介绍一下各个模块的作用,会在后面的文章展开讲。 类加载子系统会把类信息…

class 100 KMP算法原理和代码详解

1. KMP 算法介绍 1.1 暴力方法 暴力方法就是将两个字符串进行一个一个比较 这个知道就行了, 我们的重点是 KMP 算法 1.2 KMP 算法介绍 暴力方法的时间复杂度是:O(n * m), 使用 KMP 算法可以将时间复杂度优化到:O(n m). 暴力方法时间慢的原因是&…

不基于Gin手撸一个RPC服务

目标 实现一个GRPC框架,可以通过grpc-ui来对接口进行访问。也可以使用client来直接调用服务端服务 准备(这边以Mac系统举例) 安装homebrew(如果没有安装的话) /bin/bash -c "$(curl -fsSL https://raw.github…

大数据治理:策略、技术与挑战

随着信息技术的飞速发展,大数据已经成为现代企业运营和决策的重要基础。然而,大数据的复杂性、多样性和规模性给数据管理带来了前所未有的挑战。因此,大数据治理应运而生,成为确保数据质量、合规性、安全性和可用性的关键手段。本…

Web应用性能测试工具 - httpstat

在数字化时代,网站的性能直接影响用户体验和业务成功。你是否曾经在浏览网页时,遇到加载缓慢的困扰?在这个快速变化的互联网环境中,如何快速诊断和优化Web应用的性能呢?今天,我们将探讨一个强大的工具——h…

宝藏虚拟化学习资料大全

最近发现了关于虚拟化的宝藏资料,瑞斯拜!原文链接如下: 500篇关于虚拟化的经典资料,含CPU虚拟化,磁盘虚拟化,内存虚拟化,IO虚拟化。 目录 🪐 虚拟化基础 🍃 虚拟化分类&…

【源码+文档】基于SpringBoot+Vue旅游网站系统【提供源码+答辩PPT+参考文档+项目部署】

作者简介:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流。✌ 主要内容:🌟Java项目、Python项目、前端项目、PHP、ASP.NET、人工智能…

微服务核心——网关路由

目录 前言 一、登录存在的问题归纳 二、*微服务网关整体方案 三、认识微服务网关 四、网关鉴权实现 五、OpenFeign微服务间用户标识信息传递实现 六、微服务网关知识追问巩固 前言 本篇文章具体讲解微服务中网关的实现逻辑、用于解决什么样的问题。其中标题中标注* 涉…

移植 AWTK 到 纯血鸿蒙(HarmonyOS NEXT)系统 (0) - 序

移植 AWTK 到 纯血鸿蒙 (HarmonyOS NEXT) 系统 (0) - 序 前段时间纯血鸿蒙系统 HarmonyOS 5.0(又称 HarmonyOS NEXT)正式推出,这是继苹果 iOS 和安卓系统后,全球第三大移动操作系统。纯正国产操作系统登场,国人无不欢…

docker-compose安装rabbitmq 并开启延迟队列和管理面板插件(rabbitmq_delayed_message_exchange)

问题: 解决rabbitmq-plugins enable rabbitmq_delayed_message_exchange :plugins_not_found 我是在docker-compose环境部署的 services:rabbitmq:image: rabbitmq:4.0-managementrestart: alwayscontainer_name: rabbitmqports:- 5672:5672- 15672:156…

SpringBoot AOP介绍、核心概念、相应实现

文章目录 AOP介绍AOP的核心概念切面(Aspect)切点(Join Point)语法具体解释 增强(Advice)织入(weaving) 相应实现权限校验日志输出 AOP介绍 AOP全称Aspect Oriented Programming意为面向切面编程,通过预编译和运行期间通过动态代理来实现程序功能统一维护的技术。AO…

Python 数据结构对比:列表与数组的选择指南

文章目录 💯前言💯Python中的列表(list)和数组(array)的详细对比1. 数据类型的灵活性2. 性能与效率3. 功能与操作4. 使用场景5. 数据结构选择的考量6. 实际应用案例7. 结论 💯小结 &#x1f4af…

CSS 超出一行省略号...,适用于纯数字、中英文

文本超出显示省略号... 代码: .ellipsis{ overflow: hidden; -webkit-line-clamp:1; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; word-break: break-all; /** 纯数字、中英文都适用 */ }

C/C++中标准的输入输出

一、c语言的标准输入输出 c语言的标准输出函数式printf,它可以将用户设置的变量输出到控制台;标准的输入函数式scanf,接收用户在控制台的输入数据,注意,如果使用的是visual stdio编译器,会提示使用scanf_s…

Elasticsearch中时间字段格式用法详解

Elasticsearch中时间字段格式用法详解 攻城狮Jozz关注IP属地: 北京 2024.03.18 16:27:51字数 758阅读 2,571 Elasticsearch(简称ES)是一个基于Lucene构建的开源、分布式、RESTful搜索引擎。它提供了全文搜索、结构化搜索以及分析等功能,广泛…

Java实战项目-基于SpringBoot+Vue的二手车交易系统的研究与实现

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

Redis安装与使用 + Springboot整合Redis

Redis安装与使用 Springboot整合Redis 前言Redis简介Redis优势 Redis安装Windows1.相关配置2.启动Redis服务3.连接Redis,进行操作4.测试一些Redis命令 Linux Springboot项目整合使用Redis1.添加Maven依赖2.配置Redis相关属性3.在测试类中进行测试 结语 &#x1f60…

lust变频器维修电梯变频器CDD34.014.W2.1LSPC1

LUST伺服在安装时须注意,不可有任何的铁屑、螺丝、导线等掉人驱动器内。在安装完成后应作基本的检测动作,如对地阻抗,和短路检测等。 所有的安装及使用事项需要符合安全规定,并且也需要符合当地的相关规定和灾害预防措施。DC BUS…

在VSCode中读取Markdown文件

在VSCode安装Markdown All in One或Markdown Preview Enhanced即可 插件Markdown All in One GitHub:https://github.com/yzhang-gh/vscode-markdown v3.6.2下载链接:https://marketplace.visualstudio.com/_apis/public/gallery/publishers/yzhang/vs…

闪存学习_2:Flash-Aware Computing from Jihong Kim

闪存学习_2:Flash-Aware Computing from Jihong Kim【1】 一、三个闪存可靠性问题二、内存的分类三、NAND 闪存和 NOR 闪存四、HDD和SSD比较Reference 一、三个闪存可靠性问题 耐性(即寿命):最多能经受编程和擦除的次数。数据保留…