Рассмотрим крайне неприятную и загадочную проблему, с которой рано или поздно сталкивается любой разработчик на платформе 1С:Предприятие 8. Представьте ситуацию: вы отлаживаете код (например, фоновое задание по формированию статистики в конфигурации 1С:Управление торговлей), пошагово проходите процедуру, и вдруг на абсолютно рядовой строке, где нет никакого оператора Возврат или явного вызова исключения, отладчик прекращает выполнение текущей функции и «выбрасывает» вас из неё. При этом сама программа продолжает выполняться корректно, данные рассчитываются, и никаких видимых ошибок в журнале регистрации не фиксируется.
В этой статье мы подробно разберем, почему возникает этот эффект «магического» исчезновения указателя отладки, проанализируем внутренние механизмы платформы 1С и изучим все возможные методы решения — от простых до продвинутых.
Выясним первопричину этой мистики. Имя этому явлению в кругу профессиональных разработчиков — последствия так называемого «демонического» (динамического) обновления конфигурации.
Когда мы выполняем обновление информационной базы в режиме «динамически», платформа 1С записывает новые метаданные и исходные коды в базу данных. Однако активные сеансы пользователей и, что важнее, рабочие процессы сервера 1С (rphost) продолжают использовать скомпилированный байт-код старой версии конфигурации, который уже загружен в их оперативную память и кэш.
В момент запуска отладки возникает серьезный конфликт систем:
rphost) выполняет старый скомпилированный байт-код, в котором количество строк, их порядок и даже состав процедур могут отличаться.В результате, когда сервер выполняет старый код, в котором функция уже завершилась (или была короче), отладчик в Конфигураторе визуально перескакивает строки, останавливается на комментариях или пустых областях, либо внезапно «выбрасывает» вас из функции, как будто сработал невидимый оператор Возврат.
Проанализируем, почему именно фоновые задания чаще всего страдают от этой проблемы.
Серверный кластер 1С распределяет нагрузку по нескольким рабочим процессам rphost. При динамическом обновлении часть процессов может частично обновить свой кэш, а часть останется со старыми данными в оперативной памяти. Фоновые задания могут запускаться на разных рабочих процессах. Если задание попало на процесс со старым кэшем метаданных, вы гарантированно получите описанный сдвиг строк при попытке отладки.
Кроме того, если в базе параллельно выполняются другие фоновые процессы, автоматическое подключение отладчика может среагировать на чужой поток, из-за чего у разработчика возникнет ложное ощущение «вылета» из текущего сеанса отладки.
Это самый надежный и проверенный временем метод, который полностью устраняет любые проблемы с рассинхронизацией кода.
Разберем по шагам, как правильно выполнить эту процедуру на сервере:
1С:Предприятие. В операционной системе Windows это делается через оснастку «Службы» (служба 1C:Enterprise 8.3 Server Agent).C:\Program Files\1cv8\srvinfo или C:\ProgramData\1C\1cv8).reg_1541) и удалите внутри неё все временные кэш-каталоги. Это папки с длинными шестнадцатеричными именами вроде snccntry..., а также временные файлы сессий. Внимание! Не удаляйте файлы конфигурации кластера (1CV8Reg.lst).После перезапуска сервер будет вынужден заново скомпилировать байт-код для всех модулей актуальной конфигурации, и проблема с отладкой исчезнет.
Если база находится в рабочем режиме и останавливать службу сервера нельзя, мы можем временно заставить код выполняться синхронно, в рамках нашего текущего клиентского сеанса. Это стандартная практика при использовании инструментов Библиотеки Стандартных Подсистем (БСП).
Проанализируем пример кода. Обычно фоновое задание запускается через общий модуль длительных операций. Изменим параметры запуска следующим образом:
// Создаем параметры выполнения длительной операции
ПараметрыВыполнения = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
// Временно переопределяем свойства для отладки в текущем сеансе
ПараметрыВыполнения.ЗапуститьВФоне = Ложь;
ПараметрыВыполнения.ЗапуститьНеВФоне = Истина;
// Запускаем операцию - теперь код выполнится синхронно в тонком/толстом клиенте
Результат = ДлительныеОперации.ВыполнитьВФоне("МойМодуль.СформироватьСтатистикуПоставщика", ПараметрыПроцедуры, ПараметрыВыполнения);
Благодаря этому приёму отладчик не будет переключаться на фоновые потоки сервера, а пошаговое выполнение пройдет плавно и без сдвигов строк, так как сеанс клиента гарантированно использует актуальные метаданные.
Если вам нужно быстро «оживить» отладку конкретной функции без перезапуска всего сервера, можно заставить платформу принудительно перекомпилировать только этот измененный модуль.
Разберем этот простой, но эффективный трюк по шагам:
Платформа зафиксирует изменение контрольной суммы модуля, определит, что его исходный текст изменился, и принудительно обновит скомпилированный байт-код в оперативной памяти всех рабочих процессов rphost при первом же обращении к любой функции этого модуля. После этого отладчик снова начнет точно попадать в строки.
Иногда ложные вылеты происходят из-за того, что отладчик автоматически подцепляет фоновые процессы других пользователей, работающих в этой же базе. Чтобы этого избежать, настроим фильтрацию предметов отладки:
Применяя эти методы на практике, вы навсегда избавитесь от загадочных явлений при отладке и сэкономите массу времени при локализации ошибок в сложных серверных механизмах.