Difference between revisions of "Debugging - GDB tricks"

From Free Pascal wiki
Jump to navigationJump to search
(→‎Stop debugger on exception: fpc_raiseexception loses backtrace on assert(), we need to break on fpc_assert instead)
 
(5 intermediate revisions by 5 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 ==
 
== Pointer ==
 
+
When you print the value of a pointer gdb will say something like:  
when you print the value of a pointer gdb will say something like:  
 
 
   $0 = (MYPTR) 0x0202
 
   $0 = (MYPTR) 0x0202
  
Line 44: Line 47:
 
If you do not have a separate type for the actual pointer type, but   
 
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   
 
only a type for what it points to, then the syntax is somewhat awkward   
because the gdb parser is still showing it's C-heritage in that case:
+
because the gdb parser is still showing its C heritage in that case:
  
 
   p ^myvartype(ptrvar)^
 
   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 23:30, 20 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