美文网首页
软件诊断-症状收集与分析

软件诊断-症状收集与分析

作者: 若隐爱读书 | 来源:发表于2023-06-23 22:44 被阅读0次

    在人类医学的诊断学中,症状收集与分析是指在发现疾病或病理后,收集并分析相关的信息,以便确定疾病或病理的类型和原因。这些信息包括病史、体格检查、实验室检查、影像学检查等。根据不同的情况,医生会采用不同的技巧和工具,来进行差别诊断、鉴别诊断、综合诊断等。有时候,医生还会使用数学或统计模型,来预测疾病或病理的发展趋势和治疗效果。

    软件诊断学与人类医学的诊断学有很多相似之处。软件也可以被视为一种复杂的系统,它也会出现故障或异常,需要进行诊断和修复。软件诊断学中的症状收集与分析,就是指在发现软件故障后,收集并分析相关的信息,以便确定故障的原因和解决方案。

    收集素材

    当软件出现故障时,我们需要尽可能多地收集相关的素材,以便进行分析。这些素材包括:

    • 日志:日志是记录软件运行过程中的事件和状态的文件。日志可以帮助我们了解软件在故障发生前后的行为和状态,以及可能出现的异常和错误。日志有不同的级别,例如DEBUG、INFO、WARN、ERROR等,表示不同的重要性和紧急程度。一般来说,越高级别的日志越有利于定位故障,但也会占用更多的存储空间和性能开销。因此,在设计和开发软件时,我们需要合理地设置日志级别和输出方式,以达到平衡。

      什么样的日志是好的日志呢?好的日志应该具备以下特点:

      • 完整:日志应该包含足够多的信息,以便重现和分析故障。例如,日志应该记录下故障发生的时间、地点、环境、输入、输出、调用栈等。
      • 清晰:日志应该使用易于理解和阅读的格式和语言,以便快速定位关键信息。例如,日志应该使用统一的时间格式、编码方式、分隔符等,并且避免使用过于简略或模糊的缩写和术语。
      • 有用:日志应该提供有助于诊断故障的信息,而不是无关或冗余的信息。例如,日志应该记录下异常或错误的类型、代码、消息等,并且避免输出过多无用或重复的信息。

      下面是一个好的日志示例:

      [2021-07-23 15:50:36.123] [INFO] [main] Starting application...
      [2021-07-23 15:50:37.456] [DEBUG] [main] Loading configuration from config.json
      [2021-07-23 15:50:38.789] [INFO] [main] Connecting to database at localhost:3306
      [2021-07-23 15:50:39.012] [ERROR] [main] Failed to connect to database: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
      [2021-07-23 15:50:39.012] [ERROR] [main] Exiting application with code -1 ```
      
      
    • 硬件信息:硬件信息是指软件运行时所依赖或影响的硬件设备和资源的状态和参数。硬件信息可以帮助我们了解软件在故障发生时所处的物理环境,以及可能存在的硬件故障或不兼容问题。硬件信息包括:

      • CPU:CPU是中央处理器,是软件执行的核心。CPU的信息包括型号、频率、核心数、缓存大小、负载、温度等。CPU的信息对于定位性能问题等非常有效。Linux系统中常用lscpu获取CPU使用信息的命令。
      • 内存:内存是随机存取存储器,是软件运行时的临时存储空间。内存的信息包括总量、可用量、使用量、交换量、速度、延迟等。内存信息对于定位OOM类的问题非常重要。Linux系统中使用freevmstattop等命令获取内存信息。
      • 磁盘:磁盘是永久存储器,是软件安装和保存数据的地方。磁盘的信息包括类型(例如SSD或HDD)、容量、可用空间、使用空间、读写速度、碎片率等。如果你想查看或管理磁盘分区或文件系统,你可以使用fdiskpartedmkfs等命令。如果你想查看或管理磁盘空间或使用情况,你可以使用dfduncdu等命令。如果你想测试或优化磁盘性能,你可以使用hdparmddfio等命令。
      • 网络:网络是连接不同设备和资源的通道,是软件进行数据传输和通信的方式。网络的信息包括类型(例如有线或无线)、协议(例如TCP或UDP)、地址(例如IP或MAC)、端口、带宽、延迟、丢包率等。网络问题可用的手段或者命令有tcpdumpwiresharktraceroutenetstatpingifconfig
      • 外设:外设是指连接到计算机的其他硬件设备,例如键盘、鼠标、显示器、打印机等。外设的信息包括型号、驱动程序、状态、设置等。设计到外设的软件问题通常需要确认外设是否正常,涉及到的命令有lsusblspcilsscsi

    分析方法

    当我们收集到足够的素材后,我们就可以开始分析故障发生的场景了。场景的分析方法是指在不同的情况下,采用不同的技巧和工具,来定位故障的位置和原因。常用的场景分析方法有:

    • 单步调试:单步调试是指使用调试器或其他工具,逐行执行软件代码,并观察变量的值和程序的状态。单步调试可以帮助我们跟踪程序的执行流程,发现逻辑错误或异常情况。单步调试适用于故障发生在开发环境或测试环境中,且可以重现的情况。例如,我们可以使用gdb命令行调试器或者IDE集成开发环境来进行单步调试。在单步调试中,我们可以使用断点来暂停程序的执行,并检查关键信息,如变量值、函数返回值、内存地址等。我们还可以使用单步执行、继续执行、跳过函数等命令来控制程序的执行流程。
    • 增加日志打点:增加日志打点是指在代码中添加更多的日志输出语句,以便记录更多的信息。增加日志打点可以帮助我们了解程序在故障发生前后的行为和状态,以及可能出现的异常和错误。增加日志打点适用于故障发生在生产环境中,且不容易重现或调试的情况。例如,我们可以在代码中使用printf、syslog、log4j等函数或库来输出日志信息。我们应该在一些关键的地方增加日志打点,如程序入口、出口、接口处、异常处理处等。这样可以帮助我们快速定界故障发生在哪个模块或功能中。
    • 二分法:二分法是指将问题的范围不断缩小,直到找到故障的位置和原因。二分法可以帮助我们快速排除无关或正常的部分,缩小搜索空间,提高效率。二分法适用于故障发生在任何环境中,且可以划分为多个子问题或模块的情况。例如,我们可以根据软件的结构或功能,将软件划分为多个模块或子系统,并测试每个模块或子系统是否正常工作。如果某个模块或子系统出现了问题,我们就可以继续划分它,并测试它的子模块或组件。这样就可以逐渐缩小问题的范围,直到找到具体的故障点。另外,我们也可以使用二分法来进行版本之间的比较,如果我们知道某个版本是正常的,而某个版本是有问题的,我们就可以找到这两个版本之间变化的部分,并测试它们是否导致了故障。

    定位案例

    下面是一个经典的定位案例:

    假设我们的软件是一个计算器应用程序,用户可以输入数学表达式,并得到结果。有一天,我们发现有些用户反馈说,他们在输入某些表达式时得到了错误的结果。例如,当他们输入sqrt(3x-1)+(1+x)^2时,得到了6.164414002968976而不是正确答案9.0(假设x=1)。我们怎么定位这个故障呢?

    首先,我们可以尝试重现这个故障,在自己的开发环境或测试环境中运行软件,并输入相同的表达式。如果我们也得到了错误的结果,那么说明这个故障是可重现且与环境无关的,我们就可以使用单步调试的方法来定位故障。

    接下来,我们可以使用调试器或其他工具,逐行执行软件代码,并观察变量的值和程序的状态。我们可以发现,软件的代码大致分为三个部分:

    • 解析:将用户输入的表达式转换为一个抽象语法树(AST),表示表达式的结构和语义。例如,sqrt(3x-1)+(1+x)^2的AST如下:
      image.png
    • 求值:根据AST和变量的值,计算表达式的结果。例如,sqrt(3x-1)+(1+x)^2的结果为sqrt(2)+(2)^2=9.0(假设x=1)
    • 输出:将计算结果转换为字符串,并显示给用户。例如,9.0。

    我们可以逐步检查每个部分是否正常工作,发现问题出在求值部分。当我们执行到求值部分时,我们发现AST的结构是正确的,但是变量的值是错误的。我们发现x的值不是1,而是0.9999999999999999。这是因为在计算机中,浮点数是有精度限制的,不能精确地表示某些数值。当我们将x的值赋给一个double类型的变量时,就会出现这种误差。

    由于这种误差的存在,当我们计算sqrt(3x-1)时,就会得到一个错误的结果。因为sqrt(3*0.9999999999999999-1)不等于sqrt(2),而是等于1.414213562373095。这个结果与正确答案相差了0.000000000000001。当我们将这个结果与(1+x)^2相加时,就会得到一个错误的结果。因为1.414213562373095+(1+0.9999999999999999)^2不等于9.0,而是等于6.164414002968976

    通过这样的单步调试,我们就可以找到故障的位置和原因了。在这个例子中,问题是由于浮点数精度误差导致的。

    总结

    本节介绍了症状收集与分析的概念和方法。症状收集与分析是软件诊断学中非常重要的一环,它可以帮助我们确定故障的原因和解决方案。在进行症状收集与分析时,我们需要注意以下几点:

    尽可能多地收集相关的素材,例如日志、硬件信息等。
    根据不同的场景,采用不同的分析方法,例如单步调试、增加日志打点、二分法等。
    学习并借鉴经典的定位案例,提高自己的诊断能力。

    软件诊断学 - 简书 (jianshu.com), 欢迎关注!

    相关文章

      网友评论

          本文标题:软件诊断-症状收集与分析

          本文链接:https://www.haomeiwen.com/subject/whbvydtx.html