OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4937|回复: 26

求助,特别诡异的代码bug

[复制链接]

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
发表于 2016-5-24 13:52:35 | 显示全部楼层 |阅读模式
10金钱
昨天写了些代码,定义了全局变量a
u8 a = 0x00;
if(a)
{
fuction1();
}
结果fuction1能执行到,但是达到不了我的函数目的,哪怕是只让1+1=2都不行。
经过尝试,改了一下
u8 a;
a = 0x00;
if(a)
{
fuction1();
}
就好使了。这怎么可能。。。我以前都按第一个用也没出过问题啊。

今天更逗,又写了另一个.c.h文件,和昨天的不一样了。我定义了一个函数fuction2,根本就没用到过。
还是这么写
u8 a;
a = 0x00;
if(a)
{
fuction1();
}
结果fuction1();能执行到,也能达到函数目的。
现在我想把fuction2删掉,发现fuction1();能执行到,却达不到函数目的了。
这个fuction2真的没用过,也什么都没干。

请教各位这么诡异的bug出现的原因可能是什么?为了测试,我已经把函数简化到最简,变量名字也不会出问题。由于代码太长,都是干扰,我没法贴出来,只能这么硬说了。


自在随心
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

290

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1130
金钱
1130
注册时间
2015-8-4
在线时间
107 小时
发表于 2016-5-24 17:03:55 | 显示全部楼层
我表示没看懂。if(a)难道不是a为非0 才执行?你都赋值为0了怎么会执行呢。
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11545
金钱
11545
注册时间
2014-4-1
在线时间
1315 小时
发表于 2016-5-24 17:28:43 | 显示全部楼层

什么平台?


回复

使用道具 举报

1

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2015-11-26
在线时间
25 小时
发表于 2016-5-24 17:48:17 | 显示全部楼层
kingnike 发表于 2016-5-24 17:03
我表示没看懂。if(a)难道不是a为非0 才执行?你都赋值为0了怎么会执行呢。

哈哈哈哈    他自己也不知道
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-24 18:11:53 | 显示全部楼层
kingnike 发表于 2016-5-24 17:03
我表示没看懂。if(a)难道不是a为非0 才执行?你都赋值为0了怎么会执行呢。

好吧,笔误,其实我后面还有个else,我是想让它进else。代码很长,我不想写出来而已。
用的keil4.定义了一个全局变量,只要我用到它,和它完全不相关的一个函数就会突然出问题。
fuction1(u16 temp_val,float user,float sign)
{
此处用串口打印temp_val user sign三个数
}
打印出的user和sign就会变成0.0和0.0,如果我没用到这个全局变量,打印出的就是我想要的值,比如20.3和1.2.
也是编程好久了,编程代码的低级错误我不会犯,我就想请教,都有什么原因会导致这种奇葩现象出现,一个全局变量的使用会导致另一个完全不相关的函数失效。
自在随心
回复

使用道具 举报

4

主题

290

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1130
金钱
1130
注册时间
2015-8-4
在线时间
107 小时
发表于 2016-5-25 09:00:56 | 显示全部楼层
yuzeyuan1 发表于 2016-5-24 18:11
好吧,笔误,其实我后面还有个else,我是想让它进else。代码很长,我不想写出来而已。
用的keil4.定义了 ...

keil里面把优化等级改成0试试。
活到老,学到老。
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-5-25 09:07:10 | 显示全部楼层
换个串口助手试试,真的
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-26 08:39:34 | 显示全部楼层
kingnike 发表于 2016-5-25 09:00
keil里面把优化等级改成0试试。

你好,请问优化等级是什么?
昨天上午重写了一遍代码,什么都没变,就好了。然后昨天下午又添加了一个全局变量,又诡异地挂掉,试了好久,发现只要屏蔽掉下面两行代码就好使。
a[0]=(sx*sy-7*sxy)/(sx*sx-7*sx2);
a[1]=(sx2*sy-sx*sxy)/(7*sx2-sx*sx);
是一个最小二乘拟合的公式,分子分母都不是0,所有变量都是float型。
朋友也在帮我测试,他那里也是时好时坏,出错崩溃的函数和导致此次错误的代码都完全不沾边。
自在随心
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2016-5-26 09:00:48 | 显示全部楼层
你是怎么定义“函数能执行到”,又是怎么定义“函数能达到目的”的?你debug的时候是否看到程序指针跑了进来又跑出去了?
你用那个全局变量到底干什么了,是简单的赋值为常量,还是做了运算,还是调用了什么函数?
你注销掉的2行代码,最可能只在运行时才出错的原因大概就是溢出,除零,数组越界这几个了,你是如何断定减法不会产生0结果的?
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-26 10:28:38 | 显示全部楼层
xianshasaman 发表于 2016-5-26 09:00
你是怎么定义“函数能执行到”,又是怎么定义“函数能达到目的”的?你debug的时候是否看到程序指针跑了进 ...

你好,感谢回答!
1、函数能执行到,我是每一句代码后面都加了串口打印,单步调试也可以过。只要进了函数,原本输入参数为0.9 200,进入函数后参数就变成了0.0 0.0.就像是程序崩了一样,但是程序仍然在运行。(现在还是这样,最头疼的地方,找不到原因)
2、全局变量什么都没干,只有定义,和一个if判断。if内部没有这个全局变量。
3、这2行公式,所有输和参数都是我自己控制的,是多少我有准,它不可能出现数组溢出和分母为0的情况。
自在随心
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-5-26 10:37:10 | 显示全部楼层
你是用串口验证你的参数值吗?最好直接在编译器上看
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-26 11:18:34 | 显示全部楼层
不吃鱼的老鼠 发表于 2016-5-26 10:37
你是用串口验证你的参数值吗?最好直接在编译器上看

编译器上直接看也不对的。
串口我其实是为了证明它能够运行到这里。还有个LCD屏,如果它数是对的,LCD也会有显示。
自在随心
回复

使用道具 举报

0

主题

183

帖子

0

精华

高级会员

Rank: 4

积分
684
金钱
684
注册时间
2016-1-27
在线时间
184 小时
发表于 2016-5-26 11:29:28 | 显示全部楼层
yuzeyuan1 发表于 2016-5-26 11:18
编译器上直接看也不对的。
串口我其实是为了证明它能够运行到这里。还有个LCD屏,如果它数是对的,LCD也 ...

如果确定是公式的问题,可以分解公式,分成一步一步,设置标志位,单步执行,查看值的变化,既然找到问题了,排错的方式有很多,但是一般这种都是自己编程时没注意的小错误
回复

使用道具 举报

15

主题

184

帖子

0

精华

高级会员

Rank: 4

积分
647
金钱
647
注册时间
2014-4-29
在线时间
299 小时
发表于 2016-5-26 11:39:15 | 显示全部楼层
yuzeyuan1 发表于 2016-5-26 10:28
你好,感谢回答!
1、函数能执行到,我是每一句代码后面都加了串口打印,单步调试也可以过。只要进了函 ...

bug是挺坑的。别着急,慢慢调。看起来你这个程序就是输入,计算,输出之间和你预想的结果不一样。必然是3个环节中的某个除了问题。
输入是怎么输入的,是串口输入字符串还是用立即数直接赋值的?输出是通过串口输出字符串吗?输入输出的浮点和整形与字符串之间的转换是自己写的吗?有没有测试过?计算模块的接口是怎么设计的?测试过吗?我说这些不是非要你回答,是要你自己想一下
分析bug尽量孤立的,片面的看问题,不要辩证的,整体的搞,别非要和哪个全局变量联系起来,重现一下问题,在线调下,仔细看看每个环节输入和输出的数据,什么时候开始数据就和预期的不一致了?
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-5-26 11:54:15 | 显示全部楼层
以我入门两天级别的经验,应该是内存问题

先确保函数形参和载入变量的一致性。否则内存地址错位

回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-26 13:20:18 | 显示全部楼层
止天 发表于 2016-5-26 11:54
以我入门两天级别的经验,应该是内存问题

先确保函数形参和载入变量的一致性。否则内存地址错位

这个不大了解,请问内存问题会导致时好时坏吗?有时候想调出错都调不出来了。
自在随心
回复

使用道具 举报

22

主题

751

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1605
金钱
1605
注册时间
2015-6-10
在线时间
222 小时
发表于 2016-5-27 14:21:29 | 显示全部楼层
yuzeyuan1 发表于 2016-5-26 13:20
这个不大了解,请问内存问题会导致时好时坏吗?有时候想调出错都调不出来了。

会的
比如   void FX(u16 temp)

u8 i;

FX(i);

这个时候如果temp内存分配的高八位有值(未必有,就时好时坏)

temp有可能是大于256的值
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
10
金钱
10
注册时间
2016-5-26
在线时间
1 小时
发表于 2016-5-27 16:20:43 | 显示全部楼层
带rtos吗?不带的话直接改下系统的堆栈大小,带的话改下任务的堆栈大小。进入函数时输入参数出错可能与堆栈有关系。
另外改程序优化级别你不会吗?改成不优化试试。
回复

使用道具 举报

18

主题

79

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
283
金钱
283
注册时间
2015-11-12
在线时间
54 小时
发表于 2016-5-27 16:42:59 | 显示全部楼层
你是不是在else里也用了function1()
回复

使用道具 举报

7

主题

188

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2282
金钱
2282
注册时间
2013-12-16
在线时间
448 小时
发表于 2016-5-27 17:40:15 | 显示全部楼层
出现诡异情况时,我感觉多数都是内存泄漏造成的,内存因此被非法篡改,所以会出现诡异情况,毫不相干的数据却会相互影响.因为我就遇到过几次,最终结果都是因为内存泄漏造成的.
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-28 10:29:11 | 显示全部楼层
zdfwyh 发表于 2016-5-27 17:40
出现诡异情况时,我感觉多数都是内存泄漏造成的,内存因此被非法篡改,所以会出现诡异情况,毫不相干的数据却会 ...

谢谢,内存泄漏是不是基本没办法找?只能一点一点屏蔽代码找吗?
我现在发现是float类型的问题,之前听说float会出问题,也没用过。突然间涉及了一些公式要用浮点型,就加入了float。虽然好使了一阵,但时好时坏,现在全扔掉就好用了。
自在随心
回复

使用道具 举报

7

主题

188

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2282
金钱
2282
注册时间
2013-12-16
在线时间
448 小时
发表于 2016-5-28 10:40:07 | 显示全部楼层
yuzeyuan1 发表于 2016-5-28 10:29
谢谢,内存泄漏是不是基本没办法找?只能一点一点屏蔽代码找吗?
我现在发现是float类型的问题,之前听 ...

不好查,不过不外乎指针过界,数组超上限等这几种情况,主要是指针操作最容易造成内存泄漏.你将float相关的代码好好查查吧,可以换成double类型试一试
回复

使用道具 举报

50

主题

1805

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
6662
金钱
6662
注册时间
2016-5-29
在线时间
910 小时
发表于 2016-5-29 03:14:25 | 显示全部楼层
u8 a;
a = 0;
if(a == 0)
{

funtion1();//不执行就是有中断函数修改了 a

}


if(a)
{
  funtion2();// 会执行就怪了.
}
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-5-28
在线时间
1 小时
发表于 2016-5-29 08:39:46 | 显示全部楼层
编译选项中,降低优化等级即可解决这个问题
回复

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2016-5-28
在线时间
1 小时
发表于 2016-5-29 08:43:13 | 显示全部楼层
其实这也不是bug。系统在编译优化时会进行处理,发现你的a变量如果在系统全局中没有使用变化过,你的if估计就给甩了
回复

使用道具 举报

84

主题

766

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2775
金钱
2775
注册时间
2015-6-1
在线时间
394 小时
 楼主| 发表于 2016-5-30 14:44:37 | 显示全部楼层
zdfwyh 发表于 2016-5-28 10:40
不好查,不过不外乎指针过界,数组超上限等这几种情况,主要是指针操作最容易造成内存泄漏.你将float相关的 ...

double也不好使。暂时用无符号整型代替了,等过半个月项目结了,有时间再好好查查。
自在随心
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2016-6-1 22:01:42 | 显示全部楼层
有点像字节对齐的问题现象。
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 00:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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