태그 : IE
2009/06/15   Internet Explorer+VB Runtime에서의 Crash 현상
Internet Explorer+VB Runtime에서의 Crash 현상

사실 아직까지 VB runtime Internet Explorer에 올라가 있다는 것은 그리 놀랍지 않다. COM개발이 도입이 되면서 ActiveX Control의 개발은 VB가 대체로 대세였다. 개발의 속도 면에서 그리고, User Interface를 쉽게 제공해주는 면에서 거부할 수 없는 선택 이였다. 하지만, VB runtime의 태생적인 Threading Model의 한계는 Internet Explorer가 마치 Server Application Environment 처럼 변모하면서 너무나 많은 제약을 얻을 수 밖에 없게 되었다. 다음의 Crash 현상 역시 이러한 변화 속에서 드러나는 단면이다.

 

0:000> kbL

ChildEBP RetAddr  Args to Child             

WARNING: Frame IP not in any known module. Following frames may be wrong.

001273e8 66107873 0eddbd00 00000000 00127494 <Unloaded_es_kr.dll>+0x64ff81

00127400 66107bec 00000000 00127424 03ffe070 MSVBVM60!ExHandleLBFailure+0x20

00127458 661079e5 03ffe070 80010003 00000004 MSVBVM60!ExLateIdNamed+0xca

00127484 66108b9a 03ffe070 80010003 fffffffd MSVBVM60!ExLateIdSt+0x4a

0012749c 06977430 03ffe070 80010003 00000004 MSVBVM60!__vbaLateIdSt+0x16

00127508 660ca914 0cd4f1d0 00000000 0cd4f1d0 ttt!DllCanUnloadNow+0x2e61e

00127564 660cae57 00000006 00000001 0e801210 MSVBVM60!RUN_INSTMGR::ExecuteInitTerm+0x178

00127598 660caab3 00000000 00000013 0400758c MSVBVM60!RUN_INSTMGR::CreateObjInstanceWithParts+0x1e4

00127618 660cbc3a 0cd4f1ec 00000000 00127a00 MSVBVM60!RUN_INSTMGR::CreateObjInstance+0x14d

001278cc 66072b6e 001278e4 00000000 03ffa66d MSVBVM60!TipCreateInstanceEx+0xd5

00127908 66078642 01572100 06930000 00000000 MSVBVM60!CThreadPool::CreateInstanceFactory+0xfd

00127a04 66078226 03ff4e8c 00000000 00000000 MSVBVM60!CPrivClassFactory::CreateInstanceLic+0x16e

00127a20 7e605619 03ff4e8c 00000000 7e3a3028 MSVBVM60!CPrivClassFactory::CreateInstance+0x1a

00127a5c 7e60aa10 031d8e48 031d9654 80004005 mshtml!COleSite::InstantiateObjectFromCF+0x114

00129ae0 7e60b386 7e3b919c 03ff4e8c 031d9654 mshtml!COleSite::CreateObjectNow+0xa5

00129b04 7e60bc1a 031d9610 7e3b919c 03ff4e8c mshtml!CCodeLoad::OnObjectAvailable+0x84

00129b78 7e60bf76 7e391b04 00129c68 031d8e00 mshtml!CCodeLoad::BindToObject+0x460

00129b98 7e605369 031d8e00 00129c68 7e60f904 mshtml!CCodeLoad::Init+0x287

00129c18 7e60f85c 00129c68 13ca5100 031d9470 mshtml!COleSite::CreateObject+0x26d

0012ddc8 7e5f393b 7e4306e9 13c9b6c0 00000020 mshtml!CObjectElement::CreateObject+0x72a

 

es_kr.dll unload되었다고 믿기 어렵다. 최종 Stack에서 Assembly Check하더라고 이것이 정확한 instruction인지 믿기 어려운 상황이다.

 

0:000> u

<Unloaded_es_kr.dll>+0x64ff81:

00650072 6f              outs    dx,dword ptr [esi]

00650073 bc46c045c0      mov     esp,0C045C046h

00650078 0000            add     byte ptr [eax],al

0065007a 0000            add     byte ptr [eax],al

0065007c e8e8448a00      call    <Unloaded_es_kr.dll>+0xef4478 (00ef4569)

00650081 0000            add     byte ptr [eax],al

00650083 0000            add     byte ptr [eax],al

00650085 008001000000    add     byte ptr [eax+1],al

 

이러한 경우는 최종적으로 Thread Stack이 정상적으로 보이는 Frame에서 EIP가 잘못될 가능성이 없는 지를 Check 해야 한다.

 

ChildEBP RetAddr  Args to Child

001273e8 66107873 0eddbd00 00000000 00127494 <Unloaded_es_kr.dll>+0x64ff81

00127400 66107bec 00000000 00127424 03ffe070 MSVBVM60!ExHandleLBFailure+0x20

 

0:000> ub 66107873

MSVBVM60!ExHandleLBFailure+0xc:

6610785f ff15b8100066    call    dword ptr [MSVBVM60!_imp__TlsGetValue (660010b8)]

66107865 8bd8            mov     ebx,eax  <--- eax TlsGetValue return

66107867 8b03            mov     eax,dword ptr [ebx]

66107869 85c0            test    eax,eax

6610786b 7409            je      MSVBVM60!ExHandleLBFailure+0x23 (66107876)

6610786d 8b08            mov     ecx,dword ptr [eax]  <--- ecx eax address

6610786f 50              push    eax

66107870 ff5108          call    dword ptr [ecx+8]

 

0:000> r

eax=0eddbd00 ebx=001e1f38 ecx=0ce1ef38 edx=04009b10 esi=00127494 edi=00000000

eip=00650072 esp=001273ec ebp=00127400 iopl=0         nv up ei pl nz na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00240206

<Unloaded_es_kr.dll>+0x64ff81:

00650072 6f              outs    dx,dword ptr [esi]   ds:0023:00127494=fffffffd

 

0:000> ? 0ce1ef38+8

Evaluate expression: 216133440 = 0ce1ef40 <--- call dword ptr[0ce1ef40]

 

하지만, 아래 data를 보면, Method로 보이진 않는 다. 단지 String Data로 보인다. 그러므로, Tls Broken 된 것으로 추측할 수 있다.

 

0:000> dc 0ce1ef40

0ce1ef40  00650072 003a0072 00680020 00740074  r.e.r.:. .h.t.t.

0ce1ef50  003a0070 002f002f 00300037 0032002e  p.:././.7.0...2.

0ce1ef60  0031002e 00300034 0031002e 00300034  ..1.4.0...1.4.0.

0ce1ef70  0039003a 00310030 002f0036 00740068  :.9.0.1.6./.h.t.

0ce1ef80  006c006d 00700043 002f0063 00720070  m.l.C.p.c./.p.r.

0ce1ef90  002f006f 0048004d 0046005f 00310030  o./.M.H._.F.0.1.

0ce1efa0  0030005f 002e0031 0073006a 000d0070  _.0.1...j.s.p...

0ce1efb0  0041000a 00630063 00700065 002d0074  ..A.c.c.e.p.t.-.

 

0:000> dc 0ce1ef40-10

0ce1ef30  00a20016 030a01ee 0e98bb18 00650066  ............f.e.

0ce1ef40  00650072 003a0072 00680020 00740074  r.e.r.:. .h.t.t.

0ce1ef50  003a0070 002f002f 00300037 0032002e  p.:././.7.0...2.

0ce1ef60  0031002e 00300034 0031002e 00300034  ..1.4.0...1.4.0.

0ce1ef70  0039003a 00310030 002f0036 00740068  :.9.0.1.6./.h.t.

0ce1ef80  006c006d 00700043 002f0063 00720070  m.l.C.p.c./.p.r.

0ce1ef90  002f006f 0048004d 0046005f 00310030  o./.M.H._.F.0.1.

0ce1efa0  0030005f 002e0031 0073006a 000d0070  _.0.1...j.s.p...

 

0:000> u MSVBVM60!ExHandleLBFailure 66107873

MSVBVM60!ExHandleLBFailure:

66107853 55              push    ebp

66107854 8bec            mov     ebp,esp

66107856 53              push    ebx

66107857 56              push    esi

66107858 57              push    edi

66107859 ff357cee1066    push    dword ptr [MSVBVM60!g_itlsEbthread (6610ee7c)]

6610785f ff15b8100066    call    dword ptr [MSVBVM60!_imp__TlsGetValue (660010b8)]

66107865 8bd8            mov     ebx,eax

66107867 8b03            mov     eax,dword ptr [ebx]

66107869 85c0            test    eax,eax

6610786b 7409            je      MSVBVM60!ExHandleLBFailure+0x23 (66107876)

6610786d 8b08            mov     ecx,dword ptr [eax]

6610786f 50              push    eax

66107870 ff5108          call    dword ptr [ecx+8]

 

Thread Stack은 다르더라도 상위의 TLS(Thread Local Storage)연산에 대한 Assembly code는 기억해둘 필요가 있다. VB runtime Thread Safe 한 처리를 이유로 주로 TLS를 이용한다. 하지만, IE7 이상의 Browser에서 TAB Browser의 처리에 따라서 동일한 VB ActiveX Control이 중복해서 하나의 Browser load되는 가능성도 커졌다. 이에 따라서 TLS slot이 고갈되어 VB Runtime TLS 연산에서 crash가 발생하는 경우가 빈번해졌다. 만일, Vista OS 사용한다면, 같이 shipping VB runtime에서는 문제되지 않지만, XP machine이라면 이러한 Crash를 볼 수 있다.

 

최근에 Internet Explorer와 같은 Multiple Threaded 환경에서 ActiveX Control로써 VB 를 사용하는 경우는 확실히 줄었지만, 과거의 Control을 유지 보수하는 차원에서 존재하는 것이라면, VB Runtime에서의 Crash는 당황될 수 있다. 가장 많이 보고 되는 것이 1) vb6ko.dll 이라는 모듈이 System32 Directory에 존재하지 않아서 Crash가 발생하는 경우와 2)TLS Operation에서의 VB runtime에서의 Crash이다. (설마 아직도 IE/VB Control을 Single Threading으로 사용하여 Crash되는 경우가 있을 거라고는 ... 생각치 않는다.) TLS Operation에서의 VB runtime Crash의 경우는 쉽게 Vista OS shipping VB Runtime XP Box copy하여 배포하는 경우도 있고, KB930828에서 제공하는 VB runtime으로 Update 하는 방법이 존재한다. 이 경우는 Microsoft 기술지원부를 Contact해야 하는 번거로움이 존재한다.

 

by 강세윤 | 2009/06/15 17:16 | Windows debugging | 트랙백 | 덧글(0)
< 이전페이지 다음페이지 >