From 041f471d82b95372c16042c37e942f71bc438b0a Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Wed, 28 Aug 2024 21:22:43 -0500 Subject: [PATCH] Create GDB pretty printer for offset_ptr, and implement the Unordered customization points --- extra/boost_interprocess_printers.py | 43 ++++++++++++ .../interprocess/interprocess_printers.hpp | 66 +++++++++++++++++++ include/boost/interprocess/offset_ptr.hpp | 1 + 3 files changed, 110 insertions(+) create mode 100644 extra/boost_interprocess_printers.py create mode 100644 include/boost/interprocess/interprocess_printers.hpp diff --git a/extra/boost_interprocess_printers.py b/extra/boost_interprocess_printers.py new file mode 100644 index 0000000..0fb0041 --- /dev/null +++ b/extra/boost_interprocess_printers.py @@ -0,0 +1,43 @@ +# Copyright 2024 Braden Ganetsky +# Distributed under the Boost Software License, Version 1.0. +# https://www.boost.org/LICENSE_1_0.txt + +import gdb.printing + +class BoostInterprocessOffsetPtrPrinter: + def __init__(self, val): + self.val = val + + def to_string(self): + return f"{BoostInterprocessOffsetPtrPrinter.get(self.val)}" + + # This is a simplified and inlined version of `offset_ptr::get()` + def get(offset_ptr): + offset = offset_ptr["internal"]["m_offset"] + pointer = offset_ptr.type.template_argument(0).pointer() + if offset == 1: + return gdb.Value(0).cast(pointer) # nullptr + else: + unsigned_char_pointer = gdb.lookup_type("unsigned char").pointer() + this = offset_ptr.address + return (this.cast(unsigned_char_pointer) + offset).cast(pointer) + + def boost_to_address(offset_ptr): + return BoostInterprocessOffsetPtrPrinter.get(offset_ptr) + + # This is a simplified and inlined version of `offset_ptr::operator+=()` + def boost_next(raw_ptr, offset): + unsigned_char_pointer = gdb.lookup_type("unsigned char").pointer() + pointer = raw_ptr.type + aa = raw_ptr.cast(unsigned_char_pointer) + bb = offset * pointer.target().sizeof + return (aa + bb).cast(pointer) + +def boost_interprocess_build_pretty_printer(): + pp = gdb.printing.RegexpCollectionPrettyPrinter("boost_interprocess") + + pp.add_printer("boost::interprocess::offset_ptr", "^boost::interprocess::offset_ptr<.*>$", BoostInterprocessOffsetPtrPrinter) + + return pp + +gdb.printing.register_pretty_printer(gdb.current_objfile(), boost_interprocess_build_pretty_printer()) diff --git a/include/boost/interprocess/interprocess_printers.hpp b/include/boost/interprocess/interprocess_printers.hpp new file mode 100644 index 0000000..263f964 --- /dev/null +++ b/include/boost/interprocess/interprocess_printers.hpp @@ -0,0 +1,66 @@ +// Copyright 2024 Braden Ganetsky +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +// Generated on 2024-08-16T22:13:13 + +#ifndef BOOST_INTERPROCESS_INTERPROCESS_PRINTERS_HPP +#define BOOST_INTERPROCESS_INTERPROCESS_PRINTERS_HPP + +#ifndef BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS +#if defined(__ELF__) +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Woverlength-strings" +#endif +__asm__(".pushsection \".debug_gdb_scripts\", \"MS\",@progbits,1\n" + ".ascii \"\\4gdb.inlined-script.BOOST_INTERPROCESS_INTERPROCESS_PRINTERS_HPP\\n\"\n" + ".ascii \"import gdb.printing\\n\"\n" + + ".ascii \"class BoostInterprocessOffsetPtrPrinter:\\n\"\n" + ".ascii \" def __init__(self, val):\\n\"\n" + ".ascii \" self.val = val\\n\"\n" + + ".ascii \" def to_string(self):\\n\"\n" + ".ascii \" return f\\\"{BoostInterprocessOffsetPtrPrinter.get(self.val)}\\\"\\n\"\n" + + ".ascii \" # This is a simplified and inlined version of `offset_ptr::get()`\\n\"\n" + ".ascii \" def get(offset_ptr):\\n\"\n" + ".ascii \" offset = offset_ptr[\\\"internal\\\"][\\\"m_offset\\\"]\\n\"\n" + ".ascii \" pointer = offset_ptr.type.template_argument(0).pointer()\\n\"\n" + ".ascii \" if offset == 1:\\n\"\n" + ".ascii \" return gdb.Value(0).cast(pointer) # nullptr\\n\"\n" + ".ascii \" else:\\n\"\n" + ".ascii \" unsigned_char_pointer = gdb.lookup_type(\\\"unsigned char\\\").pointer()\\n\"\n" + ".ascii \" this = offset_ptr.address\\n\"\n" + ".ascii \" return (this.cast(unsigned_char_pointer) + offset).cast(pointer)\\n\"\n" + + ".ascii \" def boost_to_address(offset_ptr):\\n\"\n" + ".ascii \" return BoostInterprocessOffsetPtrPrinter.get(offset_ptr)\\n\"\n" + + ".ascii \" # This is a simplified and inlined version of `offset_ptr::operator+=()`\\n\"\n" + ".ascii \" def boost_next(raw_ptr, offset):\\n\"\n" + ".ascii \" unsigned_char_pointer = gdb.lookup_type(\\\"unsigned char\\\").pointer()\\n\"\n" + ".ascii \" pointer = raw_ptr.type\\n\"\n" + ".ascii \" aa = raw_ptr.cast(unsigned_char_pointer)\\n\"\n" + ".ascii \" bb = offset * pointer.target().sizeof\\n\"\n" + ".ascii \" return (aa + bb).cast(pointer)\\n\"\n" + + ".ascii \"def boost_interprocess_build_pretty_printer():\\n\"\n" + ".ascii \" pp = gdb.printing.RegexpCollectionPrettyPrinter(\\\"boost_interprocess\\\")\\n\"\n" + + ".ascii \" pp.add_printer(\\\"boost::interprocess::offset_ptr\\\", \\\"^boost::interprocess::offset_ptr<.*>$\\\", BoostInterprocessOffsetPtrPrinter)\\n\"\n" + + ".ascii \" return pp\\n\"\n" + + ".ascii \"gdb.printing.register_pretty_printer(gdb.current_objfile(), boost_interprocess_build_pretty_printer())\\n\"\n" + + ".byte 0\n" + ".popsection\n"); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#endif // defined(__ELF__) +#endif // !defined(BOOST_ALL_NO_EMBEDDED_GDB_SCRIPTS) + +#endif // !defined(BOOST_INTERPROCESS_INTERPROCESS_PRINTERS_HPP) diff --git a/include/boost/interprocess/offset_ptr.hpp b/include/boost/interprocess/offset_ptr.hpp index 5619ec3..bbedbbd 100644 --- a/include/boost/interprocess/offset_ptr.hpp +++ b/include/boost/interprocess/offset_ptr.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include #include