ayfalcon 发表于 2024-5-6 10:00

XC8编译器调用函数后局域变量值被改变

最近发现个问题,有个函数里边调用别的函数后老出错,查找程序没有问题,经过仿真后发现在调用一个子函数后有几个局部变量值会发生改变,再分析原因,发现本函数的局部变量和子函数的局部变量有地址重合的,子函数中对局部变量进行了操作,返回后相应的局部变量值发生了改变,所以出错,我现在把函数的所有局部变量全部设置为了静态变量,但是这只能是个权益之计,而且这样解决不知道会不会造成别的问题,正常来说C编译器应该能够避免这种现象的发生,我怀疑是编译器设置有问题了,但是找不到地方,有哪位大神能给帮帮忙呗。

lb1057907736 发表于 2024-5-6 10:26

制作一个能复现问题的例子工程发上来,大家帮你看看。你想解决问题,即使你找美国原厂的技术支持,也要求你这么做。我可以肯定是你程序的问题。

ayfalcon 发表于 2024-5-6 10:38

lb1057907736 发表于 2024-5-6 10:26
制作一个能复现问题的例子工程发上来,大家帮你看看。你想解决问题,即使你找美国原厂的技术支持,也要求你 ...

我这个程序很大,就在这个工程上发现了这个问题,别的从来没有问题过,要是能从别的工程上复现,那么寻找共性就能发现问题了。我可以把这两个函数给您发过去,这个工程发给您也没有问题。您给分析分析,但是有点大。

lb1057907736 发表于 2024-5-6 10:59

先问一下,你所使用的环境,具体芯片型号,编译器版本,X IDE版本。你有没有对编译器进行过设置,一般默认设置就够用了。

lb1057907736 发表于 2024-5-6 11:17

请制作一个能复现问题的最小例程的工程,说不定你在制作的过程中就能发现问题了。做减法逐步缩小范围,我们调试新程序,不都是这样做的。

ayfalcon 发表于 2024-5-6 12:02

lb1057907736 发表于 2024-5-6 10:59
先问一下,你所使用的环境,具体芯片型号,编译器版本,X IDE版本。你有没有对编译器进行过设置,一般默认 ...

XIDE v5.40,XC8 2.36.芯片是PIC18F67K22,编译器设置过,但是恢复默认值后还是一个样。我电脑里有XC8 2.1版本和2.36两个版本,试了一下都一样,所以我感觉和编译器版本没有关系,应该就是程序的问题,但是程序一切都正常,原来也没有问题,就是最近程序修改了出现这个问题了,但是修改的地方和这个函数没有关系!!

lb1057907736 发表于 2024-5-6 12:34

ayfalcon 发表于 2024-5-6 12:02
XIDE v5.40,XC8 2.36.芯片是PIC18F67K22,编译器设置过,但是恢复默认值后还是一个样。我电脑里有XC8 2.1 ...

很明确了,程序修改后出问题了。修改后的你又找不出问题,开始怀疑编译器问题。你要学会调试程序。重新建一个工程,把无关的模块去掉,最小化排查范围,一定要复现出问题。说了很多次了,请接受建议!

ayfalcon 发表于 2024-5-6 13:28

lb1057907736 发表于 2024-5-6 12:34
很明确了,程序修改后出问题了。修改后的你又找不出问题,开始怀疑编译器问题。你要学会调试程序。重新建 ...

谢谢!!!我从头再试试把!!关键是现在程序挺大了!从头试太麻烦。

qintian0303 发表于 2024-5-6 14:54

只能设置断点看了,不知道是什么编译器或者开发环境,现在应该都可以看Flash的值,一般有溢出才可能出现这个问题

ayfalcon 发表于 2024-5-6 15:59

qintian0303 发表于 2024-5-6 14:54
只能设置断点看了,不知道是什么编译器或者开发环境,现在应该都可以看Flash的值,一般有溢出才可能出现这 ...

设置断点看过了,就是被调用的函数局域变量地址与母函数局域变量地址重了!!所以局域变量值在调用函数之后就被改变,而此变量在调用之后还要使用,所以出错了。

cxz_00 发表于 2024-5-6 17:29

ayfalcon 发表于 2024-5-6 15:59
设置断点看过了,就是被调用的函数局域变量地址与母函数局域变量地址重了!!所以局域变量值在调用函数之 ...

感觉像是堆栈不够用了

cxz_00 发表于 2024-5-6 17:31

ayfalcon 发表于 2024-5-6 15:59
设置断点看过了,就是被调用的函数局域变量地址与母函数局域变量地址重了!!所以局域变量值在调用函数之 ...

你这里有没有递归调用?

lb1057907736 发表于 2024-5-6 18:20

没看到例程,只能瞎猜……

lb1057907736 发表于 2024-5-6 18:23

xc8不允许递归调用,会报错,编译不通过

lb1057907736 发表于 2024-5-6 18:25

PIC18有31级深度的硬件堆栈,如果你在函数内部定义一个局部数组,元素个数超过了硬件堆栈深度,也会报错

kingTek 发表于 2024-5-8 18:43

极大概率是切bank所导致的问题,我们经历过类似情况,函数原来是好的,中间加了一个函数后就乱套了,就是因为增加的函数把原来的bank号中断打乱了,而且又没恢复,故而错误,我本人早就料到pic会发生此类bug,所以很快就用汇编解决了问题!

kingTek 发表于 2024-5-8 18:45

就是用的xc8编译器,18f芯片

lb1057907736 发表于 2024-5-8 20:53

制作一个能复现故障的最小例程,提供给mchp,狠狠打脸。其实他们内心是高兴的,提供了一个测试用例,用于他们对编译器的回归测试。XC8的前身是PICC编译器,被他们收购了。很稳定了,这种错误,我没遇到过。关于bank切换的问题,不是只写汇编才会关心嘛,写C不需要,编译器帮你搞定了。

ayfalcon 发表于 2024-5-8 22:23

cxz_00 发表于 2024-5-6 17:31
你这里有没有递归调用?

没有

ayfalcon 发表于 2024-5-8 22:24

lb1057907736 发表于 2024-5-6 18:25
PIC18有31级深度的硬件堆栈,如果你在函数内部定义一个局部数组,元素个数超过了硬件堆栈深度,也会报错 ...

我这边不是报错,就是函数局部变量和他调用的子函数的局部变量地址重了。
页: [1] 2
查看完整版本: XC8编译器调用函数后局域变量值被改变