python - 在 python gdb 脚本中索引 c++ vector

标签 python c++ gdb

我想编写一个 python 脚本来分析算法的调试器状态,但我不知道如何让索引 vector 的基本示例起作用。

例如调试如下文件(gdb_test.cpp)时:

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::cout << v.size() << std::endl;
    for (const auto& element : v)
    {
        std::cout << element << std::endl;
    }
}

使用 gdb 并获取以下脚本 (print_vector.py),该脚本旨在打印出名称提供的输入 vector 的前三个元素:

import gdb
class print_vector(gdb.Command):
    def __init__(self):
        super(print_vector, self).__init__('print_vector',
                                           gdb.COMMAND_SUPPORT,
                                           gdb.COMPLETE_FILENAME)

    def invoke(self, arg, from_tty):
        # Access the variable from gdb.
        frame = gdb.selected_frame()

        args = arg.split('; ')
        val = frame.read_var(args[0])

        for i in range(3):
            print(val[0])
print_vector()

使用命令:

g++ gdb_test.cpp -std=c++11 -g
gdb ./a.out
(gdb) b gdb_test.cpp:10
(gdb) r
(gdb) source print_vector.py
(gdb) print_vector v

我得到了错误

Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
Error occurred in Python command: Cannot subscript requested type.

这是指 print(val[0]) 行。问题是 gdb.Value 对象不能作为列表进行索引。还有其他方法可以访问元素吗?

我也尝试过 val['at'][0]val['at(0)'] 之类的方法,但都不起作用。通过一次调用 gdb.parse_and_eval 逐一加载元素,每个元素都有效,但速度太慢。

最佳答案

问题是暴露给 Python 的 C++ 对象不是“第一类”Python 对象——因此,它们没有映射到相应机制以获取项目的 Python __getitem__ 方法在对象的“C++”类中。

另一方面,该 API 确实公开了一个 parse_and_eval 方法,该方法将处理一个字符串,就好像它是在 C++ 源代码中键入的一样 - 因此允许使用 v[i] 以一种简单的方式来自 Python -

对于上面的示例,您可以将 Python 源更改为:

import gdb
class print_vector(gdb.Command):
    def __init__(self):
        super(print_vector, self).__init__('print_vector',
                                           gdb.COMMAND_SUPPORT,
                                           gdb.COMPLETE_FILENAME)

    def invoke(self, arg, from_tty):
        # Access the variable from gdb.
        frame = gdb.selected_frame()

        args = arg.split('; ')
        valname = args[0]

        for i in range(3):
            content_value = gdb.parse_and_eval(f"{valname}[{i}]")
            print(int(content_value))
print_vector()

看到这个工作。对于更复杂的代码,可能值得在 Python 中为 gdb.Value 对象创建一个包装类,它将实现一个自动执行此操作的 __getitem__

关于python - 在 python gdb 脚本中索引 c++ vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57147836/

相关文章:

python - 在一个散点图中绘制两个 pandas 数据框

python - Keras 中的反展平层

assembly - jmp x86 解释

debugging - 如何让gdb每次启动时都运行用户定义的函数(在.gdbinit中定义)?

linux - 从命令输出在 GDB 中设置环境变量

python - 如何在不带括号调用的函数中传递参数?

python - 该问题要求根据字典检查列表并在列表中未出现在字典中的项目之前添加 *

c++ - 插入稀疏矩阵时出现问题

c++ - llvm clang 2.6 : "not using the clang compiler for C++ inputs "

c++ - 如何在一个DLL中找到哪个进程加载了它?