Skip to content

theg4sh/userver-gdb-pp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Description

This is a gdb pretty-printers for common types of userver-framework. This is experimental feature to debug logical issues, use this code at your own risk. Feel free to make an issue or pull-request.

How it looks when printing a formats::json::Value variable:

$1 = userver::v2_0_0_rc::formats::json::Value(data={"a":[1,{}],"b":[true,false],"c":{"internal":{"subkey":2}},"i":-1,"u":1,"i64":-1.8446744073709552e+19,"u64":18446744073709551614,"d":0.40000000000000002}) 

Supported types

  • formats::json::Value
  • formats::yaml::Value
  • utils::FastPimpl<T>

Dependencies

Fedora: sudo dnf debuginfo-install yaml-cpp-0.7.0-4.fc39.x86_64

Usage

At least you need pull userver-framework and build debug.

git clone --depth 1 https://github.com/userver-framework/userver cd userver mkdir build_debug && cd build_debug cmake -DCMAKE_CXX_COMPILER=clang++-17 -DUSERVER_FEATURE_GRPC=OFF -DUSERVER_FEATURE_POSTGRESQL=OFF \ -DUSERVER_FEATURE_MYSQL=OFF -DUSERVER_FEATURE_STACKTRACE=OFF -DUSERVER_FEATURE_CLICKHOUSE=OFF \ -DUSERVER_USE_LD=lld .. make 

Now gdb needs to be configured regarding Python Auto-Loading documentation for your executable or library. See objfile script objfile-gdb.py and .debug_gdb_scripts sections in References. The way how to do it is left to the user's discretion.

Loading pretty-printers using a script

tools/userver-gdb is a simple bash script to automate gdb configuration in-fly.

Instead of using gdb directly gdb [<gdb-arg>...] --args <executable> [<executable-arg>...] you can run the script:

tools/userver-gdb [<gdb-arg>...] --args <executable> [<executable-arg>...] 

The script will create link objfile-gdb.py in the same directory as the executable file, and it will execute gdb with additional arguments needed to initialize the pretty-printers.

Loading pretty-printers manually

For a better understanding the magic behind the scenes, let's take a look the steps needed to enable pretty-printers for sample/json2yaml.

Basically, we need to tell gdb to set the scripts-directory and safe-path to the path where our executable file is located. For example:

# cd build_debug/ gdb \ -iex "add-auto-load-scripts-directory samples/json2yaml" \ -iex 'add-auto-load-safe-path samples/json2yaml' \ ... 

To make an experiment lets create shell-script gdb-run.sh with the following content:

#!/bin/bash JSON_SAMPLE='r <<<"{\"a\":[1,{}],\"b\":[true,false],\"c\":{\"internal\":{\"subkey\":2}},\"i\":-1,\"u\":1,\"i64\":-18446744073709551614,\"u64\":18446744073709551614,\"d\":0.4}"' # at userver root directory cd build_debug && \ gdb \ -iex "add-auto-load-scripts-directory samples/json2yaml" \ -iex 'add-auto-load-safe-path samples/json2yaml' \ -ex 'b json2yaml.cpp:53' \ -ex $JSON_SAMPLE \ -ex 'p json' \ -ex 'fg' \ -ex 'q' \ --args samples/json2yaml/userver-samples-json2yaml 

After run this script you will see something like:

$ bash ./gdb-run.sh ... Breakpoint 1, main () at userver/samples/json2yaml/json2yaml.cpp:53 53 formats::yaml::Serialize(json.ConvertTo<formats::yaml::Value>(), std::cout); $1 = {holder_ = {static kInvalidVersion = 18446744073709551615, data_ = std::shared_ptr<userver::v2_0_0_rc::formats::json::impl::VersionedValuePtr::Data> (use count 1, weak count 0) = {get() = 0x7ffff3e33010}}, root_ptr_for_path_ = 0x7ffff3e33010, value_ptr_ = 0x7ffff3e33010, depth_ = 0, lazy_detached_path_ = {parent_value_ptr_ = 0x0, parent_depth_ = 0, virtual_path_ = Python Exception <class 'gdb.error'>: There is no member named _M_p. }} ... 

Looks like a mess and useless for debugging a logical issue.

Now prepare pretty-printers:

git clone https://github.com/theg4sh/userver-gdb-pp export USERVER_GDB_PP_DIR="$(readlink -f userver-gdb-pp)" (cd userver/build_debug/samples/json2yaml && \ ln -s $USERVER_GDB_PP_DIR/userver_gdb_pp/__init__.py userver-samples-json2yaml-gdb.py) 

and now check the result:

$ bash ./gdb-run.sh ... Breakpoint 1, main () at /home/arkcoon/repos/theg4sh/userver/samples/json2yaml/json2yaml.cpp:53 53 formats::yaml::Serialize(json.ConvertTo<formats::yaml::Value>(), std::cout); $1 = userver::v2_0_0_rc::formats::json::Value(version=0,data={"a":[1,{}],"b":[true,false],"c":{"internal":{"subkey":2}},"i":-1,"u":1,"i64":-1.8446744073709552e+19,"u64":18446744073709551614,"d":0.40000000000000002}) ... 

That's much better!

References

Releases

No releases published

Packages

No packages published