我想编写一个 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/