Difference between revisions of "Debugger Status"

From Lazarus wiki
Jump to navigationJump to search
(30 intermediate revisions by one other user not shown)
Line 7: Line 7:
 
{{Debugger_Backend_List}}
 
{{Debugger_Backend_List}}
  
==== Notes ====
+
{{Note|
 +
* For the [[GDB]] and [[LLDB]] based debugger, support is indicated based on the assumption that your version of GDB supports this. Support indication is generally based on current GDB/LLDB for mainstream OS.
 +
* [[FpDebug]]ger currently only works for Windows and Linux
 +
* The "LLDB Debugger (Alpha)" is not included below. It is a by-product of the "LLDB+FpDebug". It is not actively developed/maintained, other than what is needed for "LLDB+FpDebug".
 +
}}
 +
 
 +
==== Availability (OS/Platform) ====
 +
{| class="wikitable "
 +
! OS/Platform
 +
! GdbMi !! GdbMi+Ssh !! GdbServer !! GdbMi+FpDebug
 +
! Lldb+FpDebug
 +
! Fp-Debugger
 +
! Comments
 +
 
 +
|---- class="working"
 +
| style="text-align:left" | Linux
 +
| Y || Y || Y || Y
 +
| class="partial" | Depends on availability<br/>of a stable LLDB
 +
| Y
 +
|
 +
|---- class="working"
 +
| style="text-align:left" | Mac
 +
| class="partial" | Depends on availability<br/>of a stable<br/>and codesigned GDB || class="unknown" | ? || class="unknown" | ? || class="unknown" | ?
 +
| Y
 +
| class="not" | N
 +
|
 +
|---- class="working"
 +
| style="text-align:left" | Windows
 +
| Y || Y || Y || Y
 +
| class="partial" | Depends on availability<br/>of a stable LLDB
 +
| Y
 +
|
 +
|}
  
* For the GDB and LLDB based debugger, support is indicated based on the assumptino that your version of GDB supports this. Support indication is generally based on current GDB/LLDB for mainstream OS.
 
* Fp-Debugger currently only works for Windows and Linux
 
* The "LLDB Debugger (Alpha)" is not included below. It is a by-product of the "LLDB+FpDebug". It is not actively developed/maintained, other than what is needed for "LLDB+FpDebug".
 
  
 
==== Start/Stop ====
 
==== Start/Stop ====
Line 33: Line 62:
 
| class="not" | N  
 
| class="not" | N  
 
| For GUI apps the first line is in the code generated by the IDE
 
| For GUI apps the first line is in the code generated by the IDE
 +
|---- class="working"   
 +
| style="text-align:left" | Run to line at cursor ||
 +
| Y || Y || Y || Y
 +
| class="not" | N
 +
| Y
 +
| Lazarus 2.2 and higher
 +
 
|---- class="working"  
 
|---- class="working"  
 
| style="text-align:left" | Attach ||  
 
| style="text-align:left" | Attach ||  
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?  
 
| class="unknown" | ?  
| class="not" | N
+
| Lazarus 2.2 and higher
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
Line 43: Line 79:
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?
 
| class="unknown" | ?
| class="not" | N
+
| Lazarus 2.2 and higher
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
Line 57: Line 93:
 
| Y  
 
| Y  
 
| Kill/Stop<br>Restart the external debugger (gdb/lldb)
 
| Kill/Stop<br>Restart the external debugger (gdb/lldb)
 +
|---- class="working"
 +
| style="text-align:left" | Debugger stopped dialog when app exits ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
| Configurable
 
|---- class="unknown" style="font-style:italic"
 
|---- class="unknown" style="font-style:italic"
 
| style="text-align:left" | Run without debugging || {{keypress|Ctrl}}+{{keypress|Shift}}+{{keypress|F9}} || colspan="6" | Y || Not debugger specific
 
| style="text-align:left" | Run without debugging || {{keypress|Ctrl}}+{{keypress|Shift}}+{{keypress|F9}} || colspan="6" | Y || Not debugger specific
Line 89: Line 131:
 
| style="text-align:left" | Step (over) to line at cursor || {{keypress|F4}}
 
| style="text-align:left" | Step (over) to line at cursor || {{keypress|F4}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
| class="unknown" | ?
+
| class="not" | N
| class="partial" | Partial
+
| Y
 
| "STEP OVER" - This works only within the current procedure.
 
| "STEP OVER" - This works only within the current procedure.
 
It will go to the selected line, or stop if the current procedure is left.
 
It will go to the selected line, or stop if the current procedure is left.
 
<br>It will *step* *over* any recursive calls of the procedure, therefore not stopping at the line during recursion.
 
<br>It will *step* *over* any recursive calls of the procedure, therefore not stopping at the line during recursion.
|---- class="not"     
+
|---- class="working"     
 
| style="text-align:left" | Run to line at cursor ||
 
| style="text-align:left" | Run to line at cursor ||
| N || N || N || N
+
| Y || Y || Y || Y
| N
+
| class="not" | N  
| N
+
| Y
| Workaround: Use F5 to set a breakpoint, then F9 to run
+
| Only Lazarus 2.2 and higher
  
 
|---- class="working"  
 
|---- class="working"  
Line 120: Line 162:
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Step over "none breaking" breakpoint ||
+
| style="text-align:left" | Smart source or asm stepping (over/into) ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
| Assign one key (one for "over", one for "into") that acts as source-line or asm stepping, depending on window focus
 +
 
 +
|---- class="working"
 +
| style="text-align:left" | Pause ||
 +
| Y || class="partial" | depends on gdb, mostly "No" || Y || Y
 +
| Y
 +
| Y
 +
|
 +
 
 +
|---- class="working"
 +
| style="text-align:left" | Step: steps over "none breaking" breakpoint ||
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?
 
| class="unknown" | ?
Line 127: Line 183:
 
<br>{{Warning|The "auto-continue" (time based) function may not return to stepping, but instead "run/continue" execution.}}
 
<br>{{Warning|The "auto-continue" (time based) function may not return to stepping, but instead "run/continue" execution.}}
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Step over ignored exceptions ||
+
| style="text-align:left" | Step: steps over ignored exceptions ||
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?
 
| class="unknown" | ?
Line 134: Line 190:
 
Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).  
 
Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).  
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Step from except to finally or except ||
+
| style="text-align:left" | Source-Step: steps from except to finally or except ||
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?  
 
| class="unknown" | ?  
Line 140: Line 196:
 
| Only for standard fpc exception handling. And (Lazarus 2.2) SEH on Win64. <br>
 
| Only for standard fpc exception handling. And (Lazarus 2.2) SEH on Win64. <br>
 
Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).  
 
Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).  
 +
 +
|---- class="working"
 +
| style="text-align:left" | Executable/Code line indicators ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
| Blue dots in the gutter indicate lines with debug info.
 
|}
 
|}
  
 
;Breakpoints / None-breaking breakpoints / Auto-continue breakpoints / Disabled breakpoints: A breakpoint usually pauses your app, in addition it can perform tasks like logging a message (debugger event log), dumping data to the log, taking a snapshot (debugger history). <br>A none-breaking breakpoint will perform those extra tasks, but not pause your app. <br>An auto-continue breakpoint will pause your app (and perform any other action) for a given amount of milliseconds (during which you can use the pause button, to pause permanently), after that it will continue your app. It usually continues using "Run", therefore loosing any current single-step action<br>A disabled breakpoint will do nothing. It is as if it does not exist.
 
;Breakpoints / None-breaking breakpoints / Auto-continue breakpoints / Disabled breakpoints: A breakpoint usually pauses your app, in addition it can perform tasks like logging a message (debugger event log), dumping data to the log, taking a snapshot (debugger history). <br>A none-breaking breakpoint will perform those extra tasks, but not pause your app. <br>An auto-continue breakpoint will pause your app (and perform any other action) for a given amount of milliseconds (during which you can use the pause button, to pause permanently), after that it will continue your app. It usually continues using "Run", therefore loosing any current single-step action<br>A disabled breakpoint will do nothing. It is as if it does not exist.
;Stepping and breakpoints / exceptions: If any debugger pauses the target-app at a breakpoint or exception while single stepping, then the single-step is lost. The breakpoint/exception may be in a deeply nested called function, and you can not continue the single-step. I.e. there is no build in way to get back to the function where you started your step, and finish this step. For this you need to go through the callstack yourself and find the start location and use breakpoints
+
;Stepping and breakpoints / exceptions: If any debugger pauses the target-app at a breakpoint or exception while single stepping, then the single-step is lost. The breakpoint/exception may be in a deeply nested called function, and you cannot continue the single-step. I.e. there is no build in way to get back to the function where you started your step, and finish this step. For this you need to go through the callstack yourself and find the start location and use breakpoints
 
;Stepping and none-breaking-breakpoints / Ignored-exceptions: Most/All? debugger backends can in this case continue to the position where the single-step would have ended. (This may be limited for asm stepping). In case of an exception the single step will end at the next finally or except. "Next" from the point of view of the step-command. I.e., any finally inside a "stepped over function" will be stepped over, but any finally on the same level as the step began will be used as end point. If there is none on the same level, then the next outer will be used.<br>This feature relies heavily on FPC implementation details. Thus it may not work with newer FPC versions.
 
;Stepping and none-breaking-breakpoints / Ignored-exceptions: Most/All? debugger backends can in this case continue to the position where the single-step would have ended. (This may be limited for asm stepping). In case of an exception the single step will end at the next finally or except. "Next" from the point of view of the step-command. I.e., any finally inside a "stepped over function" will be stepped over, but any finally on the same level as the step began will be used as end point. If there is none on the same level, then the next outer will be used.<br>This feature relies heavily on FPC implementation details. Thus it may not work with newer FPC versions.
  
Line 174: Line 237:
 
Intel based systems usually have 4 Watchpoints, each with a max size of 32 bit (64 bit on 64bit CPU)
 
Intel based systems usually have 4 Watchpoints, each with a max size of 32 bit (64 bit on 64bit CPU)
  
 +
|---- class="working"
 +
| style="text-align:left" | Conditional Break/Watch-point ||
 +
| (Y) || (Y) || (Y) || (Y)
 +
| ?
 +
| Y
 +
| GDB based debuggers are limited to GDB's understanding of the conditional expression
 +
|---- class="working"
 +
| style="text-align:left" | Enable/Disable Break/Watch-point according to program flow ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
| Enable/Disable a breakpoint (or a group of) when execution passes through a pre-defined point in your code.
 +
So you can setup that the debugger will only break/skip-breaking, when the code is called in a specific order, or from a specific outer subroutine.
 
|---- class="working"  
 
|---- class="working"  
 
| style="text-align:left" | Ignore exception by class ||
 
| style="text-align:left" | Ignore exception by class ||
Line 180: Line 256:
 
| Y  
 
| Y  
 
| Configurable for each project
 
| Configurable for each project
 +
|---- class="working"
 +
| style="text-align:left" | Break/Watch-point overview Window || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|B}}
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
|
 +
 
|---- class="unknown"  
 
|---- class="unknown"  
 
| style="text-align:left" | TODO: .... Document Breakpoint properties ||
 
| style="text-align:left" | TODO: .... Document Breakpoint properties ||
Line 194: Line 277:
  
 
|}
 
|}
 +
 +
;GdbMi+Ssh: Some functionality depends on the ability to use "Pause". If "Pause" does not work, break/watch-points can not be changed/added/removed while the target app is running. Only when the target app pauses at a breakpoint (or for other reasons), then can changes be made.
  
 
==== Data ====
 
==== Data ====
Line 204: Line 289:
  
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Watches ||
+
| style="text-align:left" | Watches || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|W}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| Y
 
| Y
Line 210: Line 295:
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Locals ||
+
| style="text-align:left" | Locals || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|L}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| Y
 
| Y
Line 216: Line 301:
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Stack ||
+
| style="text-align:left" | Stack || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|S}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| Y
 
| Y
Line 222: Line 307:
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Threads ||
+
| style="text-align:left" | Threads || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|T}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| Y
 
| Y
Line 228: Line 313:
 
| Running State indicator may not be accurate
 
| Running State indicator may not be accurate
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Inspect ||
+
| style="text-align:left" | Inspect || {{keypress|Alt}}+{{keypress|F5}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| Y
 
| Y
Line 234: Line 319:
 
| View members in property Grid. Double-click to inspect members
 
| View members in property Grid. Double-click to inspect members
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Evaluate / Modify ||
+
| style="text-align:left" | Evaluate / Modify || {{keypress|Ctrl}}+{{keypress|F7}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?  
 
| class="unknown" | ?  
Line 240: Line 325:
 
|
 
|
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Disassembler ||
+
| style="text-align:left" | Disassembler || {{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|D}}
 
| Y || Y || Y || Y  
 
| Y || Y || Y || Y  
 
| class="unknown" | ?  
 
| class="unknown" | ?  
Line 247: Line 332:
  
 
|---- class="not"     
 
|---- class="not"     
| style="text-align:left" | Watch/Inspect Class Properties ||
+
| style="text-align:left" | Watch/Inspect Class Properties ||  
 
| N || N || N || N  
 
| N || N || N || N  
 
| N
 
| N
Line 285: Line 370:
 
| Y
 
| Y
 
| Y  
 
| Y  
 +
|
 +
|---- class="working"
 +
| style="text-align:left" | Paste value into Watches window  ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
| Paste directly into watches window, no need to press "Add new watch"
 +
|---- class="working"
 +
| style="text-align:left" | Drag/Drow value from source-editor to Watches window  ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 
|
 
|
 
|---- class="unknown"  
 
|---- class="unknown"  
Line 305: Line 402:
  
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | History ||
+
| style="text-align:left" | History ||{{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|H}}
 
| Y || Y || Y || Y
 
| Y || Y || Y || Y
 
| Y  
 
| Y  
Line 321: Line 418:
 
*Combined with "snapshot" taking breakpoints, you can send a prepared project (watches/breakpoints set) to a co-worker, have them run the project in the debugger, and return the result to you.
 
*Combined with "snapshot" taking breakpoints, you can send a prepared project (watches/breakpoints set) to a co-worker, have them run the project in the debugger, and return the result to you.
 
|---- class="working"  
 
|---- class="working"  
| style="text-align:left" | Event log ||
+
| style="text-align:left" | Event log ||{{keypress|Ctrl}}+{{keypress|Alt}}+{{keypress|V}}
 
| Y || Y || Y || Y
 
| Y || Y || Y || Y
 
| Y  
 
| Y  
Line 330: Line 427:
 
| Y || Y || Y || Y<br>partly
 
| Y || Y || Y || Y<br>partly
 
| class="unknown" | ?  
 
| class="unknown" | ?  
| class="not" | N
+
| class="not" | Not applicable
 
| View communication with the external debugger. For troubleshooting
 
| View communication with the external debugger. For troubleshooting
 
|---- class="working"  
 
|---- class="working"  
Line 346: Line 443:
 
| class="not" | N  
 
| class="not" | N  
 
|
 
|
 +
 +
|---- class="working"
 +
| style="text-align:left" | Edit source code while debugging ||
 +
| Y || Y || Y || Y
 +
| Y
 +
| Y
 +
|
 +
* Fully working source editor (with code completion), while debugging
 +
* Editor keeps track of inserted/deleted lines, so breakpoints can be set to correct location
 
|}
 
|}

Revision as of 15:54, 13 October 2020


This is based on Lazarus 2.0

Available Debuggers

GNU Debugger (gdb)
The first debugger that was supplied with Lazarus. This debugger uses GDB as backend. The IDE performs translations between gdb's none Pascal-ish interface and the interface provided by the IDE. Package: LazDebuggerGdbmi
GNU Debugger through SSH (gdb)
Allows to launch GDB over an ssh connection for remote debugging. This has however some serious limitations. Package: LazDebuggerGdbmi
GNU remote debugger (gdbserver)
Remote debugger using GdbServer (part of the gdb suite). Package: LazDebuggerGdbmi
LLDB Debugger (Alpha)
A basic LLDB based backend. This is a prove of concept implementation. The IDE displays raw LLDB output (no translation, no clean-up...) and there are no plans to add translation of the LLDB output. For using LLDB on Pascal applications the "LLDB Debugger (with fpdebug)" should be used. Package: LazDebuggerLldb
LLDB Debugger (with fpdebug)
This debugger uses LLDB as a backend. In order to display Pascal-style results, it uses the "fpdebug" engine to show locals/watches. LLDB is used to control stepping, breakpoint and execution. For reading data LLDB is used to read the raw memory only. Package: LazDebuggerFPLldb
GNU Debugger (with fpdebug)
Using GDB for stepping/breakpoints/... and FpDebug for watches. Package: LazDebuggerFPGdbmi
FpDebug / LazDebuggerFp - integrated DWARF debugger / (Known issues)
A new debugger completely implemented in Pascal. This debugger implements the DWARF standard (currently 2 and 3 are partly implemented). It has special implementations added to interpret info provided by FPC. It can currently be used on Windows and Linux (very basic support for MacOS). Package: LazDebuggerFP
FpDebug / LazDebuggerFpRspRemote
A new remote debugger to communicate with a gdbserver stub using gdb's remote serial protocol over tcp/ip (in future this could be expanded to include serial/UART). This debugger inherits from LazDebuggerFP, hence in principle supports the same functionality. Currently it only supports the AVR target. Not stable yet. Package: LazDebuggerFpRspRemote
DAB / LazDABDebugger
The Debug Adapter Protocol (DAB) is a protocol to abstract the communication between a Debugger-frontend like Lazarus, and an underlying debugger like FpdServer. LazDABDebugger is a debugger that connects to (any?) DAB-adapter. This makes is possible to debug other languages or different platforms within Lazarus.
DAB - FpdServer / LazFPDServerDebugger
A derivative of LazDABDebugger specifically shaped to work with FpdServer, a debugger based on FpDebug that supports the DAB-protocol.

Light bulb  Note:

  • For the GDB and LLDB based debugger, support is indicated based on the assumption that your version of GDB supports this. Support indication is generally based on current GDB/LLDB for mainstream OS.
  • FpDebugger currently only works for Windows and Linux
  • The "LLDB Debugger (Alpha)" is not included below. It is a by-product of the "LLDB+FpDebug". It is not actively developed/maintained, other than what is needed for "LLDB+FpDebug".

Availability (OS/Platform)

OS/Platform GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
Linux Y Y Y Y Depends on availability
of a stable LLDB
Y
Mac Depends on availability
of a stable
and codesigned GDB
? ? ? Y N
Windows Y Y Y Y Depends on availability
of a stable LLDB
Y


Start/Stop

Feature Key GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
Run F9 Y Y Y Y Y Y
Run to first line (Step) F7 / F8 Y Y Y Y ? N For GUI apps the first line is in the code generated by the IDE
Run to line at cursor Y Y Y Y N Y Lazarus 2.2 and higher
Attach Y Y Y Y ? Lazarus 2.2 and higher
Detach Y Y Y Y ? Lazarus 2.2 and higher
Stop Ctrl+F2 Y Y Y Y Y Y
Reset Debugger Y Y Y Y Y Y Kill/Stop
Restart the external debugger (gdb/lldb)
Debugger stopped dialog when app exits Y Y Y Y Y Y Configurable
Run without debugging Ctrl+ Shift+F9 Y Not debugger specific

Execution Control

Feature Key GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
Continue (Run) F9 Y Y Y Y Y Y
Step over line F8 Y Y Y Y Y Y
Step into line F7 Y Y Y Y Y Y
Step (over) to line at cursor F4 Y Y Y Y N Y "STEP OVER" - This works only within the current procedure.

It will go to the selected line, or stop if the current procedure is left.
It will *step* *over* any recursive calls of the procedure, therefore not stopping at the line during recursion.

Run to line at cursor Y Y Y Y N Y Only Lazarus 2.2 and higher
Step out (of current function) Shift+F8 Y Y Y Y Y Y
Step over asm Alt+F8 Y Y Y Y Y Y
Step into asm Alt+F7 Y Y Y Y Y Y
Smart source or asm stepping (over/into) Y Y Y Y Y Y Assign one key (one for "over", one for "into") that acts as source-line or asm stepping, depending on window focus
Pause Y depends on gdb, mostly "No" Y Y Y Y
Step: steps over "none breaking" breakpoint Y Y Y Y ? Lazarus 2.0 or 2.2 ? Any "step" command will continue to its step-end after a "none breaking" Breakpoints. This is a Breakpoint that has its break property turned off. It may record a snapshot, log a message, or enable/disable other breakpoints.
Warning-icon.png

Warning: The "auto-continue" (time based) function may not return to stepping, but instead "run/continue" execution.

Step: steps over ignored exceptions Y Y Y Y ? Lazarus 2.2 Only for standard fpc exception handling. And (Lazarus 2.2) SEH on Win64.

Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).

Source-Step: steps from except to finally or except Y Y Y Y ? Lazarus 2.2 Only for standard fpc exception handling. And (Lazarus 2.2) SEH on Win64.

Win32 and other OS structured exception handling are not supported (Ignored exceptions will turn Stepping into Running).

Executable/Code line indicators Y Y Y Y Y Y Blue dots in the gutter indicate lines with debug info.
Breakpoints / None-breaking breakpoints / Auto-continue breakpoints / Disabled breakpoints
A breakpoint usually pauses your app, in addition it can perform tasks like logging a message (debugger event log), dumping data to the log, taking a snapshot (debugger history).
A none-breaking breakpoint will perform those extra tasks, but not pause your app.
An auto-continue breakpoint will pause your app (and perform any other action) for a given amount of milliseconds (during which you can use the pause button, to pause permanently), after that it will continue your app. It usually continues using "Run", therefore loosing any current single-step action
A disabled breakpoint will do nothing. It is as if it does not exist.
Stepping and breakpoints / exceptions
If any debugger pauses the target-app at a breakpoint or exception while single stepping, then the single-step is lost. The breakpoint/exception may be in a deeply nested called function, and you cannot continue the single-step. I.e. there is no build in way to get back to the function where you started your step, and finish this step. For this you need to go through the callstack yourself and find the start location and use breakpoints
Stepping and none-breaking-breakpoints / Ignored-exceptions
Most/All? debugger backends can in this case continue to the position where the single-step would have ended. (This may be limited for asm stepping). In case of an exception the single step will end at the next finally or except. "Next" from the point of view of the step-command. I.e., any finally inside a "stepped over function" will be stepped over, but any finally on the same level as the step began will be used as end point. If there is none on the same level, then the next outer will be used.
This feature relies heavily on FPC implementation details. Thus it may not work with newer FPC versions.

Breakpoints / Exceptions

Feature Key GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
Breakpoint on Source Line F5 Y Y Y Y Y Y
Breakpoint on Assembler Line Y Y Y Y Y Y
Watchpoint / Breakpoint Data Y Y Y Y ? Partial Amount/Size is limited by architecture

Intel based systems usually have 4 Watchpoints, each with a max size of 32 bit (64 bit on 64bit CPU)

Conditional Break/Watch-point (Y) (Y) (Y) (Y) ? Y GDB based debuggers are limited to GDB's understanding of the conditional expression
Enable/Disable Break/Watch-point according to program flow Y Y Y Y Y Y Enable/Disable a breakpoint (or a group of) when execution passes through a pre-defined point in your code.

So you can setup that the debugger will only break/skip-breaking, when the code is called in a specific order, or from a specific outer subroutine.

Ignore exception by class Y Y Y Y Y Y Configurable for each project
Break/Watch-point overview Window Ctrl+Alt+B Y Y Y Y Y Y
TODO: .... Document Breakpoint properties . . . . . .
TODO: .... Document Breakpoint actions . . . . . .
GdbMi+Ssh
Some functionality depends on the ability to use "Pause". If "Pause" does not work, break/watch-points can not be changed/added/removed while the target app is running. Only when the target app pauses at a breakpoint (or for other reasons), then can changes be made.

Data

Feature Key GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
Watches Ctrl+Alt+W Y Y Y Y Y Y
Locals Ctrl+Alt+L Y Y Y Y Y Y
Stack Ctrl+Alt+S Y Y Y Y Y Y
Threads Ctrl+Alt+T Y Y Y Y Y Y Running State indicator may not be accurate
Inspect Alt+F5 Y Y Y Y Y Y View members in property Grid. Double-click to inspect members
Evaluate / Modify Ctrl+F7 Y Y Y Y ? Only Evaluate
No Modify
Disassembler Ctrl+Alt+D Y Y Y Y ? Partial
Watch/Inspect Class Properties N N N N N N Using "DWARF" properties that refer directly to a field (no getter method) are shown.
Watch/Inspect Function calls N N N N N N
Use Instance type/class Y Y Y Y Y Y By default the debugger shows variables according to their declared type/class.

"Sender: TObject" will only show as TObject.
The debugger can detect the real class of the instance (e.g. a TButton) and show all details

Tooltip / Hint Y Y Y Y Y Y
Tooltip / Hint => Auto-deref pointer Y Y Y Y Y Y
Tooltip / Hint => Use Instance Class Y Y Y Y Y Y
Paste value into Watches window Y Y Y Y Y Y Paste directly into watches window, no need to press "Add new watch"
Drag/Drow value from source-editor to Watches window Y Y Y Y Y Y
TODO: .... Document Watches properties . . . . . .


Other

Feature Key GdbMi GdbMi+Ssh GdbServer GdbMi+FpDebug Lldb+FpDebug Fp-Debugger Comments
History Ctrl+Alt+H Y Y Y Y Y Y Allow to review Watches/Locals/Stack from when your app was previously paused.

This does not restore the state of the application. It only allows to view the value that the debugger evaluated previously.

History - Import / Export Y Y Y Y Y Y
  • Save your debug results for later review.
  • Or send them to a co-worker for feedback
  • Combined with "snapshot" taking breakpoints, you can send a prepared project (watches/breakpoints set) to a co-worker, have them run the project in the debugger, and return the result to you.
Event log Ctrl+Alt+V Y Y Y Y Y Y
View internal debug output Y Y Y Y
partly
? Not applicable View communication with the external debugger. For troubleshooting
Cross debugging 32<>64bit Y Y Y Y
Win-64bit IDE can debug 32 bit target
? Y
Win-64bit IDE can debug 32 bit target
  • Gdb-based: Requires Gdb for target-bitness to be installed, and the "LazGDeBugControl.exe" (included in Lazarus)
  • Fp-Debugger: Not tested on Linux / For Windows, requires Lazarus 2.2
Remote debugging N Y Y N N N
Edit source code while debugging Y Y Y Y Y Y
  • Fully working source editor (with code completion), while debugging
  • Editor keeps track of inserted/deleted lines, so breakpoints can be set to correct location