免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3564 | 回复: 6

[C++] g++3.4 x86 RH AS5 Dynamic_cast 导致奔溃 [复制链接]

论坛徽章:
0
发表于 2010-04-24 18:02 |显示全部楼层
请教CUer一个基础问题,大致信息如下   先谢谢.

1) 最近接收维护一个有历史的lib, 其中Class C 继承 Base A 和 Base B
    A用于定义一个连接池维护算法, B用于附加属性和状态管理
    A,B 均有Virtual Methods
2) 由于连接池算法针对Base A, 所以
    以前的逻辑是取得A类型后用强制转换来得到C类型, C* pXC = (C*) pX;
3) 在出现奔溃后,改成 C* pXC = dynamic_cast <C*> pX;
   
4) 症状: 在出错的情况下没有返回NULL而是直接Crash掉了

5) 问题: dynamic_cast 有哪些可能的情况不返回NULL而是直接奔溃?

6) 有任何更新,我会直接编辑这个Post

# Java VM: Java HotSpot(TM) Client VM (14.3-b01 mixed mode linux-x86 )
# Problematic frame:
# C  [libstdc++.so.6+0xb357e]  __dynamic_cast+0x2e
#
# If you would like to submit a bug report, please visit:
#   http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

---------------  T H R E A D  ---------------

Current thread (0x0a19c400):  JavaThread "TP-Processor1" daemon [_thread_in_native, id=24193, stack(0xe5931000,0xe5b32000)]

siginfo:si_signo=SIGSEGV: si_errno=0, si_code=1 (SEGV_MAPERR), si_addr=0x0000000c

Registers:
EAX=0x00000008, EBX=0x00000000, ECX=0x00000001, EDX=0x0a5341e8
ESP=0xe5b308e0, EBP=0xe5b30928, ESI=0x0a5341e8, EDI=0x00000000
EIP=0xebafd57e, CR2=0x0000000c, EFLAGS=0x00210212

Top of Stack: (sp=0xe5b308e0)
0xe5b308e0:   00000000 00000000 00000000 00000000
0xe5b308f0:   00000000 00000000 00000000 00000000
0xe5b30900:   00000000 00000000 00000000 00000000
0xe5b30910:   00000000 00000000 00000000 0a5341e8
0xe5b30920:   0a4b4458 00000000 e5b30948 ec3bb1f0
0xe5b30930:   0a5341e8 ec3f3c04 ec3f44e0 00000000
0xe5b30940:   00000000 0a52d1b4 e5b30988 ebbd743f
0xe5b30950:   0a4b4458 000003e8 00000001 00000000

Instructions: (pc=0xebafd57e)
0xebafd56e:   00 00 8b 02 89 d6 c7 45 e4 00 00 00 00 83 e8 08
0xebafd57e:   8b 50 04 03 30 8d 45 e4 c7 45 f4 10 00 00 00 8b

Stack: [0xe5931000,0xe5b32000],  sp=0xe5b308e0,  free space=2046k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libstdc++.so.6+0xb357e]  __dynamic_cast+0x2e
C  [libSomeLib.so+0x9d1f0]  methodOfSomeLib+0x8c

论坛徽章:
0
发表于 2010-04-24 18:21 |显示全部楼层
dynamic_cast    使用的场合时 RTTI  or  Derived -> base

论坛徽章:
0
发表于 2010-04-24 18:24 |显示全部楼层
本帖最后由 MaxWu 于 2010-04-24 18:27 编辑

谢谢,
我的情况是Base->Derived,但Base只是显式类型,实际类型还应该是Derived,
我来查一下g++, VC是需要显式turn on的,由于效率问题,GCC应该是缺省就打开的.
重现的概率不算很高,但多运行这一段几次,也会有.

论坛徽章:
0
发表于 2010-04-24 18:42 |显示全部楼层
如果从语法的角度看的话 dynamic_cast  可以 cast null pointers

我猜 还是你的业务逻辑吧! 期待楼下的同学

论坛徽章:
0
发表于 2010-04-24 18:50 |显示全部楼层
Yeah, 首先怀疑的还是业务逻辑,目前碰到的问题是,通过Dynamic_cast即使是NULL应该也不会崩溃,返回NULL还是可以继续进行处理的.
出错的情况下Base的属性确实比较奇怪, 0 或者 0xF 开头的值在一个存时间+expiryTime 的 Millisecond Ulong 里面, 所以基本可以肯定是业务逻辑上的问题,返回了无效的数据.
所以这里最好能加上一个测试.

论坛徽章:
0
发表于 2010-04-25 18:39 |显示全部楼层
本帖最后由 MaxWu 于 2010-04-25 19:00 编辑

现在终于设法让Valgrind可以跑在JVM上了, 等下看分析结果再来更新.
RHEL5上跑的系统但是出于历史原因,编译还是用gcc-3.4.6-8.
通读一下, 问题大约出在队列的移动上,某处从Idle队列向Busy队列移动一个链接的时候会出Crash
  1. if (XXX ==0 && idle_list.size()>0)
  2.     {
  3.         obj=idle_list.back();
  4.         idle_list.pop_back();
  5.         busy_list.push_back(obj);
  6.     }
复制代码
编辑一下, 这里的obj无论Base还是Derived都没有重载op=,而std::list会调delete,...

论坛徽章:
0
发表于 2010-04-27 09:37 |显示全部楼层
   原因找到了. 谢谢关注的同仁.

Race Condition, 有被标记为close的连接被重新使用了. 当标记为close时,另一个Cleaner会定期来查询做回收.
静态检查,如Valgrind对于业务相关的状态是很难查出来, (不过如果是用Together的状态机生成的code可以用UML模拟器来做检查).
这次主要是通过人工review,在排除了接口问题之后,集中看Calling Party这边的使用逻辑.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP