首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python gdb脚本中索引c++矢量

在python gdb脚本中索引c++矢量
EN

Stack Overflow用户
提问于 2019-07-22 22:07:05
回答 2查看 513关注 0票数 2

我想写一个python脚本来分析算法的调试器状态,但是我不知道如何获得索引向量的基本示例。

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

代码语言:javascript
复制
#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),该脚本用于打印按名称提供的输入向量的前三个元素:

代码语言:javascript
复制
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()

使用命令:

代码语言:javascript
复制
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

我得到了错误

代码语言:javascript
复制
Python Exception <class 'gdb.error'> Cannot subscript requested type.: 
Error occurred in Python command: Cannot subscript requested type.

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

我也尝试过像val['at'][0]val['at(0)']这样的东西,但它们都不起作用。通过调用gdb.parse_and_eval逐个加载元素,每个元素都可以工作,但速度太慢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-07-23 20:48:33

我最终在c++11中使用了以下函数:

代码语言:javascript
复制
def vector_to_list(std_vector):
    out_list = []
    value_reference = std_vector['_M_impl']['_M_start']
    while value_reference != std_vector['_M_impl']['_M_finish']:
        out_list.append(value_reference.dereference())
        value_reference += 1

    return out_list

如果std_vector是持有std::vector<T>gdb.Value-object,此函数将返回T类型的gdb.Value-objects的python列表。基于这篇博文:https://hgad.net/posts/object-inspection-in-gdb/

我发现这比为所有的i调用gdb.parse_and_eval['v[i]']快得多

票数 0
EN

Stack Overflow用户

发布于 2019-07-22 23:09:06

问题是,向Python公开的C++对象不是“第一类”Python对象-因此,它们不具有Python __getitem__方法,该方法映射到相应的机制以获取对象的"C++“类中的项。

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

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

代码语言:javascript
复制
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__

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57147836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档