硬汉嵌入式论坛

 找回密码
 立即注册
查看: 931|回复: 9
收起左侧

[有问必答] 请教一个编译器优化等级的问题。

[复制链接]

39

主题

199

回帖

326

积分

高级会员

积分
326
发表于 2022-10-24 15:18:34 | 显示全部楼层 |阅读模式
最近办公电脑换了一台,原先电脑里的程序同步到了新电脑里。
折腾了一下开发环境,把原来的程序编译后,发现不能运行。

最后拿着老电脑(幸好还没丢),折腾了一上午,发现是两个工程的优化等级不同导致的。

老代码里是-O0,新的电脑配置默认的是-O1。
有些地方的确是自己代码写的不规范(如下图),仿真之后看出来了。比如下面的局部变量count没有赋初值,导致在优化等级0的时候,按键按下可以被识别到(可能是运气好,我-O0优化等级下,这个局部变量默认就是0)
但是-O1优化等级下,这个变量初值就不确定了,导致后面逻辑错误,无法识别到这个按键。

image.png

但是有的地方,表现的很奇怪,我仿真也无法定位到为什么出问题?
虽然只要把优化等级改回来,就能解决问题,不过我的好奇心,想知道是什么原因导致的这个现象。
特地来论坛上请教下一下各位。

芯片:GD32F103CB
某个结构体里的变量,被莫名其妙更改。
可以看下面这个动图。
gif.gif
map如下图
image.png


有没有高手知道这种情况可能的原因是什么,应该怎么排查,或者还需要我提供哪些信息。
让我学习一下,解决这种奇怪问题的思路。
回复

使用道具 举报

39

主题

199

回帖

326

积分

高级会员

积分
326
 楼主| 发表于 2022-10-24 15:34:35 | 显示全部楼层
drv_keyboard_cb是用malloc分配的。
image.png
回复

使用道具 举报

39

主题

199

回帖

326

积分

高级会员

积分
326
 楼主| 发表于 2022-10-24 16:38:18 | 显示全部楼层
解决问题了,是我自己程序,写的不规范。
我用控制变量法,把工程注释掉,一点点增加,最后找到了更改的地方。

我之前写了一个可变参的函数,用于驱动段码屏..
N)5XBDNI[D%@GRZJFQ25LW3.jpg
结果我自己用的时候没加0XFF。
在-O0优化等级的时候居然没出问题...在-O1优化等级的时候就出现了莫名其妙的问题,就是这个函数导致了别的地方的内存被修改了..
S)FX[98ENEGFEKZDQ4N1P~J.jpg

这样的代码,-O0居然不会有问题!!!导致我一直都没发现改正。
回复

使用道具 举报

10

主题

90

回帖

120

积分

初级会员

积分
120
发表于 2022-10-24 17:41:43 | 显示全部楼层
首先,先表明我的态度,我目前所有项目,所有的芯片。任何核心,任何编译器,都是直接干到最大优化等级。那么,如何保持这样的代码呢,很简单,从刚开始就要这样,保持良好的代码习惯和风格。
至于你的问题,说实话,要从整个项目角度看待。比如变量,使用前先初始化(严格来说,是读取前,要先存在写入过),这个习惯很重要,不要把变量的初始化值交给MCU。因为,你永远都不知道上电和优化会带来什么初始化值。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2022-10-25 10:33:32 | 显示全部楼层
mrjiu 发表于 2022-10-24 17:41
首先,先表明我的态度,我目前所有项目,所有的芯片。任何核心,任何编译器,都是直接干到最大优化等级。那 ...

最近一个问题是0级优化搞出来的,防不胜防

细节问题,MDK AC6的0级优化对局部变量的操作全部LDR+SP相对地址和STR+SP相对地址操作玩法
https://www.armbbs.cn/forum.php?mod=viewthread&tid=116103
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2022-10-25 10:33:43 | 显示全部楼层
会飞的猪_2020 发表于 2022-10-24 16:38
解决问题了,是我自己程序,写的不规范。
我用控制变量法,把工程注释掉,一点点增加,最后找到了更改的地方 ...

谢谢楼主告知最终问题原因
回复

使用道具 举报

39

主题

199

回帖

326

积分

高级会员

积分
326
 楼主| 发表于 2022-10-25 14:28:05 | 显示全部楼层
原先的代码,写的不规范的地方很多啊。
我把优化等级给调高了之后,莫名其妙的问题层出不穷,还好最近这个项目因为采购等原因停期了。
不然我估计直接调到-O0先应付着,估计也没时间去一点点看。
后续又出了一个问题,某个函数跳转之后地址会改动,具体问题复现看下面的动图。
gif.gif

后来也是用控制变量法,发现是sprintf的buf给的小了,sprintf会最后补0,所以4个字节应该给5个字节的buf。
gif1.gif

不过我没学习过汇编,我看不太明白这个问题细节的过程,到底sprintf改了什么东西,导致了这么奇怪的现象。
如果我能看懂汇编代码的话,可能调试起来会方便一点,不知道硬汉哥有没有打算出一些讲解汇编的教程啊。
我之前也搜索过网络上的教程,不过感觉都是X86的,ARM相关的好像很少。



回复

使用道具 举报

210

主题

1044

回帖

1684

积分

至尊会员

More we do, more we can do.

积分
1684
发表于 2022-10-25 18:11:29 | 显示全部楼层
本帖最后由 emwin 于 2022-10-25 18:13 编辑

就楼主遇到的定位变量被未知代码修改,分享个定位问题的方法:设置变量写断点,这样就可以定位到代码。
image.png
回复

使用道具 举报

39

主题

199

回帖

326

积分

高级会员

积分
326
 楼主| 发表于 2022-10-25 19:54:33 | 显示全部楼层
emwin 发表于 2022-10-25 18:11
就楼主遇到的定位变量被未知代码修改,分享个定位问题的方法:设置变量写断点,这样就可以定位到代码。

这个断点能设置结构体里的某个成员变量吗,比如drv_keyboard_cb->data[2].state。
我一开始也想到用这个办法去调试,但是我试了一下,变量断电define报错,不知道怎么设置。
回复

使用道具 举报

39

主题

199

回帖

326

积分

高级会员

积分
326
 楼主| 发表于 2022-10-26 10:00:20 | 显示全部楼层
遇到了第三个问题,Eventrecorder的代码,SysTick_Handler和原工程冲突,之前我做过改动。
后来更换电脑后,重新安装MDK,这部分代码又变回原来的,编译倒是美出问题, 但是运行不正常。
仿真一下,发现原来是这部分代码被改回来了。

这个问题还是比较明显的,好改动,之后还是把代码从RTE嵌入到工程里,不然换电脑的话,全变了...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-9 18:28 , Processed in 0.299212 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表