把平时遇到的一些典型的、非典型的、可怕的、可笑的bug记录一下。
1、函数的返回值是一个地址(指针),且该函数没有声明,32位系统中没有问题,但程序移植到了64位系统中,出现了段错误,原因是:没有声明的函数,编译器默认把返回值变为int型,而正确的指针(地址)应该是64位的;解决办法:记得一定要准确的声明函数。
2、依然是32位向64位移植出现的问题,32位中:int 32位,long32位,指针32位 64位中:int 32位,long 64位,指针64位;有不标准的写法,把指针(地址)放在int中存放,程序移植到64位中,就会出现段错误;解决办法:修改用于存储传递指针的变量为intptr_t 类型定义,以保证平台兼容性
3、信号处理中的不可重入函数的使用,我们的程序中在信号处理函数中,做了太多的操作,竟然保护printf这种非可重入的函数,而且竟然在信号处理函数中因为马虎,踩了内存,触发signal11,死循环。。。 解决办法:信号处理函数,尤其是异常信号处理函数,一定要简洁,且不能有非可重入函数,我采用了信号量的方式,程序中专门有一个线程负责信号处理(堆栈回溯、异常日志记录 等),semwait一直等待,等待信号处理函数里面简单的sempost触发实际处理流程。
4、自己实现了一个ftp客户端,下载2进制格式的文件,该文件是由c代码编译而成,c代码中有类似printf("##########################################")的打印,####很长。下载时bug出现了,文件只能下载一部分,无法正常全部下载完成,试过其他普通文件,均可以正常下载; 后来把########去掉一部分,重新编译了这个2进制文件, 就可以把它下载成功了; 问题的原因后来没时间仔细追究,不过蛮奇怪的,记录一下
5、服务器程序,这个程序的启动时会检查某个key,判断是否已经有程序启动,这个是背景1,程序中新增加了一个功能,使用system调用,启动了一个监控cpu使用率的脚本,这个是背景2; 后来有个小伙把进程杀掉,重启启动时发现启动不成功,提了故障单;后来想起来system调用的原理是fork子进程,并用exec启动sh,sh脚本继承了父进程的资源,导致重启程序时失败。 解决办法:不要在程序中用system启动脚本,可以放在系统的自启动项里面,或者杀大程序的同时,把这个被调用起来的脚本监控也杀掉。
未完待续。。。。。
继续:
6、创建线程,没有设置为可分离线程,也就默认成了非可分离线程,这样也没问题,但是没有地方调用join去回收线程,导致线程退出时,没有得到资源回收,最后导致内存不足,新创建线程失败。
7、ftok的小bug,ftok创建key时以文件名和id作为标示,共同创建,按理说文件名不一样,id相同 创建出的key应该是不一样的 但是,大家可以man一下ftok,有说明:比如/dev/sda1 /dev/hda1 +一样的ID 是有可能产生相同的key的.
Of course no guarantee can be given that the resulting key_t is unique. Typically, a best effort attempt combines the given proj_id byte, the lower 16 bits of the inode number, and the lower 8 bits of the device number into a 32-bit result. Collisions may easily happen, for example between files on /dev/hda1 and files on /dev/sda1.
8、
阅读(1467) | 评论(0) | 转发(0) |