Difference between revisions of "Debugging - GDB tricks"

From Free Pascal wiki
(General tricks)
(Stop debugger on exception: fpc_raiseexception loses backtrace on assert(), we need to break on fpc_assert instead)
 
(6 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
= General tricks =
 
= General tricks =
  
* Some pascal specific patches were excepted; so if possible set language to pascal "set language pascal"
+
* Some pascal specific patches were accepted into [[GDB]], so if possible set language to pascal "set language pascal"
 
* To get help, use "help <command>" or "help" to see a category list.
 
* To get help, use "help <command>" or "help" to see a category list.
* To view datastructures raw, use the "x" command (see "help x")
+
* To view datastructures in their raw form, use the "x" command (see "help x")
  
 
== Examining Type Info ==
 
== Examining Type Info ==
Line 16: Line 16:
  
 
== Stop debugger on exception ==
 
== Stop debugger on exception ==
* Q: How to stop gdb on exception
+
* Q: How to stop gdb on exception?
 
* A: b fpc_raiseexception
 
* A: b fpc_raiseexception
  
* Q: How to show call stack
+
* Q: How to stop gdb on assert, and have a backtrace?
 +
* A: b fpc_assert
 +
 
 +
* Q: How to show call stack/backtrace?
 
* A: bt
 
* A: bt
  
Line 29: Line 32:
 
* Delete: d 1
 
* Delete: d 1
 
* Delete all: d b
 
* Delete all: d b
 +
 +
== Pointer ==
 +
When you print the value of a pointer gdb will say something like:
 +
  $0 = (MYPTR) 0x0202
 +
 +
If MYPTR is the correct type, you can just use
 +
 +
  p ptrvar^
 +
 +
if it's not the correct type, you can typecast it:
 +
 +
  p realptrtype(ptrvar)^
 +
 +
If you do not have a separate type for the actual pointer type, but 
 +
only a type for what it points to, then the syntax is somewhat awkward 
 +
because the gdb parser is still showing its C heritage in that case:
 +
 +
  p ^myvartype(ptrvar)^
 +
 +
== Accessing a symbol in a specific unit unitname.identifier ==
 +
 +
If you have several global variables of the same name in different units, GDB will *not* follow pascal scoping rules, but pick whatever it finds first. So you need to specify which one you want.
 +
 +
GDB does not know the unitname.ident syntax. But it can instead take the filename of a unit. (filenames with a dot must be in single quotes)
 +
 +
'unit1.pas'::form1
 +
 +
[[Category:Debugging]]

Latest revision as of 00:30, 21 August 2020

General tricks

  • Some pascal specific patches were accepted into GDB, so if possible set language to pascal "set language pascal"
  • To get help, use "help <command>" or "help" to see a category list.
  • To view datastructures in their raw form, use the "x" command (see "help x")

Examining Type Info

  • Q: What function should I use for dumping the type info?
  • A: Run x/100c in gdb until it frames. then use 'frame <framenr>' to jump to the correct frame

Inspecting an ansistring

  • Q: How do I examine an ansistring?
  • A: "x/s <stringname>"

Stop debugger on exception

  • Q: How to stop gdb on exception?
  • A: b fpc_raiseexception
  • Q: How to stop gdb on assert, and have a backtrace?
  • A: b fpc_assert
  • Q: How to show call stack/backtrace?
  • A: bt

Work with breakpoints

  • Add: b TObject__Method or b filename.pas:123
  • Show: inf b
  • Disable: dis 1
  • Enble: en 1
  • Delete: d 1
  • Delete all: d b

Pointer

When you print the value of a pointer gdb will say something like:

 $0 = (MYPTR) 0x0202

If MYPTR is the correct type, you can just use

 p ptrvar^

if it's not the correct type, you can typecast it:

 p realptrtype(ptrvar)^

If you do not have a separate type for the actual pointer type, but only a type for what it points to, then the syntax is somewhat awkward because the gdb parser is still showing its C heritage in that case:

 p ^myvartype(ptrvar)^

Accessing a symbol in a specific unit unitname.identifier

If you have several global variables of the same name in different units, GDB will *not* follow pascal scoping rules, but pick whatever it finds first. So you need to specify which one you want.

GDB does not know the unitname.ident syntax. But it can instead take the filename of a unit. (filenames with a dot must be in single quotes)

'unit1.pas'::form1