[英]Indexing c++ vector in python gdb script
我想編寫一個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])
。 問題在於gdb.Value
對象不能被索引為列表。 還有其他訪問元素的方法嗎?
我還嘗試了類似val['at'][0]
和val['at(0)']
,但這兩種方法都不起作用。 通過一次調用gdb.parse_and_eval
來gdb.parse_and_eval
加載元素,每個方法都可以,但是速度太慢。
問題在於,暴露給Python的C ++對象不是“一流” Python對象-因此,它們不具有映射到相應機制以在對象的“ C ++”類中獲取項目的Python __getitem__
方法。
另一方面,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__
。
我最終在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
是gdb.Value
-object拿着std::vector<T>
此函數返回的Python列表gdb.Value
類型的-objects T
。 基於此博客文章: https : //hgad.net/posts/object-inspection-in-gdb/
我發現這要比為所有i
調用gdb.parse_and_eval['v[i]']
快得多
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.