Как проверить COM-объекты из файла дампа Visual Basic?

Фон

У нас есть приложение .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-объектов в файле дампа?


person Paul Williams    schedule 16.05.2012    source источник
comment
Все ли VB6 принадлежат вам или вы также вызываете сторонние COM-объекты?   -  person tcarvin    schedule 17.05.2012
comment
Насколько мне известно, все COM-объекты VB6 принадлежат нам.   -  person Paul Williams    schedule 17.05.2012
comment
Тогда я думаю, что просмотр потоков не даст многого, учитывая, что VB6 не поддерживает многопоточность. Ближе всего это относится к серверам ActiveX, которые поддерживают несколько изолированных STA (однопотоковые апартаменты).   -  person tcarvin    schedule 17.05.2012
comment
Я ошибся — приложение действительно использует движок Microsoft Jet для выполнения некоторых запросов к базе данных. Есть некоторые другие потоки, которые имеют ссылки на DLL двигателя Jet, но они, похоже, ничего не делают.   -  person Paul Williams    schedule 18.05.2012


Ответы (2)


Вы можете сбросить состояние потока с помощью команды:

~*

это не будет отображать «фон» как состояние, вы увидите только «работает», «заморожено» или «приостановлено».

Я не уверен, как вы можете получить информацию из COM-объектов, я никогда не пытался, но расследую и вернусь к вам, что касается модели потоков, будет трудно сделать вывод, что без болезненного мониторинга состояния приложения после прохождения и даже с что, когда вы проходите через все другие потоки, они будут работать, если вы не используете .bpsync 1, который синхронизирует все потоки с текущим, но это может вызвать зависание (например, потоку графического интерфейса теперь было приказано заморозить), поэтому я думаю, что это будет сложно, если вы иметь доступ к исходному коду.

person EdChum    schedule 18.05.2012

Я могу ответить только на вопрос 1. Используйте !runaway, чтобы найти поток или потоки, потребляющие ЦП. Чтобы получить все стеки потоков, используйте ~*kb1000.

person Marc Sherman    schedule 17.05.2012
comment
Я также хотел бы видеть информацию о состоянии потока. Состояние потока: фоновое, запущенное или завершенное. - person Paul Williams; 17.05.2012