GDB Debugger Tips

From Lazarus wiki
Revision as of 20:05, 4 October 2012 by Martin (talk | contribs) (Reporting Bugs)

Introduction

Lazarus comes with GDB as default debugger.

  • This page is for Lazarus 1.0. For older versions see [previous version of this page]
  • Note on GDB 7.5: GDB 7.5 is not supported by the released 1.0. Fixes to support it were made in 1.1.

See also

Setup

To get the best possible results, you must ensure that your IDE and Project are both correctly configured.

See Debugger Setup how to set up the IDE and your project in order to use the debugger.

Setup Video Tutorial

Other

Debugging console applications

General

Debug Info Type

When debugging 64 bit applications, it may be necessary to use dwarf.

Stabs

-g or -gs

You should only use if your gdb version does not support dwarf. There are very few other cases where you need it.

You may need it with "var param" (param by ref) procedure foo(var a: integer); However the IDE deals with this in 99% of all cases.

Dwarf

This is the recommended setting.

-gw

use with -godwarfsets if you have a recent gdb. Otherwise sets are not displayed correctly.

Differences

This list is in no way complete:

  • dwarf allows some properties (those directly mapped to a field)
  • stabs (and modern gdb) can do -gp (preserve the case of symbols, instead of getting the all caps stuff).
  • stabs has problems with some class type casts. The IDE fixes that in some cases. (Only affects gdb 7.0 and up) [1]

Inspecting Data-types (Watch/Hint)

Strings

GDB does not know the pascal string data type. The type information GDB returns, hdoe not currently allow for the IDE to differentiate between a PChar (index is 0 based) or a String (index is 1 based).

As a Result "mystring[10]" could be the 10th char in a string, or 11th in a PChar.

Because the IDE can not be sure which one applies, it will show both. The 2 results will be prefixed String/PChar.


Properties

Currently the debugger does not support any method execution. Therefore only properties that refer directly to a variable can be inspected. (This only works if using dwarf)

TFoo = Class
private
  FBar: Integer;
  function GetValue: Integer;
public
  property Bar: Integer read FBar;        // Can be inspected (if Dwarf is used)
  property Value: Integer read GetValue;  // Can *not* be inspected
end;

Nested Procedures / Function

procedure SomeObject.Outer(NumText: string);
var 
  OuterVarInScope: Integer;

procedure Nested;
var 
  I: Integer;
begin
  WriteLn(OuterVarInScope);  
end;

var 
  OuterVarOutsideScope: Integer;

begin
  Nested;
end;

If you step into "Nested", then the IDE allows you to inspect variables from both stack-frames.

This is you can inspect: I, OuterVarInScope, NumText (without having to change the current stack frame, in the stack window)

However there are some caveats:

You can also inspect: OuterVarOutsideScope. That is against pascal scoping rules. This only matters, if you have several nested levels, and they all contain a variable of the same name, but the pascal scoping would hide the variable from the middle frame. Then you get to see the wrong value.

You can not evaluate statements across the 2 frames: "OuterVarnScope-I" does not work.

Arrays

array [x..y] of Integer;

shows as chars, instead of int. Only gdb 7.2 or up seems to handle it correct.

Additionally there may be issues, when using arrays of (unnamed) records.

Dynamic Arrays will only show a limited amount of their data. As of Lazarus 1.1 the limit can be specified.

Windows

Error 193 (Error creating process / Exe not found)

For details see here. This issue has been observed under Win XP and appears to be a caused by Windows itself. The issue occurs if the path to your app has a space, and a 2nd path/file exists, with a name identical to the part of the path before the space. E.g.

Your app: C:\test folder\project1.exe
Some file: C:\test

SigSegV - even with new, empty application

Note
In most cases SigSegV is simply an error in your code.

The following applies only, if you get a SigSegv, even with a new empt application (empty form, and no modifications made to unit1).

A SigSegV sometimes can be caused by an incompatibility between GDB and some other products. It is not known if this is a GDB issue or caused by the other product. There is no indication that any of the products listed is in anyway at fault. The information provided may only apply to some versions of the named products:

Comodo firewall
http://forum.lazarus.freepascal.org/index.php/topic,7065.msg60621.html#msg60621
BitDefender
enable game mode

SigSegV - and continue debugging

http://sourceware.org/bugzilla/show_bug.cgi?id=10004

http://forum.lazarus.freepascal.org/index.php/topic,18121.msg101798.html#msg101798

gdb.exe has stopped working

GDB itself has crashed. This will be due to a bug in gdb, and may not be fixable in Lazarus. Still it may be worth submitting info (see section "Reporting Bugs" below). Maybe Lazarus can avoid calling the failing function.

There is one already known situation. GDB (6.6 to 7.4 (latest at the time of testing)) may crash while your app is being started. This happen while the libraries (DLL) for your app are loaded (watch the "Debug output" window). In this case go to the debugger options and in the field "debugger_startup_options" enter:

--eval-command="set auto-solib-add off"


"PC register is not available" ("SuspendThread failed. (winerr 5)")

GDB may fail with this message. This is due to http://sourceware.org/bugzilla/show_bug.cgi?id=14018 If you get this issue you may want to downgrade to gdb 7.2

Win 64 bit

  • Requires Lazarus 1.0 with fpc 2.6
  • Advised to use dwarf

Using 32 bit Lazarus on 64 bit Windows

Alternatively it should be possible to debug apps as 32 bit apps (using the 32bit version of gdb). Once successfully debugged the app can then be cross-compiled to 64 bit. (or a 2nd Lazarus installation can be used, but it must be ensured they use different configuration --primary-config-path option)

If installing the 32 bit Lazarus, ensure you change configuration so the correct fpc, and gdb are used.

-

See also http://forum.lazarus.freepascal.org/index.php/topic,13188.0/topicseen.html

Linux

Known Problems

There might be issues on at least some CPUs when using an old version of gdb (e.g. SPARC, with gdb 6.4 as supplied by Debian "Etch"). In particular, background threads might lock up even if the program appears to run correctly standalone.

Mac OSX

Under OSX you usually install GDB with the Apple developer tools. The version of GDB available at the time of writing this is 6.3.50

This section is a first approach to collect information about known issues and workarounds. The information provided here depends a lot on feedback from OSX users.

Known Problems

Debugging 32 bit app on 64 bit architecture

It is possible and maybe sometime necessary to debug a 32 bit exe on a 64 bit system.

This is only possible with Lazarus 0.9.29 rev 28640 and up. As of Dec 2010 this feature is relatively new, and little tested. You may experience problems.

TimeOuts (64 Bit only)

It appears that certain commands are not correctly (or incompletely) processed by gdb 6.3.50. Normally GDB finishes each command with a "<gdb>" prompt for the next command. But the version provided by apple sometimes fails to do this. In this case the IDE will have to use a timeout to avoid waiting forever.

This has been observed with:

  • Certain Watch expressions (at least if the watched variable was not available in the current selected function)
  • Handling an Exception
  • Inserting breakpoints (past unit end / none code location)

It can not be guaranteed:

  • that GDB will not later return some results from such a command
  • that GDB's internal state is still valid

The prompt displayed for timeouts can be switched off in the debugger config.

Warn On Timeout
True/False. Auto continue, after a timeout, do not show a warning.
TimeOutForEval
Set in milliseconds, how long until a timeout detection is triggered (the detection itself may take some more time.)

You may need to "RESET" the debugger after those changes are made

More info see her:

An alternative solution seems to be to use a newer version of GDB (e.g. MacPorts. But this currently fails on other issues)

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.

Using Alternative Debuggers

You can download GDB 7.1 (or later) from MacPorts

The following observations have been made:

  • MacPort GDB 7.1 seems to have issues with the stabs debug info from fpc.
Make sure you select "generate dwarf debug information (-gw)" on the linking tab of the project options
Watch out for the linker warnings about "unknown stabs"
If you still have problems ensure that no code at all, is compiled with stabs. Your LCL may contain stabs, and this will end up in your app, even if you compile the app with -gw. So you may have to recompile your LCL with -gw (or without any debug info). Same for any other unit, package, rtl, .... that may have stabs
  • MacPort GDB 7.1 seems to be unable to handle application-bundles. In order to debug your app, you must use "run param" to specify the actual executable inside the app-bundle ( project.app/Content/MacOs/project or similar)

Even with those rules followed, MacPort GDB does not always work with fpc compiled apps.


Those observations may be incomplete or wrong, please update them, if you have more information.

Links

  • Mac OS X comes with a lot of useful tools for debugging and profiling. Just start /Developer/Applications/Instruments.app and try them out.

Reporting Bugs

Check existing Reports

Please check each of the following links

Bugs in GDB

Create a new Report

If you have at any time in the past updated, changed, reinstalled your Lazarus then please check the "Options" dialog ("Environment" or "Tools" Menu) for the Version of GDB and FPC used. They may still point to old settings.

Basic Information

  • Your Operating system and Version
  • Your CPU (Intel, Power, ...) 32 or 64 bit
  • Version of
    • Lazarus (Latest Release or SVN revision) (Include setting used to recompile LCL, packages or IDE (if a custom compile Lazarus is used))
    • FPC, if different from default. Please check the "Options" dialog ("Environment" or "Tools" Menu)
    • GDB, please check the "Options" dialog ("Environment" or "Tools" Menu)
  • Compiler Settings: (Menu: "Project", "Project Options", indicate all settings you used )
    • Page "Code generation"
Optimization settings (-O???): Level (-O1 / ...) Other (-OR -Ou -Os) (Please always test with all optimizations disabled, and -O1)
  • Page "Linking"
Debug Info: (-g -gl -gw) (Please ensure that at least either -g or -gw is used)
Smart Link (-XX); This must be OFF
Strip Symbols (-Xs); This must be OFF

Log info for debug session

Start Lazarus with the following options:
 -debug-log=LOG_FILE  --debug-enable=DBG_CMD_ECHO,DBG_STATE,DBG_DATA_MONITORS,DBGMI_QUEUE_DEBUG,DBGMI_TYPE_INFO
On Windows
you need to create a shortcut to the Lazarus exe (like the one on Desktop) and edit it's properties. Add " --debug-log=C:\laz.log --debug_enable=..." to the command line.
On Linux
start Lazarus from a shell and append " --debug-log=/home/yourname/laz.log --debug_enable=..." to the command line
On Mac/OSX
start Lazarus from a shell /path/to/lazarus/lazarus.app/Content/MacOS/lazarus --debug-log=/path/to/yourfiles/laz.log --debug_enable=...

Attach the log file after reproducing the error.


If you can not generate a log file, you may try to open the "Debug output" window (from menu "View", "Debug windows").You must open this before you run your app (F9). And then run your app. Once the error occurs, copy, zip, and attach the content of the "debug output" window.