1C-CodeОсновы 1С → Отладка: как искать причину

Отладка: как искать причину

Навык, который отличает того, кто чинит за десять минут, от того, кто чинит за день. Точки останова, замер и порядок поиска.

Глава 36 из 36 · чтение примерно 22 минут

Задача «не считается скидка» решается не знанием языка, а умением найти место, где всё пошло не так.

Начинающий читает код глазами и гадает. Опытный ставит точку останова и смотрит. Разница во времени — десятки раз.

Порядок, который работает всегда

1. Повторить. Пока ошибка не воспроизводится по шагам, чинить нечего: вы не узнаете, починили ли. Первый вопрос пользователю — «что вы нажали».

2. Сузить. Не «не работает отчёт», а «не работает на этом складе за этот месяц». Каждое уточнение выбрасывает половину кода из подозреваемых.

3. Найти место. Точка останова, а не чтение глазами.

4. Понять, а потом чинить. Правка, сделанная до понимания, лечит симптом и оставляет причину.

Точки останова

Отладчик конфигуратора останавливает выполнение на нужной строке и показывает значения всех переменных.

Условная точка останова — срабатывает, только когда условие истинно. В цикле по тысяче строк это единственный способ добраться до нужной, не нажимая «продолжить» тысячу раз.

Отладка фоновых заданий и сервера включается отдельно в настройках сервера и конфигуратора. Пока не включена, точки в серверном коде не срабатывают — и это первая причина недоумения «почему не останавливается».

Когда отладчик не поможет

Ошибка у пользователя на боевой базе, воспроизвести нельзя, отладку включать нельзя. Тогда остаётся журнал регистрации: ЗаписьЖурналаРегистрации с понятным комментарием в подозрительных местах.

Это не признак слабости, а нормальный способ: половина разбирательств на настоящих базах идёт именно так. Важно потом убрать временные записи — журнал не свалка.

Замер производительности

Отдельный инструмент конфигуратора: показывает, сколько заняла каждая строка и сколько раз выполнилась.

Смотреть надо на число вызовов, а не на суммарное время: строка, выполнившаяся тысячу раз по три миллисекунды, и есть виновник трёх секунд. Про это была глава «Что тормозит».

На чём спотыкаются

Чинят, не поняв. Добавили проверку — ошибка исчезла. Через месяц вернулась в другом месте, потому что причина осталась.

Меняют несколько вещей сразу. Стало работать — непонятно от чего. Меняют по одному.

Не проверяют, что ошибка действительно ушла. Проверяют тем же способом, которым воспроизводили, а не «вроде теперь нормально».

Оставляют отладочные Сообщить в рабочем коде. Пользователь видит служебные строки и перестаёт доверять программе.

Упражнение 1. Сузить круг

Функция ЧтоДальше(Повторяется, МестоНайдено) подсказывает следующий шаг поиска: если ошибка не повторяется — «Воспроизвести»; если повторяется, но место не найдено — «ТочкаОстанова»; если место найдено — «Понять».

Решается в тренажёре: код запускается и проверяется сразу.

Что показывает отладчик, кроме остановки

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

Табло — окно, куда выписывают выражения, за которыми следят. Не только переменные: туда пишут Строки.Количество(), Сумма / Количество, любое выражение — и видят его значение на каждом шаге.

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

Стек вызовов — список «кто кого вызвал», от текущей строки вверх.

Пошаговое выполнение — идти по коду и смотреть, куда он на самом деле сворачивает.

Шаги отладчика

ДействиеЧто делаетКогда нужно
Точка остановаостановиться на этой строкезнаете место, хотите посмотреть значения
Шагнуть черезвыполнить строку целиком и встать на следующуювызов доверяем, интересно, что дальше
Шагнуть ввойти внутрь вызванной процедурыподозрение, что ошибка внутри вызова
Выйти из процедурыдоработать текущую и вернуться к вызвавшейвошли по ошибке или уже всё увидели
Продолжитьбежать до следующей точки остановаздесь всё понятно, интересно следующее место
Остановитьпрервать выполнениеувидели причину, дальше не надо

Стек вызовов отвечает на «кто это вызвал»

Вы стоите внутри функции, у неё в параметрах ерунда. Вопрос не «что тут не так», а «откуда это пришло».

Стек вызовов показывает всю цепочку: ваша функция, та, что её вызвала, и так до самого начала — до нажатия кнопки или до начала проведения. По каждой строке цепочки можно щёлкнуть и увидеть значения переменных ТАМ.

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

Почему точка останова не срабатывает

Проверяйте по порядку, причин ровно пять:

1. Код выполняется на сервере, а отладка сервера не включена. Включается в самом сервере (параметр отладки) и в конфигураторе — «Отладка разрешена».

2. Это фоновое задание. Оно тоже сервер, и ему нужна отдельная галочка «Отлаживать фоновые задания» — иначе оно просто пробежит мимо ваших точек.

3. Строка вообще не выполняется. Условие выше не сработало, и до неё не доходит — это уже находка, а не проблема отладчика.

4. Выполняется другой код: расширение, копия обработки, другая база. Самая обидная причина.

5. Точка стоит на строке, которой в откомпилированном коде нет — на комментарии или на пустой строке.

Половинное деление: когда непонятно даже, где смотреть

Есть процедура на триста строк, и результат в конце неверный. Ставить точку на каждой строке — день работы.

Приём простой: поставить точку ровно посередине и посмотреть, правильны ли данные там. Если правильны — ошибка во второй половине, если нет — в первой. Повторить с половиной половины.

Триста строк разбираются семью такими шагами. То же работает не только с кодом: так же ищут «какая из двадцати строк файла ломает загрузку» и «какое из пятидесяти изменений сломало отчёт».

Упражнение 2. Починить деление на ноль

Функция Средние(Списки) считает среднюю цену по каждому списку и склеивает ответы через запятую. На пустом списке она падает. Почините СредняяЦена так, чтобы для пустого списка получался 0. Ожидаемый ответ — «200, 0, 50».

Решается в тренажёре: код запускается и проверяется сразу.

«У меня работает»

Разработчик не может повторить ошибку пользователя. Код тот же. Значит, отличается не код, и перебирать надо короткий список:

Данные. У него в документе строка без склада, отрицательное количество, дата 2099 года. Самая частая причина из всех.

Права. Под полными правами видно всё, под правами кладовщика — не всё. Запрос возвращает меньше строк, а код этого не ждал.

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

Версия и кэш. У него старая версия конфигурации или не почищенный кэш клиента.

Первый практический шаг — не читать код, а попросить документ, на котором ломается, и проверить на нём.

Отладка запросов — отдельное умение

Запрос не отлаживается по шагам: он либо выполнился, либо нет. Поэтому разбирают его иначе.

Останавливаются на строке Запрос.Выполнить(), через «Вычислить выражение» смотрят Запрос.Текст и копируют его в консоль запросов. Там же ставят параметры — их значения тоже видны в отладчике — и гоняют запрос, отрезая по одному условию, пока не станет ясно, какое из них убивает строки.

Чаще всего виноваты три вещи: соединение, размножившее строки; условие на поле, где NULL; и виртуальная таблица с параметрами, заданными не там. Про все три была часть «Данные».

Упражнение 3. Ошибка на единицу

Функция Последний(Массив) должна возвращать последний элемент, а падает с «индекс за границами». Найдите причину и почините. Проверка передаёт Гвозди, Шурупы, Молоток.

Решается в тренажёре: код запускается и проверяется сразу.

Убедиться, что починили

Правка без проверки — половина работы, и обычно худшая половина: вторая ошибка, внесённая при починке первой, обнаруживается уже у пользователя.

Проверять тем же способом, которым воспроизводили. Не «вроде теперь нормально», а те же шаги, тот же документ, тот же период.

Проверить, что не сломали соседнее. Правка в общей функции задевает всех, кто её вызывает. Кто вызывает — показывает глобальный поиск по конфигурации, и смотреть туда надо до правки, а не после.

Проверить границы. Починили на трёх строках — попробуйте на нуле строк и на одной. Именно там живут деления на ноль и ошибки на единицу, которые вы только что чинили.

Когда замер полезнее отладчика

Отладчик отвечает на «почему неправильно». На «почему долго» он не отвечает: под отладкой всё медленно, и разницы не видно.

Для скорости есть замер производительности в конфигураторе, а для боевого сервера, где отладка запрещена, — технологический журнал: он пишет, какие запросы выполнялись, сколько заняли и какие блокировки ждали. Настраивается файлом logcfg.xml на сервере.

Знать про него полезно и на собеседовании: вопрос «как искать тормоза на боевой базе» задают часто, и правильный ответ начинается не с отладчика.

Короткий свод

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

Как закрепить

Читать про код и писать код — разные умения. В тренажёре к этой главе идут упражнения: вы пишете решение, оно запускается на настоящем интерпретаторе 1С и проверяется сразу, без установки платформы.

Открыть эту главу в тренажёре

Ошибки и исключения