第一次碰到同名函数引发的段错误,那还是要记下来,防止后面再犯同样的错误。
一、前提介绍。
1. 因工作需要,我在项目中要提供一套api给客户使用,我封装为libxxx.so的形式,客户使用我提供的接口。
2. 我还提供了一个api接口的test程序(包括源码)给客户,方便客户测试,或方便调用接口。test程序一直运行正常,在客户那里也是运行正常的。
3. 客户使用的代码,我没有,也无法用客户的程序调试。
二、故障现象。
十一之前,客户已经看到了段错误,但当时没有进入调试,不知道段错误在哪。
十一期间,客户找我,给我截图说是,我提供的库函数初始化函数出现了段错误。
一看,果然是我的msgq_send出现了问题,我看了一下我的代码,这是linux系统提供的消息队列,怎么就出现了段错误?什么情况啊?
空指针,这可能是程序员最容易想到的。加上对指针的判断,故障依旧!!!
无解,我没办法了。
我自己的test测试程序是正常的,怎么到客户那就是段错误呢?
改,我写了一个只有drvCoreBoardInit()函数被调用的测试程序,能编译,能运行,正常啊(客户使用也是正常的)。客户自己实际要用的程序还是段错误。
哎,心灰意冷。让客户去排查库的问题,是不是因为加了某些库,导致了异常????
三、问题排查及解决。
客户让我把msgq的代码注释掉,好,说好就动手。
1. 所有msgq的函数全部直接返回0
2. 去掉magq的函数调用,嘿,(客户的程序)正常!怪了系统调用有BUG!!??不可能吧。
3. 加上msgq的调用,函数中实际没有任何调用,只是进入函数就返回0. 啪,段错误!!!
有鬼啊!!!return 0也是段错误!!!看来函数有问题,可能是由同名函数!!!(这时候才想到,有点晚!!)
4.再次确认段错误的问题,发现msgq_send这个地址比较小,与main是比较接近的,而我的库函数(drvCoreBoardInit)的地址是大很多的(如下图指示),明显msgq_send不是我的库函数提供的。那就是客户的程序中有与这个同名的函数。
5. 跟客户确认,同名函数,果然,果然是同名函数惹的祸。
自己写,肯定不会写出一个同名函数出来,如何确保别人在使用我们自己的接口的时候,能不同名我自己的函数呢?这又是要学习的学问了。
第一次遇到同名函数的问题,没有经验,前前后后花了差不多一个礼拜才真正找到原因。甚至一度怀疑系统调用的bug,简直不敢想想。(主要是找不到问题的原因啊。)
函数地址是一个很明显的指示,下次一定要谨记!!!