在gdb中美化打印boost::mpl::string<...>类型

6

我广泛地使用boost::mpl::string<...>类型……足够多以至于在调试时将类型漂亮地打印在gdb中会非常有帮助。

因此……与其像当前那样,gdb显示各个(多字符字面量)组件,不如……

boost::mpl::string<1668248165, 778856802, 778858343, ..., ..., 0, 0, 0, 0, 0, 0>

它将显示相应的字符串值,而不是...

boost::mpl::string<"The way out is through">

我看过用于在gdb中漂亮打印STL容器的gdb宏和python脚本,但我找不到一个用于漂亮打印boost::mpl字符串的方法。有人能帮忙吗?
更新:我添加了+100赏金...我正在寻找一种利用最新的GDB支持通过python进行漂亮打印的解决方案(如此处所述,适用于STL容器)。
1个回答

7
以下是我的解决方案,使用了Boost-Pretty-Printer (https://github.com/ruediger/Boost-Pretty-Printer/wiki):

文件mpl_printers.py:

import printers
import re
import string
import struct

@printers.register_pretty_printer
class BoostMplString:
    "Pretty Printer for boost::mpl::string"
    regex = re.compile('^boost::mpl::string<(.*)>$')

    @printers.static
    def supports(typename):
        return BoostMplString.regex.search(typename)

    def __init__(self, typename, value):
        self.typename = typename
        self.value = value

    def to_string(self):
            s = ''
            try:
                m = BoostMplString.regex.match(self.typename)
                args = string.split(m.group(1), ', ')
                for packed in args: 
                    i = int(packed)
                    if i == 0: 
                        break
                    r = ''
                    while i != 0:
                        i, c = divmod(i, 0x100)
                        r += chr(c)
                    s += r[::-1]
            except RuntimeError:
                s = '[Exception]'
            return '(boost::mpl::string) %s' % (s)

def register_boost_mpl_printers(obj):
    "Register Boost Pretty Printers."
    pass

文件 register_printers.gdb:

python

# Add the following line in your .gdbinit:
# source /usr/local/share/gdb/register_printers.gdb

import sys
sys.path.insert(0, '/usr/local/share/gdb/python')
# You might have these, too
# from libstdcxx.v6.printers import register_libstdcxx_printers
from boost.printers import register_boost_printers
from boost.mpl_printers import register_boost_mpl_printers

# register_libstdcxx_printers(None)
register_boost_printers(None)
register_boost_mpl_printers(None)

end
  • 将 printers.py 和上述的 mpl_printers.py 安装在目录 /usr/local/share/gdb/python/boost 中。
  • 确保您在 /usr/local/share/gdb/python/boost 中有一个 __init__.py 文件(一个空文件就够了)。
  • 将上述的 register_printers.gdb 安装在 /usr/local/share/gdb 中。
  • 在您的 .gdbinit 中添加 'source /usr/local/share/gdb/register_printers.gdb'。

(您可以选择不同的目录)

测试:

#include <boost/mpl/string.hpp>
int main() {
    boost::mpl::string<'hell','o wo','rld'> s;
    return 0;
}

请执行以下命令:gdb Test -ex 'b main' -ex 'r' -ex 'p s' -ex 'c' -ex 'q'

$1 = (boost::mpl::string) 你好世界


非常好用!现在我可以轻松地使用这个方法,用Python美化其他类型名称。谢谢。 - etherice
@etherice请在某一天发布您的打印机。 - user2249683
1
为了澄清指示中的一些部分:printers.pympl_printers.py应该放在一个名为boost的子目录下(即/usr/local/share/gdb/python/boost),这样register_printers.gdb中的模块名称才是有效的。此外,boost子目录必须包含一个__init__.py文件(可以为空),以便Python将其识别为包含模块的目录(否则,您将收到ImportError: No module named boost.printers错误)。 - etherice
Dieter- NP。再次感谢您提供了一个优雅的解决方案,完全符合要求。 - etherice

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接