C++(Qt)软件调试—bug排查记录(36)


文章目录

  • C++(Qt)软件调试---bug排查记录(36)
    • @[toc]
    • 1 无返回值函数风险
    • 2 空指针调用隐患
    • 3 Debug/Release差异
    • 4 ARM架构char符号问题
    • 5 linux下找不到动态库

更多精彩内容
👉内容导航 👈
👉C++软件调试 👈

1 无返回值函数风险

  • 如果一个函数的返回值为void,则编译器会自动插入一个默认return;

  • 如果非void的函数没有写return,有些版本的编译器会默认插入一个ret(例如gcc7.3,高版本gcc会插入ud2),不过这个代码还是不安全的。

  • 如果一个函数的返回值不为void,但是忘记写return语句了,会破坏栈帧的出栈,导致未定义异常,可能会软件崩溃,也可能不会崩溃,调用者会试图从栈上的某个位置读取返回值。由于这个位置没有被正确设置,读取的内容将是随机的数据,这可能导致程序继续运行但行为异常;

  • Release版本与Debug版本的差异:在Debug版本中,由于内存受到保护,即使函数没有return语句,也可能不会立即导致程序崩溃。但在Release版本中,由于所有保护都被移除,访问错误内存或寄存器值很可能导致程序异常退出或崩溃。

  • 使用基本数据类型有可能不会导致程序崩溃。

  • 例如:

int fun1()
{int a = 123;
}
QByteArray fun2()
{QByteArray arr("123");
}
int main()
{fun1();fun2();return 0;
}
  • 并且这种情况导致的程序崩溃使用调试工具很难定位,定位的位置非常随机。

  • 不过要视编译器而定,有些编译器会编译报错,例如MSVC,有些不会,例如gcc默认只是会报警告-Wreturn-type

  • gcc可以通过-Werror=return-type选项将警告设置为错误信息,防止忽略;gcc编译选项

  • 或者使用MSVC编译器编译程序,也可以检测出未写return的错误。

  • QMake可以通过下面配置将缺失返回值警告设置为错误。

    QMAKE_CC += -Werror=return-type
    QMAKE_CXX += -Werror=return-type
    
  • 如下图所示,如果非void返回值函数没有写return语句,则在函数汇编中缺失popret指令;

    • pop 通常用于恢复先前保存的寄存器值(如 ebp 或者 rbp 在 x86 架构上),或者弹出参数等。如果没有执行 pop 操作,那么这些值将不会被正确地恢复,这可能会导致后续函数调用或程序逻辑出现问题。
    • 当函数调用发生时,返回地址会被压入栈中。如果函数结束时没有使用 ret 来处理这个返回地址,栈指针将指向错误的位置,破坏栈的结构,影响后续的函数调用和返回操作。
    • 缺少正确的 popret 指令使得调试更加复杂,因为正常的调用堆栈信息不再可靠。

在这里插入图片描述


2 空指针调用隐患

  • 当一个对象为空指针或者野指针时如果调用成员函数,可能会出现未定义异常导致崩溃,也可能不会崩溃;
  • 如果调用的成员函数没有使用this指针写入数据,则不会导致崩溃;
    • 情况1:没有使用到任何成员变量;
    • 情况2:调用的是static成员函数;
    • 情况3:只是读取成员变量,没有写入成员变量。
  • 这种不崩溃是危险的
    • 不可预测性:行为依赖于编译器、平台和运行时状态
    • 隐蔽性:错误可能在生产环境中突然出现
    • 调试困难:问题表现不稳定,难以复现
#include <iostream>
using namespace std;
class A {
public :void f(int x) {int a = x;// m_a = 123;   // 崩溃for(int i = 0; i < x; i++){cout << i << endl;}cout << a <<" " << &m_a <<" "<<this << endl;}
private:int m_a;
};int main() {A* a ;a -> f(10);a->f(2);return 0;
}

3 Debug/Release差异

Debug模式下通常会有更多的内存保护机制,这有助于捕获潜在的内存错误。

这些保护机制在Release模式下可能被禁用或简化,从而导致某些问题在Debug模式下不明显但在Release模式下暴露出来。具体来说:

  • 内存初始化

    • Debug模式下,编译器可能会自动将未初始化的变量设置为特定值(如0或特殊标记值),以帮助检测未初始化变量的使用。
    • Release模式下,未初始化的变量保持未初始化状态,可能导致不可预测的行为。
  • 边界检查

    • Debug模式下,可能会启用额外的数组和指针边界检查,防止越界访问。
    • Release模式下,这些检查通常被移除以提高性能,因此越界访问可能导致崩溃或未定义行为。
  • 堆栈保护

    • Debug模式下,堆栈可能会有更多的保护措施,例如填充“安全”值来检测堆栈溢出。
    • Release模式下,这些保护措施可能被移除或简化。
  • 调试信息

    • Debug模式下,程序会包含更多的调试信息和符号表,便于调试工具(如GDB、Visual Studio Debugger)进行更详细的分析。
    • Release模式下,这些调试信息通常被移除,导致难以通过调试工具捕捉到问题。

解决方法

  1. 使用静态分析工具

    • 使用静态分析工具(如Clang Static Analyzer、Cppcheck)来检测代码中的潜在问题。
  2. 启用运行时检查

    • 在Release模式下启用运行时检查工具,如AddressSanitizer、Valgrind等,可以帮助检测内存错误。
  3. 确保一致的初始化

    • 确保所有变量在使用前都已正确初始化,避免依赖Debug模式下的默认初始化行为。
  4. 检查内存分配和释放

    • 检查动态内存分配和释放是否正确,确保没有内存泄漏或双重释放的问题。
  5. 审查多线程代码

    • 如果程序涉及多线程,确保线程同步机制正确无误,避免竞争条件和死锁。
  6. 对比宏定义

    • 检查Debug和Release模式下的宏定义差异,确保两种模式下的行为一致,特别是与内存管理相关的宏定义。

4 ARM架构char符号问题

  • 在vs编译器、x86架构linux中的gcc编译器ux中的gcc编译器都是把char定义为signed char;

  • arm-linux-gcc把char定义为unsigned char;

  • 所以直接使用char有移植性问题,例如在x86架构中开发的程序,在arm架构系统(例如国产银河麒麟、树莓派、Android等)中可能就会出现问题,并且这种情况很隐蔽,比较难排查;

  • 例如在cppreference中的定义:

    在这里插入图片描述

  • 解决办法:

    1. 在编译时加上选项-fsigned-char
    2. 不使用char,改成使用int8_t或者qint8;

5 linux下找不到动态库

  1. 使用ldd命令查看可执行程序或者动态库的链接路径,是否找得到动态库;

  2. 使用下面命令查看、修改动态库链接路径

    patchelf --set-rpath '$ORIGIN/lib/' ./RadarServer     # 设置程序动态库链接路径
    patchelf --print-rpath ./RadarServer   # 打印链接路径
    


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

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

相关文章

人工智能领域、图欧科技、IMYAI智能助手2025年8月更新月报

IMYAI 平台 2025 年 8 月功能更新与模型上新汇总 2025年08月31日 功能更新&#xff1a; 对话与绘画板块现已支持多文件批量上传。用户可通过点击或拖拽方式一次性上传多个图片或文件&#xff0c;操作更加便捷。2025年08月25日近期更新亮点&#xff1a; 文档导出功能增强&#x…

2025独立站技术风向:无头电商+PWA架构实战指南

根据 Gitnux 的统计数据&#xff0c;预计到 2025 年&#xff0c;北美将有 60% 的大型零售商采用无头平台。而仍在传统架构上运营的独立站&#xff0c;平均页面加载速度落后1.8秒&#xff0c;转化率低32%。无独有偶&#xff0c;Magento Association 的一项调查显示&#xff0c;7…

淘宝京东拼多多爬虫实战:反爬对抗、避坑技巧与数据安全要点

一、先搞懂&#xff1a;电商爬虫的 3 大核心挑战&#xff08;比普通爬虫更复杂的原因&#xff09; 做电商爬虫前&#xff0c;必须先明确「为什么难」—— 淘宝、京东、拼多多的反爬体系是「多层级、动态化、行为导向」的&#xff0c;绝非简单的 UA 验证或 IP 封禁&#xff1a;…

【1】MOS管的结构及其工作原理

以nmos举例&#xff0c;mos管由三个电极&#xff1a;G极&#xff08;gate&#xff09;、D极&#xff08;drain&#xff09;、S极&#xff08;source&#xff09;和一个衬底组成&#xff0c;而这三个电极之间通过绝缘层相隔开&#xff1b;①既然GDS三个电极之间两两相互绝缘&…

如何保存训练的最优模型和使用最优模型文件

一 保存最优模型主要就是我们在for循环中加上一个test测试&#xff0c;并且我还在test函数后面加上了返回值&#xff0c;可以返回准确率&#xff0c;然后每次进行一次对比&#xff0c;然后取大的。然后这里有两种保存方式&#xff0c;一种是保存了整个模型&#xff0c;另一个是…

vue3+ts+echarts多Y轴折线图

因为放在了子组件才监听&#xff0c;加载渲染调用&#xff0c;有暗黑模式才调用&#xff0c;<!-- 温湿度传感器 --><el-row v-if"deviceTypeId 2"><el-col :xs"24" :sm"24" :md"24" :lg"24" :xl"24&qu…

基于Taro4打造的一款最新版微信小程序、H5的多端开发简单模板

基于Taro4、Vue3、TypeScript、Webpack5打造的一款最新版微信小程序、H5的多端开发简单模板 特色 &#x1f6e0;️ Taro4, Vue 3, Webpack5, pnpm10 &#x1f4aa; TypeScript 全新类型系统支持 &#x1f34d; 使用 Pinia 的状态管理 &#x1f3a8; Tailwindcss4 - 目前最流…

ITU-R P.372 无线电噪声预测库调用方法

代码功能概述&#xff08;ITURNoise.c&#xff09;该代码是一个 ITU-R P.372 无线电噪声预测 的计算程序&#xff0c;能够基于 月份、时间、频率、地理位置、人为噪声水平 计算特定地点的 大气噪声、银河噪声、人为噪声及其总和&#xff0c;并以 CSV 或标准输出 方式提供结果。…

《从报错到运行:STM32G4 工程在 Keil 中的头文件配置与调试实战》

《从报错到运行&#xff1a;STM32G4 工程在 Keil 中的头文件配置与调试实战》文章提纲一、引言• 阐述 STM32G4 在嵌入式领域的应用价值&#xff0c;说明 Keil 是开发 STM32G4 工程的常用工具• 指出头文件配置是 STM32G4 工程在 Keil 中开发的关键基础环节&#xff0c;且…

Spring 事务提交成功后执行额外逻辑

1. 场景与要解决的问题在业务代码里&#xff0c;常见诉求是&#xff1a;只有当数据库事务真正提交成功后&#xff0c;才去执行某些“后置动作”&#xff0c;例如&#xff1a;发送 MQ、推送消息、写审计/埋点日志、刷新缓存、通知外部系统等。如果这些动作在事务提交前就执行&am…

Clickhouse MCP@Mac+Cherry Studio部署与调试

一、需求背景 已经部署测试了Mysql、Drois的MCP Server,想进一步测试Clickhouse MCP的表现。 二、环境 1)操作系统 MacOS+Apple芯片 2)Clickhouse v25.7.6.21-stable、Clickhouse MCP 0.1.11 3)工具Cherry Studio 1.5.7、Docker Desktop 4.43.2(199162) 4)Python 3.1…

Java Serializable 接口:明明就一个空的接口嘛

对于 Java 的序列化,我之前一直停留在最浅层次的认知上——把那个要序列化的类实现 Serializbale 接口就可以了嘛。 我似乎不愿意做更深入的研究,因为会用就行了嘛。 但随着时间的推移,见到 Serializbale 的次数越来越多,我便对它产生了浓厚的兴趣。是时候花点时间研究研…

野火STM32Modbus主机读取寄存器/线圈失败(三)-尝试将存贮事件的地方改成数组(非必要解决方案)(附源码)

背景 尽管crc校验正确了&#xff0c;也成功发送了EV_MASTER_EXECUTE事件&#xff0c;但是eMBMasterPoll( void )中总是接收的事件是EV_MASTER_FRAME_RECEIVED或者EV_MASTER_FRAME_SENT&#xff0c;一次都没有执行EV_MASTER_EXECUTE。EV_MASTER_EXECUTE事件被别的事件给覆盖了&…

微信小程序校园助手程序(源码+文档)

源码题目&#xff1a;微信小程序校园助手程序&#xff08;源码文档&#xff09;☑️ 文末联系获取&#xff08;含源码、技术文档&#xff09;博主简介&#xff1a;10年高级软件工程师、JAVA技术指导员、Python讲师、文章撰写修改专家、Springboot高级&#xff0c;欢迎高校老师、…

59-python中的类和对象、构造方法

1. 认识一下对象 世间万物皆是"对象" student_1{ "姓名":"小朴", "爱好":"唱、跳、主持" ......... }白纸填写太落伍了 设计表格填写先进一些些 终极目标是程序使用对象去组织数据程序中设计表格&#xff0c;我们称为 设计类…

向成电子惊艳亮相2025物联网展,携工控主板等系列产品引领智造新风向

2025年8月27-29日&#xff0c;IOTE 2025 第二十四届国际物联网展深圳站在深圳国际会展中心&#xff08;宝安&#xff09;盛大启幕&#xff01;作为全球规模领先的物联网盛会之一&#xff0c;本届展会以“生态智能&#xff0c;物联全球”为核心&#xff0c;汇聚超1000家全球头部…

阵列信号处理之均匀面阵波束合成方向图的绘制与特点解读

阵列信号处理之均匀面阵波束合成方向图的绘制与特点解读 文章目录前言一、方向图函数二、方向图绘制三、副瓣电平四、阵元个数对主瓣宽度的影响五、阵元间距对主瓣宽度的影响六、MATLAB源代码总结前言 \;\;\;\;\;均匀面阵&#xff08;Uniform Planar Array&#xff0c;UPA&…

算法在前端框架中的集成

引言 算法是前端开发中提升性能和用户体验的重要工具。随着 Web 应用复杂性的增加&#xff0c;现代前端框架如 React、Vue 和 Angular 提供了强大的工具集&#xff0c;使得将算法与框架特性&#xff08;如状态管理、虚拟 DOM 和组件化&#xff09;无缝集成成为可能。从排序算法…

网络爬虫是自动从互联网上采集数据的程序

网络爬虫是自动从互联网上采集数据的程序网络爬虫是自动从互联网上采集数据的程序&#xff0c;Python凭借其丰富的库生态系统和简洁语法&#xff0c;成为了爬虫开发的首选语言。本文将全面介绍如何使用Python构建高效、合规的网络爬虫。一、爬虫基础与工作原理 网络爬虫本质上是…

Qt Model/View/Delegate 架构详解

Qt Model/View/Delegate 架构详解 Qt的Model/View/Delegate架构是Qt框架中一个重要的设计模式&#xff0c;它实现了数据存储、数据显示和数据编辑的分离。这种架构不仅提高了代码的可维护性和可重用性&#xff0c;还提供了极大的灵活性。 1. 架构概述 Model/View/Delegate架构将…