GCC Middle and Back End API Reference
gdbhooks Namespace Reference

Data Structures

class  BasicBlockPrinter
class  BreakOnPass
class  CfgEdgePrinter
class  CgraphEdgePrinter
class  DotFn
class  DumpFn
class  DWDieRefPrinter
class  GdbPrettyPrinters
class  GdbSubprinter
class  GdbSubprinterRegex
class  GdbSubprinterTypeList
class  GimplePrinter
class  IpaReferencePrinter
class  MachineModePrinter
class  OptMachineModePrinter
class  PassNames
class  PassPrinter
class  Rtx
class  RtxPrinter
class  SymtabNodePrinter
class  Tree
class  TreePrinter
class  VecPrinter


 intptr (gdbval)
 bb_index_to_str (index)
 GET_RTX_NAME (code)
 build_pretty_printer ()
 find_gcc_source_dir ()


 tree_code_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code'))
 TYPE_DECL = tree_code_dict['TYPE_DECL']
 SSA_NAME = tree_code_dict['SSA_NAME']
 tree_code_class_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code_class'))
 tcc_type = tree_code_class_dict['tcc_type']
 tcc_declaration = tree_code_class_dict['tcc_declaration']

Detailed Description

Enabling the debugging hooks
gcc/configure (from configure.ac) generates a .gdbinit within the "gcc"
subdirectory of the build directory, and when run by gdb, this imports
gcc/gdbhooks.py from the source directory, injecting useful Python code
into gdb.

You may see a message from gdb of the form:
  "path-to-build/gcc/.gdbinit" auto-loading has been declined by your `auto-load safe-path'
as a protection against untrustworthy python scripts.  See

The fix is to mark the paths of the build/gcc directory as trustworthy.
An easy way to do so is by adding the following to your ~/.gdbinit script:
  add-auto-load-safe-path /absolute/path/to/build/gcc
for the build directories for your various checkouts of gcc.

If it's working, you should see the message:
  Successfully loaded GDB hooks for GCC
as gdb starts up.

During development, I've been manually invoking the code in this way, as a
precanned way of printing a variety of different kinds of value:

  gdb \
    -ex "break expand_gimple_stmt" \
    -ex "run" \
    -ex "bt" \
    --args \
      ./cc1 foo.c -O3

Examples of output using the pretty-printers
Pointer values are generally shown in the form:
  <type address extra_info>

For example, an opt_pass* might appear as:
  (gdb) p pass
  $2 = <opt_pass* 0x188b600 "expand"(170)>

The name of the pass is given ("expand"), together with the

Note that you can dereference the pointer in the normal way:
  (gdb) p *pass
  $4 = {type = RTL_PASS, name = 0x120a312 "expand",
  [etc, ...snipped...]

and you can suppress pretty-printers using /r (for "raw"):
  (gdb) p /r pass
  $3 = (opt_pass *) 0x188b600

Basic blocks are shown with their index in parentheses, apart from the
CFG's entry and exit blocks, which are given as "ENTRY" and "EXIT":
  (gdb) p bb
  $9 = <basic_block 0x7ffff041f1a0 (2)>
  (gdb) p cfun->cfg->x_entry_block_ptr
  $10 = <basic_block 0x7ffff041f0d0 (ENTRY)>
  (gdb) p cfun->cfg->x_exit_block_ptr
  $11 = <basic_block 0x7ffff041f138 (EXIT)>

CFG edges are shown with the src and dest blocks given in parentheses:
  (gdb) p e
  $1 = <edge 0x7ffff043f118 (ENTRY -> 6)>

Tree nodes are printed using Python code that emulates print_node_brief,
running in gdb, rather than in the inferior:
  (gdb) p cfun->decl
  $1 = <function_decl 0x7ffff0420b00 foo>
For usability, the type is printed first (e.g. "function_decl"), rather
than just "tree".

RTL expressions use a kludge: they are pretty-printed by injecting
calls into print-rtl.c into the inferior:
  Value returned is $1 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
  (gdb) p $1
  $2 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
  (gdb) p /r $1
  $3 = (rtx_def *) 0x7ffff043e140
This won't work for coredumps, and probably in other circumstances, but
it's a quick way of getting lots of debuggability quickly.

Callgraph nodes are printed with the name of the function decl, if
  (gdb) frame 5
  #5  0x00000000006c288a in expand_function (node=<cgraph_node* 0x7ffff0312720 "foo"/12345>) at ../../src/gcc/cgraphunit.c:1594
  1594    execute_pass_list (g->get_passes ()->all_passes);
  (gdb) p node
  $1 = <cgraph_node* 0x7ffff0312720 "foo"/12345>

Similarly for symtab_node and varpool_node classes.

Cgraph edges are printed with the name of caller and callee:
    (gdb) p this->callees
    $4 = <cgraph_edge* 0x7fffe25aa000 (<cgraph_node * 0x7fffe62b22e0 "_GLOBAL__sub_I__ZN5Pooma5pinfoE"/19660> -> <cgraph_node * 0x7fffe620f730 "__static_initialization_and_destruction_1"/19575>)>

IPA reference follow very similar format:
    (gdb) Value returned is $5 = <ipa_ref* 0x7fffefcb80c8 (<symtab_node * 0x7ffff562f000 "__dt_base "/875> -> <symtab_node * 0x7fffe795f000 "_ZTVN6Smarts8RunnableE"/16056>:IPA_REF_ADDR)>

vec<> pointers are printed as the address followed by the elements in
braces.  Here's a length 2 vec:
  (gdb) p bb->preds
  $18 = 0x7ffff0428b68 = {<edge 0x7ffff044d380 (3 -> 5)>, <edge 0x7ffff044d3b8 (4 -> 5)>}

and here's a length 1 vec:
  (gdb) p bb->succs
  $19 = 0x7ffff0428bb8 = {<edge 0x7ffff044d3f0 (5 -> EXIT)>}

You cannot yet use array notation [] to access the elements within the
vector: attempting to do so instead gives you the vec itself (for vec[0]),
or a (probably) invalid cast to vec<> for the memory after the vec (for
vec[1] onwards).

Instead (for now) you must access the payload directly:
  (gdb) p ((edge_def**)(bb->preds+1))[0]
  $20 = <edge 0x7ffff044d380 (3 -> 5)>
  (gdb) p ((edge_def**)(bb->preds+1))[1]
  $21 = <edge 0x7ffff044d3b8 (4 -> 5)>

Function Documentation

◆ bb_index_to_str()

gdbhooks.bb_index_to_str ( index)

◆ build_pretty_printer()

gdbhooks.build_pretty_printer ( )

References build_pretty_printer().

Referenced by build_pretty_printer().

◆ find_gcc_source_dir()

gdbhooks.find_gcc_source_dir ( )


gdbhooks.GET_RTX_FORMAT ( code)


gdbhooks.GET_RTX_LENGTH ( code)

References intptr().


gdbhooks.GET_RTX_NAME ( code)

◆ intptr()

Variable Documentation


gdbhooks.IDENTIFIER_NODE = tree_code_dict['IDENTIFIER_NODE']

◆ replace



gdbhooks.SSA_NAME = tree_code_dict['SSA_NAME']

◆ tcc_declaration

gdbhooks.tcc_declaration = tree_code_class_dict['tcc_declaration']

◆ tcc_type

gdbhooks.tcc_type = tree_code_class_dict['tcc_type']

◆ tree_code_class_dict

gdbhooks.tree_code_class_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code_class'))

◆ tree_code_dict

gdbhooks.tree_code_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code'))


gdbhooks.TYPE_DECL = tree_code_dict['TYPE_DECL']