Исключение COM на "пользовательский компонент" - как определить DLL?

У нас есть большое унаследованное приложение VB, состоящее из нескольких библиотек DLL (несколько десятков или около того), установленных в одном приложении сервера COM+. Время от времени происходит что-то, что вызывает dllhost.exe киль (и автоматический перезапуск), оставляя это сообщение в журнале событий приложений Windows...

Система вызвала пользовательский компонент, и этот компонент вышел из строя и сгенерировал исключение. Это указывает на проблему с пользовательским компонентом. Сообщите разработчику этого компонента о сбое и предоставьте ему информацию ниже.
Идентификатор серверного приложения: {8CC02F18-2733-4A17-9E5C-1A70CB6B6977}
Идентификатор экземпляра приложения сервера: {1940A147-8A5E-45FA-86FE-DAF92A822597}
Имя приложения сервера: MyTestApp
Серьезный характер этой ошибки привел к прекращению процесса.
Исключение: C0000005
Адрес: 0x758DA3DA

Источник: Complus
Код события: 4786
Уровень: Ошибка

Наряду с этим это еще один журнал, в частности, на dllhost.exe...

Неверное имя приложения: dllhost.exe, версия: 6.0.6000.16386, отметка времени: 0x4549b14e
Неверное имя модуля: msvcrt.dll, версия: 7.0.6002.18005, отметка времени: 0x49e0379e.
Код исключения: 0xc0000005
Смещение ошибки: 0x0000a3da
Идентификатор ошибочного процесса: 0x83c
Время запуска ошибочного приложения: 0x01cb50c507ee0166
Неверный путь к приложению: %11
Неверный путь к модулю: %12
Идентификатор отчета: %13

Я знаю, что это указывает на ошибку во время выполнения C (msvcrt), но в идеале мне нужно проследить это обратно в DLL, которая вызывается в msvcrt (возможно, с неверными данными / параметрами). Итак, без установки отладчика, есть ли способ определить DLL, которая вызывает это? Я пытаюсь увидеть, есть ли где-нибудь дамп памяти, который я могу использовать для анализа в автономном режиме - и, таким образом, привязать адрес к чему-то конкретному. Но без этого я не уверен, что это возможно. Может ли подсистема COM получить минимальный дамп при сбое размещенного приложения? (да, это возможно [возможно] - на вкладке "Дамп" есть флажок).

Это на Windows Server 2008 R1 32-битный (но также будет интересен и для Server 2003).

Это не влияет на доступность приложения - COM+ просто перезапускает dllhost, и приложение продолжается, но это неудобство, которое было бы полезно исправить.

Ладно, у меня аварийная свалка, у меня виндбг, но это не помогает. Не уверен, что я толстый (возможно) или что-то еще:-) Вывод !analyze -v ниже, но он ничего не показывает в наших DLL, хотя похоже, что он не смог разрешить FAULTING_IP? Я не уверен, куда обратиться дальше.

Мне интересно, являются ли какие-либо из моих pdb унылыми и стоит создавать новые - подключенные к серверу символов Microsoft, поэтому они не должны быть, но не уверены, для какого модуля он (очевидно) сообщает о неправильных символах для (BUGCHECK_STR и PRIMARY_PROBLEM_CLASS) (или эти символы находятся на сервере, на котором изначально выполнялся код?). Было бы лучше разместить PDB на самом сервере?

Если нет, то есть другие идеи? Раньше я кратко использовал windbg, но я не являюсь его постоянным пользователем, так что, может быть, есть еще заклинания, которые мне нужно набрать, чтобы копать глубже? Руководство приветствуется:-)

*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

FAULTING_IP: 
+5c112faf02e0d82c
00000000 ??              ???

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 00000000
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 0

FAULTING_THREAD:  00000f1c
DEFAULT_BUCKET_ID:  WRONG_SYMBOLS
PROCESS_NAME:  dllhost.exe
ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION}  Breakpoint  A breakpoint has been reached.
EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - One or more arguments are invalid
MOD_LIST: <ANALYSIS/>
NTGLOBALFLAG:  0
APPLICATION_VERIFIER_FLAGS:  0
MANAGED_STACK: !dumpstack -EE
OS Thread Id: 0xf1c (0)
Current frame: 
ChildEBP RetAddr  Caller,Callee

LAST_CONTROL_TRANSFER:  from 77b15620 to 77b15e74
PRIMARY_PROBLEM_CLASS:  WRONG_SYMBOLS
BUGCHECK_STR:  APPLICATION_FAULT_WRONG_SYMBOLS

STACK_TEXT:  
0022fa68 77b15620 77429884 00000064 00000000 ntdll!KiFastSystemCallRet
0022fa6c 77429884 00000064 00000000 00000000 ntdll!NtWaitForSingleObject+0xc
0022fadc 774297f2 00000064 ffffffff 00000000 kernel32!WaitForSingleObjectEx+0xbe
0022faf0 778e2c44 00000064 ffffffff 00e42374 kernel32!WaitForSingleObject+0x12
0022fb0c 778e2e32 00060848 0022fb5b 00000000 ole32!CSurrogateProcessActivator::WaitForSurrogateTimeout+0x55
0022fb24 00e413a4 0022fb40 00000000 00061d98 ole32!CoRegisterSurrogateEx+0x1e9
0022fcb0 00e41570 00e40000 00000000 00061d98 dllhost!WinMain+0xf2
0022fd40 7742d0e9 7ffde000 0022fd8c 77af19bb dllhost!_initterm_e+0x1a1
0022fd4c 77af19bb 7ffde000 dc2ccd29 00000000 kernel32!BaseThreadInitThunk+0xe
0022fd8c 77af198e 00e416e6 7ffde000 ffffffff ntdll!__RtlUserThreadStart+0x23
0022fda4 00000000 00e416e6 7ffde000 00000000 ntdll!_RtlUserThreadStart+0x1b

STACK_COMMAND:  .cxr 00000000 ; kb ; dt ntdll!LdrpLastDllInitializer BaseDllName ; dt ntdll!LdrpFailureData ; ~0s; .ecxr ; kb

FOLLOWUP_IP: 
dllhost!WinMain+f2
00e413a4 ff15a410e400    call    dword ptr [dllhost!_imp__CoUninitialize (00e410a4)]

SYMBOL_STACK_INDEX:  6
SYMBOL_NAME:  dllhost!WinMain+f2
FOLLOWUP_NAME:  MachineOwner
MODULE_NAME: dllhost
IMAGE_NAME:  dllhost.exe
DEBUG_FLR_IMAGE_TIMESTAMP:  4549b14e
FAILURE_BUCKET_ID:  WRONG_SYMBOLS_80000003_dllhost.exe!WinMain
BUCKET_ID:  APPLICATION_FAULT_WRONG_SYMBOLS_dllhost!WinMain+f2

2 ответа

Решение

У вас есть символы для VB DLL? Символы важны для получения стека вызовов. Я надеюсь, у вас есть правильные символы. Ты можешь использовать ld * а потом lme который должен получить список символов, которые не совпадают в пределах windbg. Также установите путь к символам для символов MS, а также для своего пользовательского кода, используя _NT_SYMBOL_PATH

Один из самых простых вариантов - загрузить дамп в DebugDiag, который должен дать вам причину сбоя вместе со стеком вызовов. DebugDiag имеет расширения отладчика для Complus.

И вот команда родного стека вызовов для всех потоков

~*ek

и этот один переключиться на текущее исключение

.ecxr

Отладка Mon / WinDbg - лучший способ устранить эту проблему. у вас должна быть возможность использовать список модулей в winDbg или команду lm для просмотра списка загруженных модулей. Затем трассировка стека должна сказать вам, какие библиотеки задействованы. Это должно быть возможно даже без символов для процесса / DLL.

Другие вопросы по тегам