Почему при отладке в 1С параметры сеанса инициализируются «сами» и не срабатывают точки останова?

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

Каждый разработчик 1С рано или поздно сталкивается с ситуациями во время отладки, которые буквально «взрывают мозг». Одна из таких классических загадок — странное поведение платформы «1С:Предприятие» при попытке отладить процедуру УстановкаПараметровСеанса в модуле сеанса. Вы ставите точку останова в самом начале процедуры, пытаетесь посмотреть значение параметра через окно «Вычислить выражение» (Shift + F9), а он уже инициализирован! При этом точка останова в коде инициализации просто игнорируется.

Давайте подробно разберем, почему так происходит, как устроена внутренняя кухня платформы 1С и какими методами можно обойти этот «эффект наблюдателя» при отладке.

В чем суть проблемы? Классический сценарий

Представим стандартную ситуацию. Мы изучаем конфигурацию (например, «Библиотеку стандартных подсистем» — БСП) и хотим пошагово проследить, как при старте системы заполняется параметр сеанса ТекущийПользователь. Для этого мы выполняем следующие шаги:

  1. Открываем модуль сеанса и находим предопределенную процедуру УстановкаПараметровСеанса.
  2. Ставим точку останова на первой же строчке этой процедуры.
  3. Запускаем систему в режиме отладки.
  4. Отладчик успешно перехватывает управление и останавливается на нашей точке. На этом этапе параметры сеанса еще не должны быть инициализированы.
  5. Мы нажимаем Shift + F9 (или открываем панель «Табло») и вводим выражение ПараметрыСеанса.ТекущийПользователь, чтобы убедиться, что там пусто.
  6. Сюрприз! Платформа возвращает заполненное значение (например, ссылку на справочник «Пользователи» — Администратор). При этом в коде, который отвечает за заполнение этого пользователя, мы не останавливались.

Создается ощущение мистики: код инициализации физически выполнился (это легко проверить, если вставить в процедуру запись лога в текстовый файл), но отладчик проигнорировал точку останова в модуле установки этого параметра. Давайте выясним истинную причину этого явления.

Причина №1: Инициализация «по требованию» (Lazy Initialization)

Для оптимизации производительности и экономии серверной памяти платформа «1С:Предприятие» использует механизм отложенной (ленивой) инициализации параметров сеанса. Они не создаются все скопом в момент авторизации пользователя.

Когда система стартует, инициализируются только самые базовые системные механизмы. Любые прикладные параметры сеанса (такие как текущий пользователь, организация по умолчанию, настройки прав доступа RLS) остаются «пустыми» до тех пор, пока к ним не обратится какой-либо участок кода.

Как только в коде происходит обращение вида:

ТекущийПользовательСистемы = ПараметрыСеанса.ТекущийПользователь;

Платформа понимает, что параметр еще не определен, приостанавливает выполнение текущего потока и автоматически вызывает процедуру УстановкаПараметровСеанса в модуле сеанса, передавая в нее имя запрашиваемого параметра.

Причина №2: «Эффект наблюдателя» и блокировка точек останова

Когда мы останавливаемся в самом начале процедуры УстановкаПараметровСеанса, сам параметр ТекущийПользователь еще действительно не инициализирован. Но как только мы нажимаем Shift + F9 и просим отладчик вычислить выражение ПараметрыСеанса.ТекущийПользователь, мы сами принудительно инициируем обращение к нему!

Платформа послушно пытается вычислить это выражение на сервере. Так как параметр не инициализирован, она неявно (в фоновом режиме) запускает процедуру УстановкаПараметровСеанса.

Но почему же тогда не срабатывает точка останова внутри этой процедуры?

Это важнейший защитный механизм платформы 1С. Вычисление выражений в отладчике (через «Табло» или Shift + F9) происходит в реальном контексте исполнения, но с жестким ограничением: при выполнении кода, инициированного самим отладчиком, все точки останова временно блокируются.

Если бы платформа этого не делала, возникла бы бесконечная рекурсия (так называемый dead-lock):

  1. Отладчик пытается вычислить параметр сеанса.
  2. Для этого вызывается код инициализации.
  3. В коде инициализации срабатывает точка останова.
  4. Отладчик снова пытается обновить значения в Табло, опять вызывая этот же код.
  5. Программа намертво зависает или аварийно завершается из-за переполнения стека.

Именно поэтому при вычислении выражения код инициализации выполняется «втихую». Он отрабатывает, записывает данные в файлы, если это прописано в коде, заполняет параметр сеанса, но интерфейс конфигуратора никак не выдает этот процесс разработчику. А когда вы закрываете окно оценки выражения и нажимаете F8 (Шагнуть обойти), параметр сеанса уже инициализирован, и повторно процедура инициализации для него вызываться не будет.

Как проверить эту особенность экспериментально?

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

Добавьте в процедуру инициализации конкретного параметра сеанса (или в общий модуль, который им занимается) следующий код:


лТекст = Новый ТекстовыйДокумент;
лТекст.ДобавитьСтроку("Процедура инициализации вызвана неявно!");
лТекст.Записать("C:\temp\debug_log.txt");

Установите точку останова на вызове этой процедуры. Запустите отладку. При остановке в модуле сеанса проверьте папку C:\temp\ — файла там еще нет. Теперь нажмите Shift + F9 и вычислите значение проверяемого параметра сеанса. Точка останова внутри общего модуля не сработает, однако на диске мгновенно появится файл debug_log.txt. Это прямое доказательство того, что код выполнился в обход механизмов отладки.

Рекомендации: как правильно отлаживать параметры сеанса

Чтобы процесс отладки не превращался в хаос, а переменные не инициализировались в самый неподходящий момент, мы рекомендуем придерживаться нескольких простых правил.

1. Очищайте «Табло» перед началом отладки

Панель «Табло» (вызывается по сочетанию клавиш Ctrl + Alt + W) вычисляет добавленные в нее выражения автоматически на каждом шаге отладки (при каждом нажатии F8, F7 или F5). Если вы случайно оставите там строку ПараметрыСеанса.ИмяПараметра, отладчик незаметно для вас инициализирует этот параметр при первом же шаге программы, заблокировав точки останова в коде инициализации.

Перед началом сессии отладки модуля сеанса всегда полностью очищайте список вычисляемых выражений в Табло.

2. Анализируйте входящий параметр ИменаПараметровСеанса

Предопределенная процедура УстановкаПараметровСеанса(ИменаПараметровСеанса) принимает на вход массив имен параметров, которые платформа требует инициализировать прямо сейчас.

Если вы хотите понять, какой именно параметр затребовал код, не запрашивайте сами параметры сеанса напрямую. Вместо этого в окне Shift + F9 анализируйте значение переменной ИменаПараметровСеанса. Это безопасно, так как чтение локального массива не вызывает побочных эффектов инициализации на сервере.

3. Используйте режим «Остановка по ошибке»

Иногда требуется поймать момент, когда некий неизвестный модуль пытается прочитать еще не инициализированный параметр сеанса. Чтобы локализовать эту строку кода, выполните следующие действия:

  1. В главном меню Конфигуратора перейдите в раздел Отладка -> Остановка по ошибке...
  2. Установите флажок Останавливаться по ошибке.
  3. Попытка прочесть неинициализированный параметр вызывает внутреннее исключение платформы (ошибку чтения). Отладчик мгновенно приостановит выполнение ровно на той строке кода, которая инициировала некорректное обращение, позволяя вам изучить стек вызовов.

4. Используйте «Замер производительности»

Если интерактивный отладчик слишком сильно искажает логику работы системы из-за «эффекта наблюдателя», воспользуйтесь механизмом замера производительности:

  1. Запустите приложение в режиме отладки.
  2. В Конфигураторе выберите меню Отладка -> Замер производительности (включите его непосредственно перед началом критического участка кода).
  3. Выполните действие в пользовательском режиме (например, авторизацию или открытие формы).
  4. Отключите замер производительности.

В открывшейся таблице вы увидите абсолютно чистую хронологию вызовов функций без какого-либо вмешательства со стороны окон просмотра выражений. Вы сможете точно определить, какие процедуры общего модуля вызывались, сколько раз и в какой последовательности.

Понимание этих архитектурных особенностей платформы «1С:Предприятие» сбережет вам массу времени и нервов при анализе сложных конфигураций!

← На главную