Каждый разработчик на платформе «1С:Предприятие» рано или поздно сталкивается с ситуацией, которая способна вызвать настоящий когнитивный диссонанс. Вы запускаете пошаговую отладку, доходите до простейшего условия вида Если ... Тогда, вычисляете выражение в табло — оно возвращает Истина. Однако при нажатии клавиши F11 (шагнуть вглубь) желтая стрелка отладчика демонстративно перепрыгивает исполняемый блок кода и уходит в ветку Иначе или вообще за пределы условия.
Давайте подробно разберем, почему возникает этот мистический баг, как устроена работа кэша метаданных в «1С:Предприятие» и какими способами можно быстро вернуть систему в рабочее состояние без радикальных мер вроде переустановки платформы.
Проанализируем классическую ситуацию, описанную на одном из форумов. Разработчик написал простую процедуру печати ценников или этикеток, где передается необязательный параметр КоличествоБыстройПечати:
Процедура Печать(ТаблицаТоваров, КоличествоБыстройПечати = Неопределено) Экспорт
// ... некоторый код ...
Если ЗначениеЗаполнено(КоличествоБыстройПечати) тогда
КоличествоКопий = КоличествоБыстройПечати;
Иначе
КоличествоКопий = СтрокаИзСписка.Количество;
КонецЕсли;
Для Копий = 1 По КоличествоКопий Цикл
// ... выполнение печати ...
КонецЦикла;
КонецПроцедуры
При тестировании кода на рабочем компьютере отладчик показывает, что переменная КоличествоБыстройПечати равна двум (числовое значение). Функция ЗначениеЗаполнено() при вычислении в табло честно возвращает значение Истина. Но строка КоличествоКопий = КоличествоБыстройПечати; упорно игнорируется платформой. При этом на другой машине, где развернута та же самая база данных, всё отрабатывает абсолютно корректно.
Почему так происходит? Ответ кроется в понятии рассинхронизации локального кэша метаданных и исполняемого байт-кода. Этот эффект программисты 1С часто называют «эффектом призрачного кода» или «смещением строк в отладчике».
Когда мы запускаем сеанс «1С:Предприятие» в режиме отладки, платформа выполняет компиляцию модулей конфигурации в промежуточный байт-код. Для ускорения последующих запусков этот скомпилированный код кэшируется локально на компьютере пользователя.
В то же время конфигуратор отображает актуальный текстовый исходный код модуля, хранящийся в базе данных. В нормальном режиме работы эти сущности синхронизированы. Но при определенных сбоях или специфических сценариях обновления синхронизация нарушается:
1cv8.exe) локальные индексы кэша повреждаются, и платформа перестает понимать, что исходный код обновился.В процессе обсуждения проблемы на форуме автор попытался очистить кэш вручную, удалив файлы по пути:
C:\Users\ИмяПользователя\AppData\Roaming\1C\1cv8
Но эта процедура не принесла результата. Давайте разберем, почему этот шаг оказался неэффективным. Дело в том, что платформа 1С разделяет временные данные на две категории и хранит их в разных системных каталогах операционной системы Windows:
%APPDATA%\1C\1cv8 (или в развернутом виде C:\Users\[ИмяПользователя]\AppData\Roaming\1C\1cv8). Здесь хранятся пользовательские настройки интерфейса, история выбора, расположение окон, сохраненные настройки отчетов и диалогов. Удаление этой папки сбрасывает только персональные настройки интерфейса конкретного пользователя, но никак не влияет на исполняемый код программных модулей.%LOCALAPPDATA%\1C\1cv8 (или C:\Users\[ИмяПользователя]\AppData\Local\1C\1cv8). Именно здесь хранятся файлы конфигураций баз данных, скомпилированные программные модули, кэш форм и метаданные. Если не очистить этот каталог, все сбойные скомпилированные модули останутся на компьютере и платформа продолжит их использовать.Именно поэтому автору помогла только полная переустановка клиента 1С — программа удаления просто зачистила все связанные с ней временные директории, включая скрытый локальный кэш в папке Local.
Чтобы восстановить корректную работу отладчика и устранить «когнитивный диссонанс» при отладке кода, можно применить несколько гораздо более простых и быстрых способов.
Рекомендуется выполнять эту процедуру при закрытых сеансах 1С. Мы должны очистить обе временные папки. Давайте сделаем это по шагам:
%LOCALAPPDATA%\1C\1cv8. Нажмите Enter.2c9a34b2-e1d4-4a41-b121...). Это и есть кэш конкретных информационных баз. Выделите и удалите все папки с подобными именами. Не трогайте только файлы настроек платформы (если они там есть, например, 1cestart).%APPDATA%\1C\1cv8, чтобы удалить пользовательские настройки, которые также могли повредиться.Это самый быстрый и изящный способ, не требующий поиска скрытых системных папок на диске C:. Механизм работы платформы устроен так, что локальный кэш привязывается к уникальному идентификатору (UUID) базы в списке запуска на конкретном компьютере.
Проанализируем этот алгоритм:
При этом база получит абсолютно новый UUID в системе. Платформа создаст для нее чистые папки кэша в каталогах Local и Roaming, а старый зависший кэш просто останется лежать мертвым грузом (его можно будет позже удалить вручную) и больше не повлияет на работу вашей программы.
Если вы часто ведете разработку в условиях динамических обновлений, имеет смысл настроить автоматическую очистку кэша при каждом запуске программы:
/ClearCache.Теперь при каждом открытии базы в режиме «Предприятие» платформа будет принудительно очищать кэш клиентских метаданных. Обратите внимание, что это может незначительно увеличить время открытия программы, зато полностью застрахует вас от «призрачного кода» при отладке.
Если сбой произошел непосредственно в процессе отладки конкретного общего модуля или модуля документа, можно заставить платформу принудительно перекомпилировать его:
// фиктивное изменение для обновления кэша.Это действие заставит платформу обновить контрольную сумму модуля. При следующем запуске сеанса отладки система увидит несоответствие версий и скомпилирует модуль заново, устранив смещение строк в отладчике.
Что делать, если проблемный код выполняется на стороне сервера (например, в общем модуле с установленным флагом Вызов сервера или в модуле менеджера объекта), и очистка локального кэша на компьютере разработчика не помогает?
В этом случае старый байт-код заблокирован в оперативной памяти сервера приложений «1С:Предприятие». Помогут следующие действия системного администратора:
ragent) через консоль служб Windows или с помощью скрипта.Мы выяснили истинную причину «мистического» поведения платформы, когда правильное и логичное условие в коде игнорировалось отладчиком. Проблема крылась в устаревшем локальном кэше метаданных, который не обновился из-за использования динамического обновления конфигурации.
Для предотвращения подобных ситуаций в будущем рекомендуется придерживаться простых правил:
Roaming и Local в каталоге пользователя Windows. Помните, что исполняемый кэш компилятора живет именно в папке Local.