Skip to content

Latest commit

 

History

History
278 lines (209 loc) · 7.95 KB

README.adoc

File metadata and controls

278 lines (209 loc) · 7.95 KB

BoostPrettyPrinters

Branch Drone CI

master

master builds

develop

develop builds

A collection of helpers for convenient use of GDB pretty printers with accompanying build system modules.

Warning
Not an official Boost tool yet!

The core of this project is a couple of utility Python scripts.

  • embed-gdb-extension.py takes a Python GDB extension module (the most common such extesnsion is a set of pretty printers) and produces C code that pushes the contents of that module into a special binary section, so that GDB could automatically load those pretty printers during debugging.

  • generate-gdb-test-runner.py takes C or C++ source files that have special comment lines and creates a Python program that sets breakpoints on those lines to check if printed expressions produce the desired output.

Install

You can just clone or download the sources.

Usage

For convenience of using the provided tools the project also provides a CMake module and a b2 module. For direct usage consult the Direct usage subsection in the API section.

Note, you don’t have to add your build directory to GDB’s autoload safe paths if you are using build system functions. The functions invoke GDB with the necessary flag to enable autoloading of extensions.

CMake

# CMakeLists.txt
find_package(BoostPrettyPrinters)
if(BoostPrettyPrinters_FOUND)
    boost_pretty_printers_embed_gdb_extension(
        TARGET regenerate_printers
        INPUT gdb_printers.py
        OUTPUT include/myproject/gdb_printers.hpp
        EXCLUDE_FROM_ALL)
endif()

# test/CMakeLists.txt
if(BoostPrettyPrinters_GDB_FOUND)
    boost_pretty_printers_test_gdb_printers(
        TEST test_gdb_printers
        SOURCES printers.cpp
        EXCLUDE_FROM_ALL)
    target_link_libraries(test_gdb_printers PRIVATE myproject)
endif()

Note: In order for find_package to find the provided CMake module you need to append the installation directory of PrettyPrinters to CMAKE_MODULE_PATH variable. This is normally done either from the command line or via presets. For example:

cmake -S.. -B. -DCMAKE_MODULE_PATH=path/to/pretty_printers

b2

# build.jam
using boost-pretty-printers ;

import boost-pretty-printers ;
boost-pretty-printers.gdb-python-header gdb_printers.hpp
    : gdb_printers.py
    : <location>include/mymproject
    ;
always gdb_printers.hpp ;
alias regenerate-printers : gdb_printers.hpp ;
explicit regenerate-printers gdb_printers.hpp ;

# test/build.jam
import boost-pretty-printers ;
boost-pretty-printers.test-gdb-printers gdb-printers
    : printers.cpp
      ..//myproject
    ;
explicit gdb-printers ;

API

CMake module

find_package(BoostPrettyPrinters [QUIET])

The package has only one component: GDB.

Imported targets

BoostPrettyPrinters::GDB

The GDB executable to use. This target is defined only if the GDB component is found.

Variables

This module will set the following variables in your project:.

BoostPrettyPrinters_FOUND

True if both the module and a Python 3 Interpreter were found.

BoostPrettyPrinters_GDB_FOUND

True if GDB executable was found.

BoostPrettyPrinters_GDB_EXECUTABLE

The GDB executable to use.

Functions

boost_pretty_printers_embed_gdb_extension
boost_pretty_printers_embed_gdb_extension(
    TARGET target
    INPUT input
    OUTPUT output
    [EXCLUDE_FROM_ALL]
    [FLAGS flags...])

Defines a custom target target that creates a C file output from a Python script input by running embed-gdb-extension.py.

If EXCLUDE_FROM_ALL is set the target will not be added to the default build target.

FLAGS are addtional flags passed to embed-gdb-extension.py, e.g. --header-guard= or --disable-macro=.

boost_pretty_printers_test_gdb_printers
boost_pretty_printers_test_gdb_printers(
    TEST test
    [PROGRAM program]
    SOURCES [srcs...]
    [EXCLUDE_FROM_ALL])
  1. Defines a custom target that creates a Python program from srcs by running generate-gdb-test-runner.py.

  2. Defines executable target program with the provided srcs.

  3. Defines a test test that uses GDB as a Python interpreter for script from step 1 to debug the program from step 2.

If PROGRAM is not set then the executable target’s name is assumed to be the same as test.

If EXCLUDE_FROM_ALL is set then both the executable target and the custom target will not be added to the default build target.

b2 module

using boost-pretty-printers : [path/to/gdb] ;

Rules

has-gdb
rule has-gdb ( )

Returns a true value if GDB program was found.

embed-gdb-extension
rule embed-gdb-extension ( target : sources + : requirements * : usage-requirements * )

Main target rule that creates a C file from a Python script by running embed-gdb-extension.py.

Usually, you would use <location> feature to create the file in the headers directory. Use the <flags> feature to pass additional flags to embed-gdb-extension.py, for example <flags>--header-guard=MYPROJECT_GDB_PRINTERS_HPP.

test-gdb-printers
rule test-gdb-printers ( target : sources + : requirements * : default-build * : usage-requirements * )

Main target rule that

  1. creates a Python program sources by running generate-gdb-test-runner.py;

  2. compiles and links the sources into a program;

  3. runs GDB as a Python interpreter for script from step 1 to debug the program from step 2.

Direct usage

embed-gdb-extension.py

embed-gdb-extension.py input [output] [--header-guard HEADER_GUARD] [--disable-macro DISABLE_MACRO]

Creates a C file that pushes contents of a GDB Python extension file into .debug_gdb_scripts ELF section.

Positional arguments:

input

Input file; must be written in Python.

output

Output file; if not provided, the result is printed to standard output.

Options:

--header-guard

Header guard macro to use; if not provided, the value is deduced from the output file name; to remove the header guard macro use empty value (--header-guard=).

--disable-macro

Macro to disable pretty printer embedding; by default BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS; to remove the disable macro use empty value (--disable-macro=).

generate-gdb-test-runner.py

generate-gdb-test-runner.py input [output]

Creates a Python script from C++ source files to control a GDB test of those source files.

int n = 1;
// TEST_EXPR( 'n', '1' )

The resulting script commands GDB to set a breakpoint on each line with a special comment. Then the script will test that printing the expression in the first argument of TEST_EXPR (e.g. print n) produces the output equal to the second argument of TEST_EXPR (e.g. 1). Note that the breakpoint is set effectively on the next statement. Also note that multiline comments are not supported.

In some cases you need to know some run-time values to know the expected output. In that case you can provide extra arguments to TEST_EXPR. Those will be in turn printed by GDB, and their output will be substituted into the second argument of TEST_EXPR using Python’s str.format:

unsigned char buf[1024];
monotonic_resource mr(buf);
// TEST_EXPR( 'mr', 'monotonic_resource[buffer={0}]', '/a &buf' )

(The option /a tells print to output just the address, without type information).

Positional arguments:

input

Input files.

output

Output file; if not provided, the result is printed to the standard output.

License