DDD 2010年03月30日 星期二 17:59 | 2357次浏览 | 0条评论
这里记录了
 libfetion bugs
 
 
 1: linux 64位系统支持
 
 
 在linux64位版本,libfetion运行一会就崩溃
 
 
 
 这个问题困扰了我很久,程序运行一会,铁定会在m_get_sipmsg()函数处崩溃,
 
 那时来回检测了N遍代码,都觉得代码没问题。我和Wenbo Yang也就这个问题研究了好几天。
 
 
 场景:
 
 m_get_sipmsg()函数返回一个诡异的指针地址(无效),导出程序访问错误地址而崩溃
 
 
 1.1:
 
 Breakpoint 3, sipmsg_parse_msg (
 
 msg=0x2299fc0 "SIP-C/2.0 401 Unauthoried\r\nF: 67992***\r\nI: 1\r\nQ: 1 R\r\nW: Digest algorithm=\"MD5-sess;SHA1-sess\",nonce=\"1CA6E19B19CCE0D7262EBC1714345FDA\"\r\n\r\n")
 
 at sipmsg.c:85
 
   正确的 msg 参数地址,是类似于 msg=0x2299fc0 的
 
 
 1.2
 
 Breakpoint 3, sipmsg_parse_msg (
 
 msg=0x7f6b980016b0 "SIP-C/2.0 200 OK\r\nI: 1\r\nQ: 2 R\r\nX: 600\r\nL: 1291\r\n\r\n<results><client><custom-config version=\"296149662\">H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++99"...) at sipmsg.c:85
 
   会出问题的是这样的参数地址 msg=0x7f6b980016b0 ,而我们获取的地址是其的低位。
 
 
 
 分析:
 
 开始我和Wenbo Yang以为是系统malloc了错误的地址给我们或者我们在哪已经把程序内存给写坏了,导致app引用出错。但如果真是那样的话,基本是很难找到解决方法。
 
 而且问题只出在64位系统上,32位能够正常运行。
 
 最后我实在没辙了,只好找zeng兄来帮我分析下,我把我们的情况详细的给zeng兄说了说,并且将m_get_sipmsg相关的代码和反汇编给zeng兄发过去。
 
 
 zeng兄的经验果然老到,第二天就告诉我原因了,原来是....
 
 
 
             while(sipmsg = m_get_sipmsg())
 
  130:   b8 00 00 00 00          mov    $0x0,%eax
 
  135:   e8 00 00 00 00          callq  13a <thread_funcs+0x13a>
 
  13a:   48 98                   cltq
 
  13c:   48 89 45 f8             mov    %rax,-0x8(%rbp)
 
  140:   48 83 7d f8 00          cmpq   $0x0,-0x8(%rbp)
 
  145:   0f 85 53 ff ff ff       jne    9e <thread_funcs+0x9e>
 
                 } //end of sipmsg->method, sometimes the method will be null.
 
                 sipmsg_free(sipmsg);
 
                 sipmsg = NULL;
 
             }
 
 
 
 请注意:
 
  130:   b8 00 00 00 00          mov    $0x0,%eax
 
  135:   e8 00 00 00 00          callq  13a <thread_funcs+0x13a>
 
  13a:   48 98                   cltq
 
 
 cltq[x86-64] convert double word to quad word,
 
 这就是为什么当malloc分配出出高位地址的时候,我们却是获取了底位地址指针的原因。
 
 
 造成这个原因的问题是:
 
 在当前的.c文件没有包含m_get_sipmsg()函数的申明,所以在编译时,编译器就默认为void*这样的类型的,
 
 并且使用cltq指令来强转返回值。这样在64位系统上,很有可以将64位的指针截短为32位的,导致指针取址失败。
 
 
 
 解决:
 
 在那个c文件处加上m_get_sipmsg()函数申明,处理所有该相关的编译警告,最后libfetion在64位机上终于能稳定运行了...
 总结:
 
 应该理会每一个编译器给出的warning,尽量需要处理到每一个warning,也许该warning后就隐藏着一个缺陷.
 非常感谢zeng兄和Wenbo Yang在这个问题上给予我极大的帮助。
 
 
 
 
 
 
 2: 符号隐藏
 
 在debain系统上,很多朋友都遇到了libfetion登录崩溃的问题,最近我在给龙芯移植LibFetiond时,也遇到了这个诡异的问题.
 
 
 场景:
 
 2.1: 崩溃的代码单独提取处理运行没问题,但只要链接到libfetion库则会崩溃.
 
 2.2: 使用libcurl4-gnutls-dev包,则无论链接到libfetion库与否都没问题,但使用libcurl-openssl-dev包则会有问题。
 
 
 
 分析:
 
 从这个现象上看,应该是libfetion库里面的一些符合名和libcurl-openssl-dev有些重叠了,导致本该调用libcurl-openssl-dev里的函数,确调用到
 
 libfetion里的某个函数了
 
 
 
 解决:
 
 编译libfetion库时,隐藏不必要的符合导出,增加编译选项: -fvisibility=hidden
Zeuux © 2025
京ICP备05028076号
暂时没有评论