Difference between revisions of "FpDebug/ru"

From Free Pascal wiki
Jump to navigationJump to search
Line 156: Line 156:
 
В настоящее время отладчик показывает первое найденное. (Что вроде случайно)
 
В настоящее время отладчик показывает первое найденное. (Что вроде случайно)
  
= FPC Issues =
+
= Проблемы FPC =
  
This affects all debuggers
+
Это влияет на все отладчики
  
* resourcestring  
+
* resourcestring
Currently not implemented https://bugs.freepascal.org/view.php?id=35571
+
В настоящее время не реализовано https://bugs.freepascal.org/view.php?id=35571
  
 
* const Foo = unicodestring('abc')
 
* const Foo = unicodestring('abc')
No debug info implemented https://bugs.freepascal.org/view.php?id=35569
+
Информация об отладке не реализована https://bugs.freepascal.org/view.php?id=35569
  
* type Foo = object (Dwarf 3) - Fixed in 3.3.3
+
* type Foo = object (Dwarf 3) - Исправлено в 3.3.3
Incorrectly encoded as class-instance https://bugs.freepascal.org/view.php?id=36017
+
Неправильно закодирован как экземпляр класса https://bugs.freepascal.org/view.php?id=36017
<br>The debugger can not display the data.
+
<br> Отладчик не может отобразить данные.
  
* Dynamic array when cross compiling
+
* Динамический массив при кросс-компиляции
 
https://bugs.freepascal.org/view.php?id=35567
 
https://bugs.freepascal.org/view.php?id=35567
<br>The debugger may calculate the length wrong.
+
<br> Отладчик может неправильно вычислить длину.
  
* Wrong stride for bitpacked array - Fixed in 3.3.3
+
* Неправильный шаг для битового массива - исправлено в 3.3.3
 
https://bugs.freepascal.org/view.php?id=36144
 
https://bugs.freepascal.org/view.php?id=36144
<br>FpDebug currently has a workaround
+
<br> В настоящее время у FpDebug есть обходной путь
  
 
= Status =
 
= Status =

Revision as of 22:32, 31 December 2020

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 есть обходной путь

Status

FpDebug supports Linux, Windows and MacOs.

Any functionality regarding execution control (stepping/pausing...) is only tested for Linux and Windows. Support for this on Mac is incomplete/fragile.

Light bulb  Примечание: For Windows/Linux please see Debugger Status

For Mac support is currently considered "Alpha" Data evaluation can be used on Mac via the "LLDB+FpDebug" backend

The information is indicative and subject to updates / subject to further testing

Notes

Stepping out

"Stepping out" relies on finding the caller address. The location of which depends on whether a function has a "stackframe" (use the BasePointer register) and has the frame already/still set-up. Detection of this is limited to a few standard situations. (Especially in none FPC code, or optimized code this will not be detectable).

Within un-optimized FPC code this feature works.

Hardware Watchpoints (aka Data Breakpoints)

Partly implemented for most data types (subset of the types supported by the hardware), including Conditions and other properties.

All watchpoints will have global scope. Watching a local var will alert you the next time the variable's memory is overwritten (e.g. if another variable takes the memory).

"Write only" watchpoints act as "read/write"

Watchpoints also trigger if they are overwritten with the value they already have.

Watchpoints do not show the before/after dialog.

Watchpoints that are not aligned to an address that is a multiply of their size, may be triggered by neighbouring values. E.g., a Word starting at an odd address, can be triggered by the byte before or after it. A 64 bit pointer must be aligned to an 8 byte boundary, or can be triggered by neighbours.

Thread and Stack

See "Stepping out". Relies on the same frame detection.

Watches / Locals / Inspect

Implemented

  • Any missing types need to be discovered (i.e. not aware of any type that does not display, if not listed under "fpc issues"
  • currency types may not display the decimal dot (they will show value * 1000)
  • Not all setting from the watch properties are implemented (most are not)
  • Expressions:
    • The debugger accepts expressions that it will calculate. Not all Pascal operators have been implemented.
    • Expressions are calculated without range checks
      • simple terms (just an identifier)
        • Includes the value identifier "self" (if in a method), and the constants nil, true, false
      • typecasts
      • @ and ^ (address of and deref)
      • "^TFoo(x)" typecast x, as pointer to TFoo
      • () bracketed expression "a*(b+c)"
      • [] index for arrays, pointers, and pchar
      • . Foo.Bar access of members
      • constant numbers in decimal, hex ($), oct (&), bin (%)
      • constant string (ansistring)
      • +-*/ for int and float
      • mod for int
      • + for string
      • +- for pointer+int
      • div for int
      • = <> < > <= >= for int, float, string
      • not and or xor: for int and boolean

Modify variables (not implemented)

Not Done

Console Output

On Windows console is opened by OS. On Linux the output goes to the debugger window "Console output"

Cross bit-ness Debugging (32/64 bit)

FpDebug has no cross debugging between different platforms.

However, if your IDE has a different bitness that your project FpDebug may be able to debug it.

Windows

A 64 bit IDE
can debug both 64bit and 32bit applications
A 32 bit IDE
can only debug 32bit applications

Linux

Cross debugging has not yet been tested, but may be possible.

Not implemented yet

  • Modify watches
  • Changing Location of execution (while paused) / Resume execution from different line
  • Properties
  • Function calls
  • ...