Почему падает серверный процесс rphost при выгрузке данных и возникает переполнение стека

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом IT и автоматизация бизнеса
← На главную

При выполнении обмена данными или выгрузке объектов с помощью универсальных механизмов обмена (например, подсистемы «Конвертация данных 2.x») разработчики нередко сталкиваются с аварийным завершением серверного рабочего процесса rphost. При этом в сеансе пользователя появляется сообщение об ошибке выхода из серверной процедуры или исключение вида «Переполнение стека встроенного языка на сервере», а на файлах базы или временных таблицах зависают блокировки.

Разберем детально, почему это происходит, как локализовать проблемный участок и какие настройки правил обмена позволяют устранить бесконечную рекурсию.

Причины падения процесса rphost и переполнения стека

Платформа 1С:Предприятие выделяет фиксированный объем стековой памяти для каждого потока выполнения серверного процесса. Если глубина вызовов функций встроенного языка превышает допустимый лимит, операционная система принудительно завершает поток с кодом исключения переполнения стека (0xC00000FD), что влечет за собой аварийную остановку всего рабочего процесса rphost.

Проанализируем основные источники данной проблемы при выгрузке по правилам:

  1. Циклические ссылки в данных. Документы учета (особенно кадровые и расчетные, такие как ВозвратИзОтпускаПоУходуЗаРебенком или Отпуск) часто содержат ссылки друг на друга через реквизиты «Документ-основание», исправления или сторнирования. Выгружая первый документ, обработка инициирует выгрузку зависимого, а тот в свою очередь снова тянет исходный документ.
  2. Автоматический выбор правила конвертации (ПКО). Если в правиле конвертации свойства (ПКС) для ссылочного реквизита не задано конкретное «облегченное» правило, платформа автоматически применяет основное ПКО по типу значения. В результате выгружается весь сложный объект целиком со всеми табличными частями и ссылками вместо обычной ссылки.
  3. Отключение кэширования выгруженных объектов. Если в настройках выгрузки или правилах нарушен механизм запоминания уже обработанных ссылок, алгоритм многократно пытается заново выгрузить один и тот же объект, порождая лавинообразный рост стека вызовов.

Способы локализации зацикливания

Когда стандартная отладка прерывается падением сервера, выясним причину и конкретное место зацикливания следующими методами:

  1. Тестирование в файловой базе. Выполним ту же выгрузку в файловой информационной базе под толстым клиентом. В файловом режиме платформа обычно успевает выдать стандартное диалоговое окно с полным стеком вызовов функций, где видны повторяющиеся правила обмена.
  2. Добавление отладочного счетчика глубины. Откроем обработку выгрузки (модуль «Универсальный обмен данными в формате XML») и добавим проверку максимального уровня рекурсии в процедуру ВыгрузитьПоПравилу:

// В обработчике или модуле выгрузки
Если Параметры.СчетчикГлубины > 100 Тогда
    ЗаписьЖурналаРегистрации("ОшибкаВыгрузки", 
        УровеньЖурналаРегистрации.Ошибка, , , 
        "Превышена глубина выгрузки для объекта: " + Строка(мДок));
    ВызватьИсключение "Обнаружена циклическая ссылка при выгрузке!";
КонецЕсли;
  1. Настройка технологического журнала. На сервере 1С настроим сбор событий EXCP и PROC. Это позволит зафиксировать контекст выполнения перед аварийным падением процесса.

Методы устранения циклических ссылок в правилах обмена

Рассмотрим, как правильно настроить правила конвертации данных (КД 2.x), чтобы избежать рекурсивных вызовов:

  1. Создание специализированных облегченных ПКО. Для реквизитов, указывающих на связанные документы (например, документ-основание), создадим отдельное правило конвертации. В нем снимем флаги выгрузки всех табличных частей и лишних реквизитов, оставив только поля поиска (номер, дата, организация). Это правило явно укажем в ПКС основного объекта.
  2. Использование режима выгрузки только ссылки. В обработчике «Перед выгрузкой» свойства или правила можно принудительно указать выгрузку ссылки без анализа свойств самого объекта:

// Обработчик "Перед выгрузкой" для ссылочного реквизита
ТолькоПолучитьУзелСсылки = Истина;
  1. Контроль флага запоминания выгруженных объектов. Убедимся, что для ссылочных типов включено кэширование и регистрация выгруженных объектов в служебных таблицах обмена, чтобы платформа не обрабатывала повторно ранее сериализованные ссылки.
  2. Разрыв взаимных зависимостей. Проверим встречные ПКС: если документ «А» выгружает документ «Б», то в правиле выгрузки документа «Б» свойство, ссылающееся обратно на документ «А», должно выгружаться исключительно по ссылке без рекурсивного разбора.
← На главную