GDB Debugger Tips

From Lazarus wiki
Jump to navigationJump to search

Introduction

Lazarus comes with GDB as default debugger.

Currently (Lazarus 0.9.26) not all features are implemented, and some things are not supported by GDB. Development is ongoing.

Below are a few of the existing issues (including workarounds where available), that can be encountered while using the debugger.

Properties

Update: With fpc 2.3.1 some of this changed. See the FAQ.

GDB has no concept of pascal-like properties. In addition some properties do have a "read" declaration that points to a function, rather than to a variable. Or they may not have a read declaration at all.

If properties point to a Function, there is currently no work around. Code evaluation is currently not supported. Also remember that it would be dangerous to call the function from the debugger (outside the normal flow of the application). This can modify the state of the application (a function may change other objects)

If a property refers to a variable then you can use the "watch"-window and inspect the variable directly. Usually this is done by prefixing it with a "F" ("property Text : String read FText")

Unfortunately this means you have to use the watch-window, you can not hover the mouse over a property in the source)

Nested Procedures / Function

(Works in 0.9.29)


Procedure SomeObject.Outer(NumText: String);
var OuterNum: integer;
  Procedure Nested;
  begin
    self.Num := Outernum;
  end
begin
  OuterNum := StrToInt(NumText);
  Nested;
end

While the "Nested" code is executed, GDB can only see the Stackframe of that Procedure. This Stackframe does *not* contain NumText, OuterNum nor self. (Since "self" is not visible to GDB, Self.Num (or just Num, or anything else on the object) is also not visible, and can not be inspected)

You will also note that the "local variable" window will not show anything belonging to the outer procedure. (Despite GDB being unable to show the info, it is available to your program and execution works)

If you need to inspect those values while in "Nested", you can open the "Stack" window, and use the "current"-button (or context menu) to change the current stackframe to the "Outer" procedure.

You can then see all the values (using the "watches" or the "local variables" window, or hints by hovering the mouse over variables in the source). Executing your app, or stepping to the next instruction, will set the current stack fram back to the "Nested" procedure.

Variables treated as pointer

Sometimes Variables are pointers in GDB, where they are not in Pascal.

if you type SomeObject as a watch it may just say "TSomeClass 0x23ab76". Try typing SomeObject^

Dynamic Arrays

FPC 2.2.4

See the following post for a workaround (it may be too complex for every day use, but it may help for desperate occasions) http://forum.lazarus.freepascal.org/index.php/topic,4763.msg22954.html#msg22954

to look at Array of String try this:

PChar(^LONGINT(^LONGINT(@t)^+0)^)
PChar(^LONGINT(^LONGINT(@t)^+4)^)
PChar(^LONGINT(^LONGINT(@t)^+8)^)

Each string needs an increase of 4 in the offset, so the above are the string at index: 0, 1, 2

and for the length of array (minus 4)

^LONGINT(^LONGINT(@t)^-4)^

FPC 2.3.1

Under fpc 2.3.1 I found the following for some arrays. (using stabs) type

 TStringArray: Array of String;

var

 a: TStringArray

Can be monitored (watch window) using

a^[0]
a^[1]

So you have to add an extra "^"

if you have var

 a : Array of String;

You can view it (but you must have TStringArray declared in your source, and maybe used somewhere, so it was forced into debug info:

TStringArray(@Text)^[0]

If you do not have TStringArray

 Pchar((^Ptrint(@Text)+0)^)
 Pchar((^Ptrint(@Text)+1)^)

Whatever expression you enter in watches: make sure, there are no spaces in it.

Hardware exceptions under Mac OS X

When a hardware exception occurs under Mac OS X, such as an invalid pointer access (SIGSEGV) or an integer division-by-zero on Intel processors, the debugger will catch this exception at the Mach level. Normally, the system translates these Mach exceptions into Unix-style signals where the FPC run time library handles them. The debugger is however unable to propagate Mach exceptions in this way.

The practical upshot is that it is impossible under Mac OS X to continue a program in the debugger once a hardware exception has been triggered. This is not FPC-specific, and cannot be fixed by us.