Точка останова как пользоваться
Как работать с отладкой в 1С 8.3 и 8.2
Отладка 1С — очень мощный и функциональный механизм платформы 1С 8.3, позволяющий быстро найти ошибки в программном коде (в других языках программирования это называется «дебаг», от английского «debug»).
Ниже рассмотрим основные методы использования механизма отладки в виде практической инструкции на конкретном примере.
Внимание! Если Вы используете клиент-серверный режим работы (на сервере), Вам необходимо включить отладку на сервере 1С Предприятия.
Запуск отладки в 1С
Самый простой способ запустить отладку в 1С — открыть 1С в режиме конфигуратор и из него запустить режим отладки в нужном режиме работы (тонком/толстом, управляемом/обычном):
Рекомендуем при рядовой разработке использовать режим отладки «Толстого клиента». Но в чистовом варианте всегда прогонять в режиме «тонкого» и «веб-клиента».
Отладка фоновых заданий 1С
Для того чтобы иметь возможность отладки фоновых заданий, необходимо зайти в меню «Отладка — Подключение». В открывшемся окне нажать кнопку «Автоматическое подключение»:
В этом окне Вы можете установить соответствующий флаг.
Помимо фоновых заданий, в данном окне Вы можете включить отладку внешних соединений, http и web-сервисов.
Установка точки останова (брейкпойнта)
Вторым этапом при отладке является установка точки останова (в других языках программирования — брейкпойнт).
Для примера я выбрал для отладки обработчик «При изменении» на форме документа Доверенность:
Для того чтобы установить точку останова, необходимо найти нужный программный код и кликнуть дважды на поле, слева от поля ввода кода (или нажать кнопку F9):
Чтобы увидеть список всех установленных, необходимо зайти в меню Отладка — Список точек останова (alt + F9):
Точка останова 1С с условием (синяя)
Помимо обычной точки останова в 1С есть еще один вид точек останова — с условием. Графически такая точка отображается синим цветом. Такая точка останова очень полезна, когда нужно отловить какую-либо определенную итерацию при обходе в цикле. Отладка включится в тот момент, когда выполнится определенное условие.
Например, остановим цикл на строке с номером 25:
Неактивная точка останова (серая)
Серая точка останова означает, что она не активна, система не будет останавливаться на такой точке. Сделать не активной её можно, нажав специальную кнопку на панели «Отключить точку останова» (shift+ctrl+F9):
Точка останова по ошибке
Система может остановиться по вызванной ошибке, для этого необходимо в меню Отладка — Остановка по ошибке установить соответствующий флаг:
Также остановка по ошибке имеет функционал, аналогичный точке остановки с условием, — она позволяет отфильтровать исключения с определенным текстом ошибки.
Пошаговое перемещение по программному коду 1С
После установки точки останова необходимо инициировать выполнение нужного программного кода, чтобы система вошла в пошаговое исполнения кода. Отображение стрелки свидетельствует о запуске режима пошагового выполнения кода:
Для того чтобы сделать шаг к следующей строке, необходимо нажать кнопку «F11″(Шагнуть в).
Если Вы пошагово проходите по строчкам программного кода и на строке присутствует процедура или функция, то Вы «провалитесь» внутрь этой процедуры (или функции).
Чтобы не «проваливаться», достаточно вместо F11 (Шагнуть в) выполнять переход по строкам кнопкой F10 (Шагнуть через), эта кнопка позволяет перешагивать через процедуры в программном коде.
Чтобы перейти с текущего положения курсора к нужному, минуя промежуточные строчки кода, необходимо установить курсор на нужной строке и нажать shift + F10 (Идти до курсора).
Анализ значений в режиме отладки 1С
Посмотреть значения определенных значений можно разными способами:
Отображение значения при наведении курсора
При наведении на переменную система «подсвечивает» значения переменной:
Использование «Вычислить выражение» или «Табло»
Эти два метода анализа очень похожи, основные отличия в интерфейсе. Табло удобнее использовать для группы показателей, выражения — для одиночных.
Использовать эти методы очень просто. Достаточно ввести в табло имя нужной переменной. Большой плюс произвольных вычислений — Вы можете добавить в выражение свои данные.
Очень полезно использовать вычисление выражения и выполнить запрос, выгрузить в таблицу значений и посмотреть её.
Как узнать откуда вызвана процедура в отладке — Стек вызовов
Очень часто требуется понять, откуда была вызвана та или иная процедура или функция и с какими параметрами. Для этого в 1С предусмотрена специальная функция — «Стек вызовов». Для запуска Стека вызовов необходимо нажать горячие клавиши — Ctrl + Alt + C или через меню (Отладка — Стек вызовов).
С помощью него Вы можете подробно узнать, откуда была вызвана процедура и с какими параметрами:
Если Вас интересует оценка производительности при отладке — Замер производительности при отладке.
Смотрите также обзорное видео по отладке в 1С:
Другие статьи по 1С:
Если Вы начинаете изучать 1С программирование, рекомендуем наш бесплатный курс (не забудьте подписаться на YouTube — регулярно выходят новые видео):
К сожалению, мы физически не можем проконсультировать бесплатно всех желающих, но наша команда будет рада оказать услуги по внедрению и обслуживанию 1С. Более подробно о наших услугах можно узнать на странице Услуги 1С или просто позвоните по телефону +7 (499) 350 29 00. Мы работаем в Москве и области.
Введение в отладку на примере Firefox DevTools, часть 4 из 4
Точки останова с условием
Точки останова — мощный инструмент. Однако иногда нужно «понизить мощность». Если точка останова нужна в теле цикла или функции, которая постоянно вызывается (вроде колбэка onscroll ), можно устать возобновлять выполнение кода. Гораздо удобнее в таком случае указать, когда именно должна сработать точка останова. Такие точки называются «Точка останова с условием».
Проще разбираться на примере, поэтому открывайте наше приложение со списком дел в новой вкладке (это тоже версия, специально подготовленная к статье) и возвращайтесь обратно.
А что, если нам нужно приостановить выполнение кода только в случае, когда текст задачи содержит слово «turtle» (англ. «черепаха»)? Легко!
Кликните в отладчике по номеру строки (в нашем случае — это 24) не левой, а правой кнопкой мыши. В открывшемся меню выберите пункт «Добавить условие»:
Пункт «Добавить условие» в контекстном меню
Выражение, которое должно вернуть true, чтобы выполнение кода приостановилось
Добавляем вместо условия вызов console.log
Теперь на каждое удаление задачи из списка её текст будет выводится в консоль:
Вывод текста удалённой задачи в консоль
Таким образом мы можем консолить наш код, не добавляя console.log в сам код.
Правда, есть способ проще, чем вместо условия использовать вызов console.log — специальный пункт меню «Добавить логирование»:
Пункт «Добавить логирование» в контекстном меню
Указать нужно лишь то, что мы хотим вывести в консоль, без console.log :
Выражение, которое нужно вывести в консоль
Вывод текста удалённой задачи в консоль правильным способом
Совет в тему
Указывать точку останова повторно в отладчике не нужно.
Убедитесь сами! Откройте версию приложения с debugger в коде во вкладке с запущенными инструментами разработчика и попробуйте добавить задачу.
Что дальше?
Кстати, отладчик Firefox написан с использованием JavaScript. Код отладчика и других инструментов разработчика общедоступен, а значит вы можете поучаствовать в его разработке.
Если вы пока не готовы участвовать в разработке браузера, а хотите начать с чего-то малого — помогите с русской версией документации по инструментам разработчика Firefox. Задачи есть разные: от правки опечаток, до написания новых статей. Внести вклад в развитие MDN просто: нужен только профиль на GitHub и минимальные знания Git.
И, конечно же, устанавливайте Firefox, созданный специально для разработчиков. Firefox Developer Edition — это самые актуальные версии инструментов, экспериментальные функции, отдельный системный профиль, чтобы вы могли легко запускать браузер одновременно с обычным Firefox.
3.7 – Использование встроенного отладчика: запуск и точки останова
Пошаговое выполнение (рассматривается в уроке «3.6 – Использование встроенного отладчика: пошаговое выполнение») полезно для изучения каждой отдельной строки вашего кода изолированно. Но в большой программе может потребоваться много времени, чтобы пройти через весь код, чтобы даже добраться до точки, которую вы хотите изучить более подробно.
К счастью, современные отладчики предоставляют больше инструментов, которые помогают нам эффективно отлаживать наши программы. В этом уроке мы рассмотрим некоторые функции отладчика, которые позволяют нам быстрее ориентироваться в коде.
Выполнение до курсора
Первую полезную команду обычно называют «Выполнить до курсора» (Run to Cursor). Эта команда «Выполнить до курсора» выполняет программу до тех пор, пока выполнение не достигнет инструкции, выбранной курсором. Затем отладчик возвращает управление вам, чтобы вы могли начать отладку с этой точки. Это обеспечивает эффективный способ начать отладку в определенной точке вашего кода или, если уже отладка начата, перейти прямо в то место, которое вы хотите изучить дальше.
Для пользователей Visual Studio
Для пользователей Code::Blocks
Давайте попробуем эту команду с помощью той же программы, которую мы использовали в предыдущем уроке:
Просто кликните правой кнопкой мыши в любом месте строки 5, затем выберите Выполнить до текущей позиции.
Рисунок 1 – Положение маркера выполнения после запуска выполнения до курсора для строки 5
Вы заметите, что программа запустится, а маркер выполнения переместится на только что выбранную строку. Ваша программа выполнилась до этой точки и теперь ожидает ваших дальнейших команд отладки. Отсюда вы можете пошагово выполнять свою программу, переходить к курсору в другое место и т.д.
Если вы запустили выполнение до курсора для места, которое не выполняется, выполнение до курсора просто запустит вашу программу до ее завершения.
Продолжение
Когда вы находитесь в середине сеанса отладки, вы можете захотеть просто запустить выполнение программы с этой точки. Самый простой способ сделать это – использовать команду Продолжить (Continue). Команда отладки Продолжить (Continue) просто продолжает выполнение программы как обычно, либо до тех пор, пока программа не завершится, либо пока что-то не вызовет возврат управления вам (например, точка останова, которую мы рассмотрим позже в этом уроке).
Для пользователей Visual Studio
Для пользователей Code::Blocks
Давайте протестируем команду продолжить. Если маркер выполнения еще не находится в строке 5, запустите выполнение до курсора для строки 5. Затем выберите продолжить с этой точки. Ваша программа завершит выполнение, а затем завершится.
Запуск
У команды продолжить есть брат-близнец по имени запуск. Команда Запуск (Start) выполняет то же действие, что и продолжить, только начиная с самого начала программы. Её можно вызвать только тогда, когда сеанс отладки еще не запущен.
Для пользователей Visual Studio
Для пользователей Code::Blocks
Если вы используете команду запуска в приведенном выше примере программы, она будет выполняться без прерываний. Хотя это может показаться бесполезным, но это только потому, что мы не сказали отладчику прервать выполнение программы. Мы воспользуемся этой командой с большей пользой в следующем разделе.
Точки останова
Последняя тема, о которой мы поговорим в этом разделе, – это точки останова. Точка останова (breakpoint) – это специальный маркер, который сообщает отладчику остановить выполнение программы при работе в режиме отладки в точке останова.
Для пользователей Visual Studio
Для пользователей Code::Blocks
Когда вы установите точку останова, вы увидите значок нового типа. Visual Studio и Code::Blocks используют красный кружок:
Рисунок 2 – Индикация точки останова в строке 5
Установите точку останова в строке 5, как показано на изображении выше.
Теперь выберите команду запуск, чтобы отладчик запустил ваш код, и давайте посмотрим, как работает точка останова. Вы заметите, что вместо того, чтобы работать до конца программы, отладчик останавливается в точке останова (с маркером выполнения, расположенным над значком точки останова):
Рисунок 3 – Отладчик остановился в точке останова в строке 5
Это как если бы вы запустили выполнение до курсора в этой точке.
Точки останова имеют несколько преимуществ по сравнению с выполнением до курсора. Во-первых, точки останова заставят отладчик возвращать вам управление каждый раз, когда они встречаются (в отличие от выполнения до курсора, которое выполняется до курсора только один раз при каждом вызове). Во-вторых, вы можете установить точку останова, и она будет сохраняться до тех пор, пока вы ее не удалите, тогда как с выполнением до курсора вам нужно находить место, до которого вы хотите запустить выполнение, каждый раз, когда вы вызываете команду.
Обратите внимание, что точки останова, размещенные на строках, которые не находятся на пути выполнения, не заставят отладчик останавливать выполнение кода.
Давайте взглянем на слегка измененную программу, которая лучше иллюстрирует разницу между точками останова и выполнением до курсора:
Сначала запустите новый сеанс отладки, а затем выполнение до курсора в строке 5. Теперь выберите продолжить. Программа продолжится до конца (она не остановится на строке 5 снова, даже если строка 5 выполняется еще дважды).
Затем установите точку останова в строке 5, затем выберите запуск. Программа остановится на строке 5. Теперь выберите продолжить. Программа остановится на строке 5 во второй раз. Выберите продолжить снова, и она остановится в третий раз. Еще одна команда продолжить, и программа завершится. Вы можете видеть, что точка останова заставляла программу останавливаться столько раз, сколько выполнялась эта строка.
Задать следующую инструкцию
Есть еще одна команда отладки, которая используется довольно редко, но, по крайней мере, о ней стоит знать, даже если вы не будете использовать ее очень часто. Команда Задать следующую инструкцию (Set next statement) позволяет нам изменить точку выполнения на какую-либо другую инструкцию (иногда неофициально называется прыжком). Её можно использовать для прыжка вперед к точке выполнения и пропуска кода, который в противном случае выполнялся бы, или назад для того, чтобы что-то, что уже было выполнено, запустилось снова.
Для пользователей Visual Studio
Для пользователей Code::Blocks
В Code::Blocks вы можете перейти к точке выполнения через меню Debug (Отладка) → Set next statement (Задать следующую инструкцию), или кликнув правой кнопкой мыши на инструкции и выбрав Set next statement (Задать следующую инструкцию) в контекстном меню. Code::Blocks не имеет сочетания горячих клавиш для этой команды.
Давайте посмотрим, как прыгать вперед:
Сначала запустите выполнение до курсора в строке 11. На этом этапе вы должны увидеть значение 5 в окне консоли.
Теперь кликните правой кнопкой мыши на строку 12 и выберите Задать следующую инструкцию. Это приведет к тому, что строка 11 пропускается и не выполняется. Затем выберите Продолжить, чтобы завершить выполнение программы.
Результат работы вашей программы должен выглядеть так:
Мы видим, что вызов printValue(6) был пропущен.
Эта функция может быть полезна в нескольких контекстах.
В нашем исследовании основных методов отладки мы обсудили закомментирование функции как способ определить, сыграла ли данная функция роль в возникновении проблемы. Для этого необходимо изменить наш код и позже не забыть раскомментировать функцию. В отладчике нет прямого способа пропустить функцию, поэтому, если вы решите, что хотите это сделать, использование Задать следующую инструкцию (Set next statement) для прыжка через вызов функции – самый простой способ сделать это.
Прыжок назад также может быть полезен, если мы хотим увидеть, как только что выполненная функция запускается снова, чтобы мы могли увидеть, что она делает.
С тем же кодом, приведенным выше, запустите выполнение до курсора в строке 12. Затем задайте следующую инструкцию на строку 11 и выполните команду продолжить. Результат работы программы должен быть следующим:
Предупреждение
Команда задать следующую инструкцию изменит точку выполнения, но не изменит состояние программы. Ваши переменные сохранят те значения, которые были у них до прыжка. В результате прыжки могут привести к тому, что ваша программа будет выдавать значения, результаты или поведение, отличающиеся от обычного последовательного выполнения. Используйте эту функцию с умом (особенно при прыжках назад).
Предупреждение
Вы не должны использовать команду задать следующую инструкцию для изменения точки выполнения на другую функцию. Это приведет к неопределенному поведению и, вероятно, к сбою.
Заключение
Теперь вы узнали об основных способах использования встроенного отладчика для наблюдения и управления выполнением вашей программы. Хотя эти команды могут быть полезны для диагностики проблем с последовательностью выполнения кода (например, для определения того, вызываются ли определенные функции или нет), они являются лишь частью преимуществ, которые дает встроенный отладчик. В следующем уроке мы начнем изучать дополнительные способы проверки состояния вашей программы, для чего вам понадобится использование этих команд.
Точки останова на ручной тяге (для архитектуры x86)
Любой программист хоть раз заглядывавший в отладчик знаком с понятием точки останова (aka бряк, breakpoint). Казалось бы нет ничего проще, чем поставить точку останова пара кликов мышкой в графическом интерфейсе или команда в консоли отладчика, но не всегда жизнь системного программиста столь проста и иногда возникает необходимость выставлять точки останова автоматически — изнутри самой программы.
Instruction breakpoints
[про этот вид точек останова оказывается достаточно подробно писали два года назад, поэтому я кратко привел лишь общие соображения]
Кстати сами отладчики тоже пользуются этой инструкцией: просто подменяют ей инструкции в памяти, когда мы просим их поставить бряк. Именно поэтому int 3 кодируется одним байтом ( 0xCC ) а не двумя, как остальные инструкции генерации программого прерывания int X ( 0xCD imm8 ) — иначе бы int 3 не годилась бы для подмены однобайтовых инструкций.
Как мы видим ничего сложного в ручной расстановке instruction breakpoints нет. Можно даже реализовывать их интерактивное включение-выключение: достаточно запоминать их позиции и заменять ненужные на пустую инструкцию nop ( 0x90 ).
Гораздо интереснее дело обстоит с другим типом точек останова — точками останова на доступ к памяти.
Access breakpoints
Допустим мы отлаживаем повреждение памяти в среде исполнения с копирующим сборщиком мусора, который постоянно компактифицирует кучу и всякими другими способами тасует объекты в памяти. Мы смогли выяснить приблизительно какое поле в каком объекте повреждается, но просто загрузить программу в отладчик и поставить им точку останова на доступ к этому полю не получается, потому что GC постоянно путается под ногами своими перемещениями. Поэтому у нас возникает разумное желание, чтобы сам добряк Сборщик Мусора и выставлял/обновлял этот бряк.
Иными словами мы хотим предоставить ему в распоряжение функцию
void SetAccessBreak(void* addr);
kBreakStateMask = 3 // mask 11
kConditionMask = 3 // mask 11
kSizeMask = 3 // mask 11
uint32_t MakeFlags ( DebugRegister reg, BreakState state, Condition cond, Size size ) <
return ( state | cond 16 | size 24 ) reg ;
uint32_t MakeMask ( DebugRegister reg ) <
return MakeFlags ( reg, kBreakStateMask, kConditionMask, kSizeMask ) ;
Вооружившись этими функциями можно не зная брода бросится в воду и попробовать реализовать SetAccessBreak с помощью простого встроенного ассемблера:
bool SetAccessBreak ( void * addr,
const uint32_t control = MakeFlags ( reg, kEnabledLocally, cond, size ) ;
__asm__ ( «movl %0, %%dr0 \n «
bool SetAccessBreak ( pthread_t target_thread,
mach_msg_type_number_t dr_count = x86_DEBUG_STATE_COUNT ;
// Извлечем из POSIX потока нижлежащий MACH поток.
mach_port_t target_mach_thread = pthread_mach_thread_np ( target_thread ) ;
// Запросим состояние отладочных регистров потока.
kern_return_t rc = thread_get_state ( target_mach_thread,
// Попытка получить текущее состояние отладочных регистров провалилась
// Загрузим адрес, за которым нужно следить с указанный регистр.
// Сбросим все флаги относящиеся к указанному регистру.
// Установим новое значение флагов.
// Обновим состояние отладочных регистров.
rc = thread_set_state ( target_mach_thread,
// Обновление регистров провалилось.
// Точка установа успешно выставлена.
Вот и все! Теперь добрый дядька Дворник-Сборщик Мусора может сам управлять точками останова. Кто не верит, может написать маленькую тестовую программку:
static int16_t foo = 0 ;
static int32_t bar = 0 ;
int main ( int argc, char * argv [ ] ) <
и запустив её под отладчиком убедится, что исполнение каждый прерывается в правильных местах — т.е. на инструкции следующей за той, которая доступается к области памяти:
(gdb) r
Starting program: /Users/mraleph/test
Reading symbols for shared libraries +++. done