Dropbox crash dump quick analysis (on Windows)

I don’t exactly remember the last time I installed or upgrade the Dropbox on my Windows 8 laptop, but today one of my application started crashing itself whenever I opened a file open browser within app and it turned out it caused by Dropbox extension after quick analysis of crash dump. Unfortunately re-installing the most recent version doesn’t fix the problem so far.

Shows the moment when the crash occurred.

0:002> r
eax=59d0d000 ebx=74a91a9c ecx=00000000 edx=0000d0d0 esi=74a91aa0 edi=0000003f
eip=74ac7736 esp=0c04c434 ebp=0c04c440 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010216
74ac7736 0fb710 movzx edx,word ptr [eax] ds:002b:59d0d000=????  <== invalid memory access

Let’s see the call stack who gave the wrong param.

0:002> kP L4
ChildEBP RetAddr 
0c04c440 74abae83 msvcr90!wcspbrk(
 wchar_t * string = 0x59d0cf80 "C:\Users\xxxxx.xxx\AppData\Roaming\Dropbox\shellext \new_trace탐탐", 
 wchar_t * control = 0x74a91a9c "?*")+0x34
0c04c8d8 59405f72 msvcr90!_wstat64i32(
 wchar_t * name = 0x59d0cf80 "C:\Users\xxxxx.xxx\AppData\Roaming\Dropbox\shellext \new_trace탐탐", 
 struct _stat64i32 * buf = 0x0c04c8f8)+0x5d
WARNING: Stack unwind information not available. Following frames may be wrong.
0c04c940 59406524 DropboxExt_24+0x5f72
0c04cd58 594135ff DropboxExt_24+0x6524
DropboxExt_24 calls msvcr90!_wstat64i32 with 0x59d0cf80.
0:002> dU 0x59d0cf80 
59d0cf80 "C:\Users\xxxxx.xxx\AppData\Roami"
59d0cfc0 "ng\Dropbox\shellext \new_trace탐탐"
59d0d000 "????????????????????????????????"
59d0d040 "????????????????????????????????"
59d0d080 "????????????????????????????????"
59d0d0c0 "????????????????????????????????"
59d0d100 "????????????????????????????????"
59d0d140 "????????????????????????????????"
59d0d180 "????????????????????????????????"
59d0d1c0 "????????????????????????????????"
59d0d200 "????????????????????????????????"
59d0d240 "????????????????????????????????"
0:002> r eax
The address 59d0d000 is invalid and inaccessible area. I turned on gflag while capturing this.
0:002> !gflag
Current NtGlobalFlag contents: 0x02000000
 hpa - Place heap allocations at ends of pages
So it could show the original heap size as follows:
0:002> !heap -p -a 0x59d0cf80
 address 59d0cf80 found in
 _DPH_HEAP_ROOT @ 59a81000
 in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
 59a8309c: 59d0cf80 7c - 59d0c000 2000
 0f578d9c verifier!AVrfDebugPageHeapAllocate+0x0000023c
 7726f819 ntdll!RtlDebugAllocateHeap+0x00000032
 772072db ntdll!RtlpAllocateHeap+0x00036e22
 771d06d3 ntdll!RtlAllocateHeap+0x0000014c
 74af3db8 msvcr90!malloc+0x00000079 [f:\dd\vctools\crt_bld\self_x86\crt\src\malloc.c @ 163]
 59405ecd DropboxExt_24+0x00005ecd
 59405ca4 DropboxExt_24+0x00005ca4
 59406513 DropboxExt_24+0x00006513
 594135ff DropboxExt_24!DllUnregisterServer+0x0000cb3f
 594136b9 DropboxExt_24!DllUnregisterServer+0x0000cbf9
 771d7aee ntdll!LdrxCallInitRoutine+0x00000016
 771d7a6f ntdll!LdrpCallInitRoutine+0x00000043
 771e07bc ntdll!LdrpInitializeNode+0x0000011d
 771e065e ntdll!LdrpInitializeGraph+0x00000059
 771dff22 ntdll!LdrpPrepareModuleForExecution+0x00000121
 771e0d88 ntdll!LdrpLoadDll+0x00000392
 771dc3ce ntdll!LdrLoadDll+0x00000067
 75a42551 KERNELBASE!LoadLibraryExW+0x000000c2
 75291892 combase!LoadLibraryWithLogging+0x0000001b [d:\blue_gdr\com\combase\common\loadfree.cxx @ 160]
 752917e0 combase!CClassCache::CDllPathEntry::LoadDll+0x0000003e [d:\blue_gdr\com\combase\objact\dllcache.cxx @ 2409]
 7529169a combase!CClassCache::CDllPathEntry::Create+0x00000035 [d:\blue_gdr\com\combase\objact\dllcache.cxx @ 2252]
 75290fe2 combase!CClassCache::CClassEntry::CreateDllClassEntry+0x000000f3 [d:\blue_gdr\com\combase\objact\dllcache.cxx @ 1048]
 752911a8 combase!CClassCache::GetClassObjectActivator+0x00000851 [d:\blue_gdr\com\combase\objact\dllcache.cxx @ 6042]
 7529015a combase!CClassCache::GetClassObject+0x00000030 [d:\blue_gdr\com\combase\objact\dllcache.cxx @ 5808]
 75290e4c combase!CServerContextActivator::CreateInstance+0x00000107 [d:\blue_gdr\com\combase\objact\actvator.cxx @ 999]
 7528d0f6 combase!ActivationPropertiesIn::DelegateCreateInstance+0x0000006e [d:\blue_gdr\com\combase\actprops\actprops.cxx @ 1906]
 75290d29 combase!CApartmentActivator::CreateInstance+0x00000075 [d:\blue_gdr\com\combase\objact\actvator.cxx @ 2323]
 75290c55 combase!CProcessActivator::CCICallback+0x00000039 [d:\blue_gdr\com\combase\objact\actvator.cxx @ 1786]
 7529095a combase!CProcessActivator::AttemptActivation+0x0000002c [d:\blue_gdr\com\combase\objact\actvator.cxx @ 1673]
 75290baa combase!CProcessActivator::ActivateByContext+0x00000094 [d:\blue_gdr\com\combase\objact\actvator.cxx @ 1539]
 75290c0c combase!CProcessActivator::CreateInstance+0x00000046 [d:\blue_gdr\com\combase\objact\actvator.cxx @ 1405]
 7528d0f6 combase!ActivationPropertiesIn::DelegateCreateInstance+0x0000006e [d:\blue_gdr\com\combase\actprops\actprops.cxx @ 1906]
The heap allocation callstack shows DropboxExt_24+0x00005ecd actually allocated only 0x7c. (UserSize is 0x7c), not area for whole path.
0:002> ? 0x7c 
Evaluate expression: 124 = 0000007c
0:002> lmvm DropboxExt_24
start end module name
59400000 59423000 DropboxExt_24 (export symbols) DropboxExt.24.dll
 Loaded symbol image file: DropboxExt.24.dll
 Image path: C:\Users\xxxxx.xxx\AppData\Roaming\Dropbox\bin\DropboxExt.24.dll
 Image name: DropboxExt.24.dll
 Timestamp: Tue Jun 24 09:31:58 2014 (53A8C6FE)
 CheckSum: 00021746
 ImageSize: 00023000
 File version:
 Product version:
 File flags: 0 (Mask 3F)
 File OS: 4 Unknown Win32
 File type: 2.0 Dll
 File date: 00000000.00000000
 Translations: 0409.04e4
 CompanyName: Dropbox, Inc.
 ProductName: Dropbox
 InternalName: DropboxExt.dll
 OriginalFilename: DropboxExt.dll
 FileDescription: Dropbox Shell Extension
 LegalCopyright: (c) Dropbox, Inc. All rights reserved

Tips for debugging COM AddRef/Release leaks

In Windows environment, adding an accessibility support to a program means you’ll have to do a lot of COM coding. For example, IRawElementProviderSimple is the most fundamental interface you should implement for every provider. So at first I started developing providers with ATL and throughout the process I learned few tips I’d like to share here:

1. Add the ‘_ATL_DEBUG_INTERFACES’ macro


MSDN link: http://msdn.microsoft.com/en-us/library/vstudio/sycfy8ec(v=vs.110).aspx

One thing should remember. If you add the _ATL_DEBUG_INTERFACES to your project, then you cannot use ‘static_cast’ to get an interface pointer between interfaces you inherited and always should get it via QueryInterface. If not, the code will crash instantly. Please refer to following forum quote more details:

Before using _ATL_DEBUG_INTERFACES, the code did a risky "static_cast"
(which itself should be a crime!) to convert a interface pointer to the
coclass object pointer. It apparently worked fine with AddRef/Release and so
one. However, as soon as _ATL_DEBUG_INTERFACES is defined, the _QI_Thunk
interface goes in between and the simple single inheritance didn't work out
any more. Thus the attempt to AddRef caused first-chance access violations
because the address of the function call was invalid and the reference count
were less than expected since. After you released and released it again, you
got the crash.

The fix for this is never do such cast. If you definitely need to get the
pointer to the class object, use a hidden method or get property to return
the this pointer.

Link: http://marc.info/?l=ms-dcom&m=103440653613791&w=2

2. Use CAdapt to contain CComPtr in std::vector

Consider wrapping CComPtr instances with CAdapt in order to maintain CComPtr instances within std::vector to avoid & operator problem.

CAdapt MSDN Link: http://msdn.microsoft.com/en-us/library/bs6acf5x.aspx

Typically, you will use CAdapt when you want to store CComBSTR, CComPtr, CComQIPtr, or _com_ptr_t objects in a container-style class. This was most commonly necessary for C++ Standard Library containers prior to support for the C++11 Standard, but C++11 Standard Library containers automatically work with types that have overloaded operator&(). The Standard Library achieves this by internally usingstd::addressof() to get the true addresses of objects