Работа в терминальной среде Windows Server 2012 R2 с платформой 1С:Предприятие 8.3.14 часто сопровождается критическими ошибками, когда приложение 1cv8c.exe прекращает взаимодействие с операционной системой. Основная сложность заключается в том, что сессии пользователей невозможно завершить стандартными средствами (через диспетчер задач или утилиту qwinsta), что вынуждает администраторов полностью перезагружать сервер. В этой статье мы подробно разберем причины возникновения "зомби-процессов", проанализируем дампы памяти и найдем эффективные способы решения проблемы.
Первым делом проанализируем типичную запись в журнале событий Windows, которая сопровождает зависание. Ошибка указывает на то, что программа 1cv8c.exe версии 8.3.14.1630 прекратила взаимодействие. Это состояние "Application Hang" (событие с кодом 1002), которое означает, что главный поток приложения перестал отвечать на сообщения системы. Рассмотрим, почему это происходит именно в терминальной среде.
Проанализируем ситуацию, когда процесс нельзя "убить". Это происходит из-за того, что поток зависает в режиме ядра (Kernel Mode). Чаще всего это связано с ожиданием освобождения ресурсов ввода-вывода или блокировками внутри подсистемы COM/DCOM. Когда 1С пытается закрыться, она инициирует процедуру очистки памяти и деинициализации внешних компонент, и именно в этот момент происходит критический сбой.
Для понимания глубинных причин нам необходимо изучить дамп процесса. В предоставленном дампе мы видим следующую последовательность вызовов:
ntdll!NtWaitForMultipleObjects
combase!CGIPTable::RevokeInterfaceInCurrentApartment
combase!CoUninitialize
1cv8c+e583
Разберем этот стек по шагам. Мы видим вызов CoUninitialize — это стандартная процедура завершения работы с COM-объектами. Далее следует RevokeInterface, которая пытается очистить таблицу глобальных интерфейсов. Зависание на функции NtWaitForMultipleObjects говорит о том, что процесс бесконечно ждет ответа от другого объекта или драйвера, который уже недоступен или заблокирован.
Выясним причину такого поведения. В версии 8.3.14.1630 наблюдались серьезные проблемы с управлением дескрипторами GDI и взаимодействием с принтерами через RDP Easy Print. Когда пользователь закрывает 1С, программа пытается сохранить настройки принтера в реестр или кэш. Если в этот момент соединение с перенаправленным принтером нестабильно, вызов COM-объекта "подвисает", блокируя весь процесс завершения сессии.
Одним из самых эффективных способов решения проблемы является замена 32-битного тонкого клиента на 64-битный (x86_64). Рассмотрим преимущества этого подхода:
Если ваши разработчики используют вызовы типа Новый COMОбъект(), это может быть источником проблем. Проанализируем код на наличие явного освобождения объектов. В 1С это делается присваиванием переменной значения Неопределено.
Рассмотрим пример правильного завершения работы с Excel, который часто вызывает зависание сессий:
Попытка
Excel = Новый COMОбъект("Excel.Application");
// ... работа с файлом
Excel.Quit();
Исключение
Сообщить("Ошибка работы с COM");
КонецПопытки;
Excel = Неопределено;
Важно помнить, что если объект не был явно уничтожен до закрытия основной формы 1С, платформа попытается сделать это принудительно, что и приводит к конфликтам в combase.dll, которые мы видели в дампе.
Поскольку проблема воспроизводится на Windows Server 2012 R2, нам необходимо внести коррективы в работу системных служб. Рассмотрим по шагам, что нужно сделать системному администратору:
AeLookupSvc может блокировать закрытие 1cv8c.exe, пытаясь применить патчи совместимости в момент выхода. Отключите её через оснастку "Службы".Конфигурация компьютера -> Административные шаблоны -> Компоненты Windows -> Службы удаленных рабочих столов -> Узел сеансов удаленных рабочих столов -> Ограничения сеансов по времени. Установите параметр "Завершать отключенный сеанс" в значение "1 минута".Выясним, можно ли повлиять на стабильность через параметры запуска платформы. Рассмотрим использование специальных ключей в ярлыке запуска 1С.
Иногда помогает отключение аппаратного ускорения графики, которое в терминальной среде работает нестабильно. Добавьте в строку запуска параметр:
/NoPrefferedGraphicsAdapter
Также стоит попробовать запуск тонкого клиента без предварительной установки (из сетевого каталога). Это позволяет избежать использования зарегистрированных в системе библиотек, которые могут конфликтовать с версиями 8.2 или 8.3.12, установленными на сервере.
Если вышеописанные методы не помогают, нам придется включить детальное логирование. Создадим файл logcfg.xml в каталоге C:\Program Files (x86)\1cv8\conf. Рассмотрим пример конфигурации для отслеживания завершения работы и ошибок:
<config xmlns="http://v8.1c.ru/7.4/config">
<log location="C:\LOGS\1C" history="24">
<event>
<eq property="Name" value="EXCP"/>
</event>
<event>
<eq property="Name" value="PROC"/>
</event>
<property name="All"/>
</log>
</config>
Событие PROC позволит нам увидеть момент старта и завершения процесса, а EXCP зафиксирует все исключения, которые происходят "под капотом" платформы, даже если они не выводятся пользователю на экран.
Важное примечание: Версия 8.3.14 признана многими специалистами переходной и достаточно нестабильной. Если инфраструктура позволяет, наиболее правильным долгосрочным решением будет переход на стабильные релизы веток 8.3.17 или выше, где ошибки взаимодействия с подсистемой COM и утечки GDI-объектов были исправлены разработчиками платформы.