FpDebug/ru
│
English (en) │
русский (ru) │
О пакете
FpDebug - это отладчик, написанный языке Паскаль для использования в Pascal.
Подробнее:
- FpDebug написан на Паскале
- FpDebug использует формат отладочной информации DWARF
- Текущая реализация является подмножеством DWARF с поддержкой DWARF версий 2 и 3. Однако «подмножество» - это просто состояние реализации. Цель состоит в том, чтобы расширить его, дабы реализовать как можно больше стандартных возможностей.
- Текущая реализация охватывает подмножество, которое используется FPC
- FpDebug имеет специальные реализации для работы с конкретным использованием DWARF для FPC (ошибки, отсутствующая информация, подробности реализации)
Что подразумевается под «FpDebug»
FpDebug может ссылаться на
Пакет "FpDebug"
Это движок отладчика. Это не относится к IDE. Пакет используется несколькими бэкэндами IDE:
- Отладчик LLDB (с fpdebug): этот отладчик использует LLDB в качестве бэкэнда. Чтобы отображать результаты в стиле Паскаля, он использует движок «fpdebug» для отображения locals/watches.
- Отладчик GNU (с fpdebug): для пошаговой отладки(stepping)/точек останова(breakpoints)/... используется GDB, а FpDebug - для списка слежения (watches).
- Внутренний отладчик Dwarf FpDebug: "чистый" FpDebug. Пошаговая отладка(Stepping), Запуск(Running), Точки останова(Breakpoint), Список слежения (Watches), Локальные переменные (Locals), Стэк (Stack)....
FpDebug как ссылка на серверную часть IDE LazDebuggerFp
Фактическое имя серверной части IDE - LazDebuggerFp. Это имя пакета, который необходимо установить для использования отладчика. Однако, как видно выше, ни в каком техническом контексте (например, в заголовках в среде IDE) это не упоминается как «FpDebug ...»
Другие проекты FpDebug
Имя используется для другого проекта с той же целью.
Установка в IDE
Установите пакет LazDebuggerFp
Общие проблемы отладки
Эти проблемы не могут быть исправлены одним отладчиком. Им тоже нужны изменения в FPC. На некоторых может также повлиять отсутствие поддержки в DWARF.
Эти проблемы относятся ко всем серверным модулям отладчика.
Свойства
Свойства - одна из наиболее востребованных функций (любого) отладчика(ов). Вот почему они еще не могут быть проверены, и почему до этого пройдет еще немало времени.
Прежде, чем вдаваться в подробности: для «Свойства без getter-функции» (т.е. «с прямым доступом к полю») FPC (как средство решения проблемы) в настоящее время добавляет запись для переменной с именем свойства. Это означает, что такие свойства могут отображаться. Они также могут быть записаны отладчиком (если отладчик поддерживает изменение данных), и если они записаны, это делается в обход любой процедуры Setter, поскольку отладчик не знает, есть ли даже сеттер.
Есть несколько недостающих частей, позволяющих отладчику показывать (и, возможно, изменять) свойства.
- Отладчику нужна поддержка для вызова функций.
- FPC нужен способ добавить информацию о «свойствах» к отладочной информации.
Что касается вызова функции. Это просто может отсутствовать реализация в отладчике. Это еще не было исследовано более глубоко. Может потребоваться или не потребоваться дополнительная информация в DWARF, созданном FPC.
Что касается добавления «свойств» к отладочной информации: DWARF (по крайней мере версии 2 и 3 / не проверено 4 или 5) фактически не имеет возможности кодировать эту информацию. Следовательно, FPC в настоящее время также не добавляет его.
В случае, если DWARF не добавит это вовремя, DWARF позволит использовать данные от производителя (afaik). До сих пор ни один отладчик не знал бы о каких-либо «частных данных fpc», поэтому в этом не было никакого смысла. В будущем такие данные могут быть согласованы между FPC и FpDebug. Но до этого еще далеко. FpDebug еще даже не выполняет вызов функций.
Strings (vs PChar и Array of Char)
Первоначально в DWARF не было концепции кодирования строк. Это было добавлено в DWARF 4 (требуется проверка), но еще не исследовано на предмет удобства использования с FPC. Также в FPC в настоящее время реализованы только DWARF 2 и 3 (с первыми шагами к версии 4).
Остается только 2 способа кодирования строки в DWARF.
- Как указатель на char
- Как массив char
Какой из них используется, зависит от версии FPC и от того, используется ли DWARF 2 или 3.
Если это «указатель на char», то это делает его неотличимым от реального PChar.
По этой причине все отладчики в Lazarus иногда для таких отслеживаемых выражений, как SomeString[4]
, показывают результат «PChar: 'a'; String: 'b'». Поскольку PChar начинается с нуля, а строка - с единицы, индекс «4» может означать 4-й или 5-й символ.
Недавние FPC используют «массив символов», когда они генерируются DWARF 3. В том, что у них (в настоящее время) есть различия в деталях реализации между тем, как они кодируют строки и реальный массив символов. (Например, пропуск необязательного/избыточного бита информации. В данном случае: DW_AT_byte_stride). Эти детали не имеют смысла с точки зрения любого другого отладчика, но FpDebug может их обнаружить, поскольку знает об этих деталях реализации. Конечно, это очень ненадежно, следующая версия FPC всегда может это изменить.
Аналогичным образом FPC обрабатывает ShortStrings внутри как запись и кодирует их как есть. Опять же, различие заключается в деталях реализации.
Изменение управляемых типов
Это применимо к любому отладчику, который может устанавливать новые значения для списка слежения (изменяет переменную в отлаживаемом exe).
Управляемые типы не могут быть изменены корректно.
Для изменения управляемых типов отладчику необходимо знать:
- счетчик ссылок
- копирование при записи
- как выделить/освободить память / или лучше как вызвать методы inc/dec_ref для каждого типа, чтобы они выполняли работу правильно
Ничего из этого не доступно.
Если вы присваиваете новое значение строке или динамическому массиву, то необходимо скорректировать счетчик ссылок старого и нового значения. При необходимости память должна быть выделена или освобождена. Если это сделать неправильно, это, по крайней мере, вызовет утечку памяти. Но это также может вызвать сбои или другие случайные ошибки, когда отлаженный exe продолжает работу.
В массиве можно изменить один элемент. "SomeArray[5] := 7;". Если на массив ссылаются несколько переменных, это повлияет на их всех. То же самое произойдет, если вы выполните этот оператор в своем приложении.
У строки (AnsiString) использует механизм копирование при записи (copy-on-write). Если вы сделаете "SomeString[4] := 'a'", тогда переменная, из которой вы получили доступ к строке, получит новую копию, и другие переменные (которые совместно используют память) не должны быть затронуты. У отладчика этой информации нет. Также у него нет доступа к счетчику ссылок и распределению/освобождению памяти (или внутренним строковым процессам).
Вызов функции с управляемыми типами в качестве параметра или результата
Предполагая, что вызов функции был реализован в целом ....
По той же причине, что и в «Модификации управляемых типов», отладчик не может создавать строки или массивы для вызова функций, которые ожидают их как параметр.
Значения результатов можно принять, но это вызовет утечку памяти.
Область действия / порядок поиска переменных
Существуют различные проблемы, при которых FPC не помещает достаточно информации в информацию DWARF, чтобы отладчик мог вычислить правильную область для всех переменных. В тех же случаях это может быть связано с тем, что DWARF не предлагает этого или не предлагает его в то время, когда он был реализован или последний раз обновлялся в FPC. Некоторые из них можно исправить, если FPC изменит способ кодирования информации.
Вложенные процедуры
var SomeVar: Integer; // глобальная переменная
procedure Outer(NumText: string);
var
SomeVar: Integer; // локальная переменная, объявленная выше "Nested"
procedure Nested;
var
I: Integer;
begin
WriteLn(OuterVarInScope);
end;
//var
// SomeVar: Integer; // локальная переменная, объявленная ниже "Nested"
begin
Nested;
end;
Локальная переменная SomeVar
скрывает глобальную переменную с таким же именем, если вы находитесь в процедуре «Outer».
Локальная переменная также видна (и скрывает глобальную), если вы находитесь в процедуре «Nested».
Но если вы закомментируете локальную переменную, "объявленную выше Nested", и раскомментируете локальную переменную, "объявленную ниже Nested", то локальная переменная больше не будет в области видимости "Nested". «Nested» теперь будет видеть глобальную переменную. («Outer» по-прежнему видит локальные переменные).
Информация DWARF в настоящее время только сообщает отладчику, что SomeVar
объявлена как локальная переменная в параметре "Outer". И это «Nested» находится внутри «Outer».
Но информация DWARF не включается, если SomeVar
объявлен выше или ниже "Nested". Так что отладчик не заметит разницы. В обоих случаях отладчик будет отображать локальную переменную SomeVar
, если она приостановлена в "Nested".
Глобальные перменные из других модулей
Информация DWARF содержит раздел для каждого модуля. Все символы модуля перечислены в правильном разделе. Однако нет информации о том, какой модуль входит в секцию "uses" какого другого модуля. И, очевидно, даже меньше, в каком порядке они используются.
Если существует несколько глобальных переменных с одинаковым именем, по одной в каждом из нескольких модулей, то FPC использует порядок разделов uses (справа налево), чтобы найти переменную, которая будет видна из кода в текущем модуле.
Если в модуле FooBar
есть код, который обращается к переменной с именем NotInFooBar
(которая не объявлена в модуле FooBar
), то эта переменная должна быть из одного из других модулей.
Если есть несколько переменных с именем NotInFooBar
в разных модулях, то отладчик не имеет информации, какой из них именно использовал FPC.
В настоящее время отладчик показывает первое найденное. (Что вроде случайно)
Проблемы FPC
Это влияет на все отладчики
- resourcestring
В настоящее время не реализовано https://bugs.freepascal.org/view.php?id=35571
- const Foo = unicodestring('abc')
Информация об отладке не реализована https://bugs.freepascal.org/view.php?id=35569
- type Foo = object (Dwarf 3) - Исправлено в 3.3.3
Неправильно закодирован как экземпляр класса https://bugs.freepascal.org/view.php?id=36017
Отладчик не может отобразить данные.
- Динамический массив при кросс-компиляции
https://bugs.freepascal.org/view.php?id=35567
Отладчик может неправильно вычислить длину.
- Неправильный шаг для битового массива - исправлено в 3.3.3
https://bugs.freepascal.org/view.php?id=36144
В настоящее время у FpDebug есть обходной путь
Положение дел
FpDebug поддерживает Linux, Windows и MacO.
Любые функции, касающиеся управления выполнением (пошаговое выполнение/приостановка ...), тестируются только для Linux и Windows. Поддержка этого на Mac неполная/ненадежная.
Поддержка Mac в настоящее время считается «альфа-версией» Оценка данных может использоваться на Mac через серверную часть LLDB + FpDebug
Информация носит ориентировочный характер и может обновляться / подлежит дальнейшему тестированию.
Примечания
Пошаговый вывод
«Пошаговый вывод» основан на поиске адреса вызова. Расположение которого зависит от того, есть ли у функции «стековый фрейм» (использует регистр BasePointer и (прим. перев.: представляет из себя структуры в стеке процессора)) и имеет ли уже/все еще настроенный фрейм. Обнаружение этого ограничено несколькими стандартными ситуациями. (Особенно это невозможно обнаружить в коде FPC или в оптимизированном коде).
Эта функция работает в неоптимизированном коде FPC.
Аппаратные точки наблюдения (также известные как точки останова по данным)
Частично реализовано для большинства типов данных (подмножество типов, поддерживаемых оборудованием), включая условия и другие свойства.
Все точки наблюдения будут иметь глобальную область действия. Наблюдение за локальной переменной будет предупреждать вас в следующий раз, когда память переменной будет перезаписана (например, если другая переменная займет память).
Точки наблюдения "только запись" действуют как "чтение/запись"
Точки наблюдения также срабатывают, если они перезаписываются имеющимся у них значением.
Точки наблюдения не показывают диалоговое окно до/после.
Точки наблюдения, которые не выровнены по адресу, кратному их размеру, могут запускаться соседними значениями. Например, Word, начинающееся с нечетного адреса, может запускаться байтом до или после него. 64-битный указатель должен быть выровнен по 8-байтовой границе или может запускаться соседями.
Поток и стэк
См. «Пошаговый вывод». Полагается на то же обнаружение кадров.
Окно наблюдений / Локальные переменные / Осмотр
Реализовано
- Любые отсутствующие типы должны быть обнаружены (т.е. неизвестны какие-либо типы, которые не отображаются, если они не указаны в разделе «Проблемы fpc»
- типы валют могут не отображать десятичную точку (они будут отображать значение * 1000)
- Реализованы не все настройки из свойств окна наблюдений (большинство из них)
- Выражения:
- Отладчик принимает выражения, которые он будет вычислять. Не все операторы Паскаля реализованы.
- Выражения рассчитываются без проверки диапазона
- простые выражения (просто идентификатор)
- Включает идентификатор значения 'self' (если в методе) и константы nil, true, false.
- приведение типов
- @ и ^ (address of и deref)
- "^TFoo(x)"' приведение типа x как указатель на TFoo
- () выражение в квадратных скобках "a*(b+c)"
- [] индекс для массивов, указателей и pchar
- Доступ участников к Foo.Bar
- постоянные числа в десятичном, шестнадцатеричном формате ($), oct (u0026), bin (%)
- постоянная строка (ansistring)
- + - * / для int и float
- мод для int
- + для строки
- +- для указателя + int
- div для int
- = <> < > <= >= для int, float, string
- not and or xor: для int и boolean
- простые выражения (просто идентификатор)
Изменение переменных (не реализовано)
Не сделано
Консольный вывод
В Windows консоль открывается ОС. В Linux вывод поступает в окно отладчика «Консольный вывод».
Кросс-битовая отладка (32/64 бит)
FpDebug не имеет кросс отладки между разными платформами.
Однако, если ваша IDE имеет другую разрядность, ваш проект FpDebug может ее отладить.
Windows
- A 64-битная IDE
- может отлаживать как 64-битные, так и 32-битные приложения
- A 32-битная IDE
- может отлаживать только 32-битные приложения
Linux
Перекрестная отладка еще не тестировалась, но, вероятно, возможна.
Еще не реализовано
- Изменение окна отладки
- Изменение места выполнения (во время паузы) / возобновление выполнения с другой строки
- Свойства
- Вызов функций
- ...