Debug模式和Release模式有什么区别?

2023-05-16

已剪辑自: https://mp.weixin.qq.com/s/4iiB48m30p4-egKBD3QY3A

张爱玲曾说过:“开发过程就是个玄学。”

有时候,程序在Debug模式下运行的好好的,一Release就crash了。

有时候,程序在Debug模式下崩溃了,Release模式下居然能正常运行。

以上这种情况,可能很多人都遇到过。

用C/C++的朋友都知道编译器编译有各种优化级别,编译器优化级别大体如下:
O0(默认选项):不开启优化,方便功能调试Og:方便调试的优化选项(比O1更保守)O1:保守的优化选项,打开了四十多个优化选项O2:常用的发布优化选项,在O1的基础上额外打开了四十多个优化选项,包括自动内联等规则Os:产生较小代码体积的优化选项(比O2更保守)O3:较为激进的优化选项(对错误编码容忍度最低),在O2的基础上额外打开了十多个优化选项

Ofast:打开可导致不符合IEEE浮点数等标准的性能优化选项。

具体介绍如下:

O0:编译器默认就是O0,该选项下不会开启优化,方便开发者调试。O1:致力于在不需要过多的编译时间情况下,尽量减少代码大小和尽量提高程序运行速度,它开启了下面的优化标志:

-fauto-inc-dec

-fbranch-count-reg

-fcombine-stack-adjustments

-fcompare-elim

-fcprop-registers

-fdce -fdefer-pop

-fdelayed-branch

-fdse

-fforward-propagate

-fguess-branch-probability

-fif-conversion

-fif-conversion2

-finline-functions-called-once

-fipa-modref

-fipa-profile

-fipa-pure-const

-fipa-reference

-fipa-reference-addressable

-fmerge-constants

-fmove-loop-invariants

-fomit-frame-pointer

-freorder-blocks

-fshrink-wrap

-fshrink-wrap-separate

-fsplit-wide-types

-fssa-backprop

-fssa-phiopt

-ftree-bit-ccp

-ftree-ccp

-ftree-ch

-ftree-coalesce-vars

-ftree-copy-prop

-ftree-dce

-ftree-dominator-opts

-ftree-dse

-ftree-forwprop

-ftree-fre

-ftree-phiprop

-ftree-pta

-ftree-scev-cprop

-ftree-sink

-ftree-slsr

-ftree-sra

-ftree-ter

-funit-at-a-time

Og:如果是为了调试,该选项是比O0更好的选择,它会打开O1大部分优化标志,但是不会启用那些影响调试的标志:

-fbranch-count-reg

-fdelayed-branch

-fdse

-fif-conversion

-fif-conversion2

-finline-functions-called-once

-fmove-loop-invariants

-fssa-phiopt

-ftree-bit-ccp

-ftree-dse

-ftree-pta

-ftree-sra

O2:常见的Release级别,该选项下几乎执行了所有支持的优化选项,它增加了编译时间,提高了程序的运行速度,又额外打开了以下优化标志:

-falign-functions

-falign-jumps

-falign-labels

-falign-loops

-fcaller-saves

-fcode-hoisting

-fcrossjumping

-fcse-follow-jumps

-fcse-skip-blocks

-fdelete-null-pointer-checks

-fdevirtualize

-fdevirtualize-speculatively

-fexpensive-optimizations

-ffinite-loops

-fgcse

-fgcse-lm

-fhoist-adjacent-loads

-finline-functions

-finline-small-functions

-findirect-inlining

-fipa-bit-cp

-fipa-cp

-fipa-icf

-fipa-ra

-fipa-sra

-fipa-vrp

-fisolate-erroneous-paths-dereference

-flra-remat

-foptimize-sibling-calls

-foptimize-strlen

-fpartial-inlining

-fpeephole2

-freorder-blocks-algorithm=stc

-freorder-blocks-and-partition

-freorder-functions

-frerun-cse-after-loop

-fschedule-insns

-fschedule-insns2 -fsched-interblock

-fsched-spec

-fstore-merging

-fstrict-aliasing

-fthread-jumps

-ftree-builtin-call-dce

-ftree-pre

-ftree-switch-conversion

-ftree-tail-merge

-ftree-vrp

Os:打开了几乎所有的O2优化标志,除了那些经常会增加代码大小的优化标志:

-falign-functions

-falign-jumps

-falign-labels

-falign-loops

-fprefetch-loop-arrays

-freorder-blocks-algorithm=stc

它还启用了-finline-functions优化标志,使编译器根据代码大小而不是程序运行速度进行优化,为了减少代码大小。

O3:在O2的基础上又打开了以下优化标志:

-fgcse-after-reload

-fipa-cp-clone

-floop-interchange

-floop-unroll-and-jam

-fpeel-loops

-fpredictive-commoning

-fsplit-loops

-fsplit-paths

-ftree-loop-distribution

-ftree-loop-vectorize

-ftree-partial-pre

-ftree-slp-vectorize

-funswitch-loops

-fvect-cost-model

-fvect-cost-model=dynamic

-fversion-loops-for-strides

Ofast:更加激进的编译选项,它不会严格遵循标准,在O3的优化基础上,它又开启了一些可能导致不符合IEEE浮点数等标准的性能优化选项,如- fast-math, -fallow-store-data-races等。

tips:上述优化选项如果想要了解具体含义可以看https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html 官方文档。编译器有这么多优化级别,Debug版本和Release版本其实就是优化级别的区别,Debug称为调试版本,编译的结果通常包含有调试信息,没有做任何优化,方便开发人员进行调试,Release称为发布版本,不会携带调试信息,同时编译器对代码进行了很多优化,使代码更小,速度更快,发布给用户使用,给用户使用以更好的体验。但Release模式编译比Debug模式花的时间也会更多。Debug模式下在内存分配上有所区别,在我们申请内存时,Debug模式会多申请一部分空间,分布在内存块的前后,用于存放调试信息。

对于未初始化的变量,Debug模式下会默认对其进行初始化,而Release模式则不会,所以就有个常见的问题,局部变量未初始化时,Debug模式和Release模式表现有所不同。

bool func() {
    bool found;
    for (int i = 0; i < vec.size(); ++i) {
        if (vec[i] == 3) {
            found = true;
        }
    }
    return found; 
}

Debug模式下可能运行正常,但Release模式下可能会返回错误结果,因为found局部变量在Release模式下没有初始化。

Debug模式以32字节为单位分配内存,例如当申请24字节内存时,Release模式下是正常的分配24字节,Debug模式会分配32字节,多了8字节,所以有些数组越界问题在Debug模式下可以安全运行,Release模式下就会出问题。

Debug模式下可以使用assert,运行过程中有异常现象会及时crash,Release模式下模式下不会编译assert,遇到不期望的情况不会及时crash,稀里糊涂继续运行,到后期可能会产生奇奇怪怪的错误,不易调试,殊不知其实在很早之前就出现了问题。编译器在Debug模式下定义_DEBUG宏,Release模式下定义NDEBUG宏,预处理器就是根据对应宏来判断是否开启assert的。

数据溢出问题,在一个函数中,存在某些从未被使用的变量,且函数内存在数据溢出问题,在Debug模式下可能不会产生问题,因为不会对该变量进行优化,它在栈空间中还是占有几个字节,但Release模式下可能会出问题,Release模式下可能会优化掉此变量,栈空间相应变小,数据溢出就会导致栈内存损坏,有可能会产生奇奇怪怪的错误。

例如:

void func() {
    char buffer[10];
    int counter;
    lstrcpy(buffer, "abcdefghik"); // 需要拷贝11字节
}

tips:不要将Debug库和Release库混合在一起,可能会出问题,至于为啥会出问题,知道的可在下方评论区留言,一般都是有两个目录,Debug目录和Release目录。

回到开篇提到的那两个问题:

程序在Debug模式下运行的好好的,Release模式下就crash了,怎么办?

可以尝试着找一找代码中的assert,看一下是否是assert导致的两种模式下的差异,从这个思路入手。

程序在Debug模式下会崩溃,Release模式下却正常运行,怎么办?

看一下代码中是否有未初始化的变量,是否有数组越界问题,从这个思路入手。

http://www.flounder.com/debug_release.htm

https://vinayakgarg.wordpress.com/2012/03/31/difference-between-debug-build-and-release-build/

https://www.xspdf.com/resolution/312312.html

https://docs.oracle.com/cd/E19205-01/820-1214/bkacs/index.html

https://www.cnblogs.com/huaping-audio/archive/2008/08/23/1274833.html

https://www.zhihu.com/question/27090458

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Debug模式和Release模式有什么区别? 的相关文章

随机推荐

  • 世界上最健康的程序员作息表!

    文章目录 7 307 30 8 008 00 8 308 30 9 009 3010 3011 0013 0014 30 15 3016 0017 00 19 0019 3021 4523 0023 30时间 健康的小常识 已剪辑自 htt
  • 30岁了,冒死说几句大实话!

    已剪辑自 https mp weixin qq com s j0yzonrhPPcemDRF6QBVkw 是的 xff0c 我 30 岁了 xff0c 还是周岁 就在这上个周末 xff0c 我度过了自己 30 岁的生日 都说三十而立 xff
  • QT使用QAxObject读取Excel教程-全网最全

    文章目录 一 背景二 介绍基本操作方法获取对象调用动态方法设置和获取属性更多相关 三 使用要求添加模块与excel com连接的方法Excel基本操作 四 具体使用说明五 项目实战实战项目1实战项目2实战项目3实战项目4实战项目5 封装好的
  • 超越内卷-认知差、信息差、时间差

    已剪辑自 https mp weixin qq com s 9pzMQJJnp9ZbkTCVe ao7w 内卷的话题曾经聊过 xff0c 当大家的努力都上不了层次 xff0c 只是原水平重复竞争 xff0c 那么内卷就开始了 最近对这个问题
  • 数十种嵌入式 C 语言代码优化的经验和方法

    文章目录 简介声明哪里需要使用这些方法 xff1f 整形数除法和取余数合并除法和取余数通过2的幂次进行除法和取余数取模的一种替代方法使用数组下标全局变量使用别名变量的生命周期分割变量类型局部变量指针指针链条件执行布尔表达式和范围检查布尔表达
  • 汽车电子国际标准现状与趋势

    已剪辑自 https mp weixin qq com s vLgnrFPtDPglwde1TZUHSQ 在汽车电子系统发展的早期 xff0c 汽车电子基础软件是没有统一标准的 xff0c 各个 OEM Tier1 Tier2 等厂商针对不
  • Linux多线程服务器编程(陈硕)学习总结

    这本书确实是学习多核时代采用现代C 43 43 编写多线程程序的好书 xff0c 下面是学习总结 xff1a 第一章 线程安全的对象生命期管理 对象的创建很简单 xff0c 但是不要在构造期间泄漏this指针 xff0c 比如不要在构造函数
  • 详解 Modbus 通信协议(清晰易懂)

    文章目录 已剪辑自 https mp weixin qq com s dvo1l1GgJ2DtIHnPK5E1tA 本文总结关于 Modbus 相关的知识 xff0c 浅显易懂 xff0c 旨在对 Modbus 有一个很直观的了解 如有错误
  • RTOS应用中的几种调度策略

    从前后台架构的软件开发过渡到使用实时操作系统 RTOS 可能是一项困难的工作 但使用RTOS有许多优势 xff0c 例如简化应用集成 xff0c 支持任务抢占调度 xff0c 当开发人员使用复杂的32位微控制器 xff0c 且可以获取足够的
  • 几款非常棒的使用文本来进行图形化注释的工具

    https mp weixin qq com s NX8feH UPE7oegM7U9W4GA 说明 xff1a 1 程序代码里面非常好的注释方式 2 相关网站 xff1a xff08 1 xff09 https metacpan org
  • 解决Excel打开UTF-8编码CSV文件乱码的问题

    最近在用QT读写CSV文件 xff0c 发现将数据写入到CSV文件中 xff0c 使用记事本打开文件是正常的 xff0c 使用Excel打开 xff0c 中文是乱码的 xff0c 下面把原因和解决方法记录一下 问题产生的原因 为什么exce
  • Windows下查看端口占用情况

    编程的时候经常发现我们需要使用的端口被别的程序占用 xff0c 这个时候需要清楚查看是哪个程序占用了端口 xff0c 用且清除了这个进程 xff01 1 开始 gt 运行 gt cmd xff0c 或者是window 43 R组合键 xff
  • 【C进阶】同事用void把我给秀翻了!

    2 简单认识一下void 今天跟大家介绍的知识是C语言中的void关键字的用法 xff0c void在大部分小伙伴的程序中都只是用于函数无参数传入 xff0c 或者无类型返回 然而我们平时所定义的变量都会有具体的类型 xff0c int x
  • 如何降低代码圈复杂度

    已剪辑自 https mp weixin qq com s biz 61 MzI2MTE4Nzk5MA 3D 3D amp mid 61 2247483685 amp idx 61 1 amp sn 61 26072d6a41ed9abef
  • 嵌入式开发:周期调度和代码执行时间理解

    已剪辑自 https mp weixin qq com s gaT7D1IgkBxxEOj DNaLPw 汽车嵌入开发中 xff0c 我们常常听到这样的名词 xff1a 1ms Task 5ms Task 10ms Task 试问 xff1
  • C语言中,实现函数宏的三种方式

    已剪辑自 https blog csdn net qq 35692077 article details 102994959 1 函数宏介绍 函数宏 xff0c 即包含多条语句的宏定义 xff0c 其通常为某一被频繁调用的功能的语句封装 x
  • 代码是如何控制硬件的?

    已剪辑自 https mp weixin qq com s UDbxTfAMLAWE8LjUiqGUBQ 先说代码 xff1a 我们是用电脑的键盘来输入的指令 xff0c 每一个指令都对应一个ASCII码 xff0c 而这里的ASCII码就
  • 使用Realsense D435相机在ROS Kinetic中跑通ORB-SLAM2

    文章中不足 xff0c 错误的地方欢迎大家批评指正 xff0c 如果哪步遇到了问题 xff0c 我尽力为你解答 皱眉 这个文章主要是想记录当时配环境的步骤 xff0c 以防以后再配忘了某步 目录 使用配置主要步骤安装基于ROS使用RealS
  • libc6-dev: 依赖: libc6 (= 2.27-3ubuntu1.3) 但是 2.31-0ubuntu9.1 正要被安装...

    libc6 dev 依赖 libc6 61 2 27 3ubuntu1 3 但是 2 31 0ubuntu9 1 正要被安装 参考链接 xff1a https blog csdn net WU2629409421perfect articl
  • Debug模式和Release模式有什么区别?

    已剪辑自 https mp weixin qq com s 4iiB48m30p4 egKBD3QY3A 张爱玲曾说过 xff1a 开发过程就是个玄学 有时候 xff0c 程序在Debug模式下运行的好好的 xff0c 一Release就c