我想写一个python脚本来分析算法的调试器状态,但是我不知道如何获得索引向量的基本示例。
例如,在调试以下文件(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),该脚本用于打印按名称提供的输入向量的前三个元素:
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])-line。问题是gdb.Value对象不能作为列表进行索引。有没有其他方法可以访问这些元素?
我也尝试过像val['at'][0]和val['at(0)']这样的东西,但它们都不起作用。通过调用gdb.parse_and_eval逐个加载元素,每个元素都可以工作,但速度太慢。
发布于 2019-07-23 20:48:33
我最终在c++11中使用了以下函数:
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]']快得多
发布于 2019-07-22 23:09:06
问题是,向Python公开的C++对象不是“第一类”Python对象-因此,它们不具有Python __getitem__方法,该方法映射到相应的机制以获取对象的"C++“类中的项。
另一方面,API确实公开了一个parse_and_eval方法,它将处理一个字符串,就像它是在C++源代码中键入的一样--因此允许人们以一种简单的方式从Python中使用v[i] -
对于上面的示例,您可以将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__。
https://stackoverflow.com/questions/57147836
复制相似问题