Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139713
  • 博文数量: 124
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 1745
  • 用 户 组: 普通用户
  • 注册时间: 2011-02-24 13:49
文章分类

全部博文(124)

文章存档

2011年(55)

2010年(14)

2009年(30)

2008年(25)

我的朋友

分类: WINDOWS

2011-09-13 15:26:09

今天发现在开发的产品中出现了一个crash,表现形式是开启了多个xxbrowser程序后,退出导致了camel 程序的crash。 

比较特别的是xxbrowser的dump机制竟然没有发挥作用。 由于这个问题能够比较简单的重复,所以用windbg attach之后看到如下。




从windgb给出的38行,看到是上图的加深的那一行,这儿呢,简单介绍一些背景,我们包装了log4cpp,然后这个包装类就是上述的clogshell ,而这个logshell又使用了单件模式构建,由于我曾经阅读过 《《c++设计新思维》》,这本书就讲到了单件的退出先后问题,所以我第一时间就认为是这个问题引起的,再仔细看看汇编代码。

所以我第一时间就怀疑这个m_logger 指针已经先delete了,然后又被后续调用者调用了logva,导致了crash。


但是非常郁闷的是用windbg 查看了m_logger 之后...


0:000> dt this
Local var @ 0x12fcb4 Type CLogShell*
0x655c3280 
   +0x000 m_logger         : 0x027bce80 ILogger
0:000> !address 0x027bce80 
 ProcessParametrs 002a1f60 in range 002a0000 00351000
 Environment 002a07f0 in range 002a0000 00351000
    027b0000 : 027b0000 - 00010000
                    Type     00020000 MEM_PRIVATE
                    Protect  00000004 PAGE_READWRITE
                    State    00001000 MEM_COMMIT
                    Usage    RegionUsageHeap
                    Handle   027b0000


发现m_logger 竟然是好的,即它并没有在crash的时候被释放。



那么问题在哪儿呢?

这儿有个技巧了,一般来说当一个c++对象被delete之后,你再访问它的地址空间,一般来说不一定会出问题,这个是由于运行库可能是出于性能考虑啥的,没有马上回收这块内存,所以类似这种问题你看到的现场往往已经不是真正的事发现场,所以比较推荐的方法是开启appverify 然后仅仅选择heaps。

FAULTING_IP: 
alilog!CLoggerImpl::Logva+90 [f:\src\alibrowser\camel\webim\source\log\alilog\source\logger.cpp @ 288]
05061d80 8b12            mov     edx,dword ptr [edx]

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 05061d80 (alilog!CLoggerImpl::Logva+0x00000090)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: 085b2f78
Attempt to read from address 085b2f78

FAULTING_THREAD:  0000136c

PROCESS_NAME:  Alibrowser.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - 0x%08lx

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  085b2f78

READ_ADDRESS:  085b2f78 

FOLLOWUP_IP: 
alilog!CLoggerImpl::Logva+90 [f:\src\alibrowser\camel\webim\source\log\alilog\source\logger.cpp @ 288]
05061d80 8b12            mov     edx,dword ptr [edx]

NTGLOBALFLAG:  2000100

APPLICATION_VERIFIER_FLAGS:  80000001

BUGCHECK_STR:  APPLICATION_FAULT_INVALID_POINTER_READ_SHUTDOWN

PRIMARY_PROBLEM_CLASS:  INVALID_POINTER_READ_SHUTDOWN

DEFAULT_BUCKET_ID:  INVALID_POINTER_READ_SHUTDOWN

LAST_CONTROL_TRANSFER:  from 732520f5 to 05061d80

STACK_TEXT:  
0012fc00 732520f5 00000000 7325c88c 0012fc48 alilog!CLoggerImpl::Logva+0x90 [f:\src\alibrowser\camel\webim\source\log\alilog\source\logger.cpp @ 288]
0012fc1c 732520ae 00000000 7325c88c 0012fc48 imentry!CLogShell::Logva+0x35 [f:\src\alibrowser\camel\webim\source\log\alilog\include\logger_shell.h @ 38]
0012fc34 732519db 7325f278 00000000 7325c88c imentry!CLogShell::Log+0x1e [f:\src\alibrowser\camel\webim\source\log\alilog\include\logger_shell.h @ 34]
0012fc6c 7325170b 561dea26 085c4fe0 0012fcb4 imentry!ImAppProxy::UnInit+0x11b [f:\src\alibrowser\camel\webim\source\imentry\imappproxy.cpp @ 155]
0012fc88 7325214f 085c4fe0 0012fcc0 732534f6 imentry!ImAppProxy::~ImAppProxy+0x4b [f:\src\alibrowser\camel\webim\source\imentry\imappproxy.cpp @ 63]
0012fc94 732534f6 00000001 561dea6e 0012fcc8 imentry!ImAppProxy::`scalar deleting destructor'+0xf
0012fcc0 73253316 0012fd0c 732565ec 73250000 imentry!CSingleton::DestroyInstance+0x66 [f:\src\alibrowser\camel\webim\include\singleton.h @ 50]
0012fcc8 732565ec 73250000 00000000 00000001 imentry!DllMain+0x16 [f:\src\alibrowser\camel\webim\source\imentry\imentry.cpp @ 31]
0012fd0c 732566a6 73250000 0012fd6c 6546c66d imentry!__DllMainCRTStartup+0x7a [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 546]
0012fd18 6546c66d 73250000 00000000 00000001 imentry!_DllMainCRTStartup+0x1e [f:\dd\vctools\crt_bld\self_x86\crt\src\crtdll.c @ 510]
0012fd6c 67e2898c 73250000 00000000 00000001 verifier!AVrfpStandardDllEntryPointRoutine+0x99
0012fdb4 773289d8 73250000 00000000 00000001 vrfcore!VfCoreStandardDllEntryPointRoutine+0x128
0012fdd4 7732e104 67e28864 73250000 00000000 ntdll!LdrpCallInitRoutine+0x14
0012fe78 7732e19f 050f4c00 050f4bfc 00000001 ntdll!LdrShutdownProcess+0x1aa
0012fe8c 7717bbf6 00000000 77e8f3b0 ffffffff ntdll!RtlExitUserProcess+0x74
0012fea0 00fe7e9c 00000000 0012fef0 00fe8101 kernel32!ExitProcessStub+0x12
0012feac 00fe8100 00000000 564d3d0a fffffffe Alibrowser!__crtExitProcess+0x17 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 731]
0012fef0 00fe812a 00000000 00000000 00000000 Alibrowser!doexit+0x113 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 644]
0012ff04 00fe36f2 00000000 564d3c72 00000000 Alibrowser!exit+0x11 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0dat.c @ 412]
0012ff88 7716ed6c 7ffd7000 0012ffd4 773337f5 Alibrowser!__tmainCRTStartup+0x120 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 272]
0012ff94 773337f5 7ffd7000 6af3f144 00000000 kernel32!BaseThreadInitThunk+0xe
0012ffd4 773337c8 00fe374f 7ffd7000 00000000 ntdll!__RtlUserThreadStart+0x70
0012ffec 00000000 00fe374f 7ffd7000 00000000 ntdll!_RtlUserThreadStart+0x1b


SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  alilog!CLoggerImpl::Logva+90

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: alilog

IMAGE_NAME:  alilog.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  4e6eb3ab

STACK_COMMAND:  ~0s ; kb

FAILURE_BUCKET_ID:  INVALID_POINTER_READ_SHUTDOWN_c0000005_alilog.dll!CLoggerImpl::Logva

BUCKET_ID:  APPLICATION_FAULT_INVALID_POINTER_READ_SHUTDOWN_alilog!CLoggerImpl::Logva+90

WATSON_STAGEONE_URL:  

Followup: MachineOwner
---------



这次crash显示的具体场景不太一样了。 

alilog!CLoggerImpl::Logva+0x90 [f:\src\alibrowser\camel\webim\source\log\alilog\source\logger.cpp @ 288]



上图高亮的那行,由于开启了了appverify 触发的是第一现场,所以直接怀疑m_instance 有问题。


0:000> dt this
Local var @ 0x12fbc8 Type CLoggerImpl*
0x085a6ff0 
   +0x000 __VFN_table : 0x050652b4 
   +0x004 m_instance       : 0x085b2f78 log4cpp::Category
   +0x008 m_async          : 1
   +0x00c m_priority       : 700
0:000> !address 0x085b2f78 
 ProcessParametrs 0016a130 in range 0016a000 0016b000
 Environment 00167880 in range 00167000 00169000
    08550000 : 085b1000 - 00003000
                    Type     00020000 MEM_PRIVATE
                    State    00002000 MEM_RESERVE
                    Usage    RegionUsageIsVAD


非常清晰的看到m_instance 确实已经被回收了。

再来看看直接导致crash的asm代码

0:000> u eip
alilog!CLoggerImpl::Logva+0x90 [f:\src\alibrowser\camel\webim\source\log\alilog\source\logger.cpp @ 288]:
05061d80 8b12            mov     edx,dword ptr [edx]

edx=085b2f78


这下看到了,呵呵,确实是想对 这个m_instance deref导致了access违规。

而且两下验证确实也是证明了 edx=085b2f78 就是那个m_instance.


呵呵,其实m_instance 咋一个source code它还是一个引用,其实从asm直观的看到它其实仅仅是一个指针。


这下原因找到并且坐实了。


到了这儿,其实还有一个深层次问题,即如果这类问题无法很好的重复,且也没有实现打开appverify,那么如何诊断?


1, 从!analyze -v 来判断是否是raw ptr 这类问题。 最近这类问题很多,主要原因是错误的地方往往不是立刻crash。

2. 就事发点周围的相关模块查看他们的一些关键内存成员,这个就要具体问题具体看,但是至少你可以逐步排除缩小。

阅读(584) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~