Фон
У нас есть приложение .NET WinForms, написанное на C#, которое взаимодействует с портативным сканером магазина через консольное приложение. Консольное приложение написано на старом добром VB6 — там нет управляемого кода. Приложение VB6 состоит из нескольких COM-объектов.
Приложение .NET WinForms обновляет данные в сканере, вызывая консольное приложение с правильными параметрами. При запуске консольного приложения появляется модальная форма, напоминающая пользователю о том, что нужно поместить карманное устройство в подставку.
Проблема
У клиента возникла странная ситуация, когда вызов запуска консольного приложения зависает до того, как отобразится форма напоминания. Если пользователь нажимает любую клавишу — даже что-то невинное, например, Shift или Alt — приложение размораживается, и появляется форма напоминания. Пока оно зависает, использование ЦП консольным приложением очень велико.
Мы получили дамп памяти из приложения командной строки с помощью ProcDump. У меня есть некоторый опыт отладки файлов управляемых дампов, но этот дамп VB 6 мне кажется странным.
Мы захватили несколько полных дампов памяти подряд. В некоторых из них есть стеки клея COM. Например, несколько файлов дампа показывают такой стек вызовов:
msvbm60!BASIC_DISPINTERFACE_GetTICount
msvbm60!_vbaStrToAnsi
msvbm60!IIDIVbaHost
msvbm60!rtcDoEvents
msvbm60!IIDIVbaHost
msvbm60!BASICCLASS_QueryInterface
[our code which I think is trying to create and invoke a COM object]
Не помогает то, что единственные символы, которые у меня есть, взяты из нашего кода. Сервер символов Microsoft не имеет PDB-файла для msvbm60.dll (по крайней мере, не из их версии 6.0.98.2).
Вопросы
Я подозреваю, что может быть какая-то проблема с потоками COM, которая происходит только в их системе.
1) Как я могу определить состояние каждого потока в файле дампа? Если бы это был управляемый файл дампа, я бы посмотрел на !threads
, а затем на !threadstate
, чтобы выяснить состояния потоков. Управляемого кода нет, поэтому я не могу использовать sos.dll. Я не видел никаких подсказок с использованием ~
и !teb
.
2) Есть ли способ увидеть, какие COM-объекты были созданы в файле дампа? Опять же, в управляемом дампе я могу выполнить !dumpheap
, чтобы получить список управляемых объектов. Есть ли что-то подобное, что я могу найти для COM-объектов?
3) Могу ли я определить поточную модель COM-объектов в файле дампа?