我可以直接在 gdb 漂亮打印机中调用程序的“operator[]”吗?

发布于 2024-12-22 06:53:17 字数 569 浏览 2 评论 0原文

我正在尝试使用 GDB 漂亮的打印功能来显示自定义 C++ 矩阵类。

该课程非常标准,您可以在任何地方找到。它是一个由类型参数化的模板,可以使用 mat[i][j] 等 C 类型表示法来访问。首先隐式返回另一个表示行或列的模板“Slice”类,它可以再次由 [] 运算符访问以提取数据。该类本身使用普通的 C 数组进行存储,但它在其上实现了一些技巧,例如预分配更大矩阵的选项、启用非零开始、使用跨步等。该类没有本机打印接口,我无法修改它,也无法轻松链接到我自己的代码。

自定义功能使得在 Python 中重现直接数据访问代码变得很痛苦。但这有必要吗?一般来说:为什么漂亮的打印应该重现访问数据的逻辑?我不能只使用 C++ 调用并使用 [] 运算符来打印第 i,j 个元素吗?事实上,在此类请求期间,Slice 类是 GDB 中的临时类,这一事实使情况变得更加复杂。

我也是 python 和 GDB 脚本的初学者。我尝试破解示例以用 gdb.execute 调用替换数据访问,但我不知道如何从 to_string 函数访问对象名称,因此我可以使用类似 gdb.execute(??? + '[] +str(i)+']',假,真)。

我想知道最有效的方法是什么。

I am trying to use the pretty printing facilities of GDB to show a custom C++ matrix class.

The class is quite standard you can find anywhere. It is a template parameterized by the type, and can be accessed with C-type notation like mat[i][j]. This first implicitly returns another template "Slice" class representing a row or a column, which can again accessed by the [] operator to extract the data. The class itself is using a plain C array for storage, but it is implementing some tricks on it, like an option of pre-allocating a larger matrix, enabling non-zero starts, using stride etc. The class does not have a native printing interface, and I cannot modify it, or link with my own code easily.

The custom features make it painful to reproduce the direct data access code in Python. But is that necessary? In general: why should pretty printing reproduce the logic of accessing the data? Cannot I just use C++ calls and use the [] operators to print the i,j-th element? The fact that the Slice class is a temporary in GDB during such a request further complicates this.

I am also quite a beginner with python and GDB scripting. I have tried to hack the examples to replace data access with gdb.execute calls, but I have no idea how to access the object name from the to_string function, so I can use something like gdb.execute(??? + '[]+str(i)+']', False, True).

I wonder what is the most effective way of doing this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

居里长安 2024-12-29 06:53:17

我不能只使用 C++ 调用并使用 [] 运算符来打印第 i,j 个元素吗?

您可以使用 gdb.parse_and_eval 从漂亮打印机调用下级(正在调试)进程(docs),但这有几个缺点:

  • 您需要一个“实时”进程来执行此操作(换句话说,当您调试核心转储)
  • 如果下级以某种方式损坏,
  • 如果下级是多线程的,并且漂亮的打印机调用可能需要锁的函数(例如 malloc),那么你很可能会导致漂亮打印机死锁,并且没有任何方法可以从这种死锁中恢复。

Cannot I just use C++ calls and use the [] operators to print the i,j-th element?

You can call from the pretty-printer into the inferior (being debugged) process using gdb.parse_and_eval (docs), but this has several disadvantages:

  • you need a "live" process to do this (in other words, your pretty printer will not work when you are debugging a core dump)
  • if the inferior is corrupt in some way, calling functions in it will likely corrupt it even more
  • if the inferior is multi-threaded, and the pretty printer calls into a function that may require a lock (e.g. malloc), then you are very likely to cause the pretty printer to deadlock, and there would not be any way to recover from such deadlock.
此刻的回忆 2024-12-29 06:53:17

这不是 python 脚本,而是 GDB 扩展的简单命令序列。我正在定义一个名为 print_matrix 的新命令。

(gdb) define print_matrix
Type commands for definition of "print_matrix".
End with a line saying just "end".
>set $s_arr = $arg0
>set $i=0
>while($i < $arg1)
 >p (int [][$arg2]) *($s_arr + $i)
 >set $i = $i + 1
 >end
>end
(gdb) print_matrix arr 10 10
$90 = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
$91 = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
$92 = {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}
$93 = {{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}
$94 = {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}
$95 = {{5, 6, 7, 8, 9, 10, 11, 12, 13, 14}}
$96 = {{6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}
$97 = {{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}
$98 = {{8, 9, 10, 11, 12, 13, 14, 15, 16, 17}}
$99 = {{9, 10, 11, 12, 13, 14, 15, 16, 17, 18}}
(gdb)

您还可以将这些命令保存为脚本并使用 -x 选项

gdb -x <commands file name> binary.out

This is not python scripting, but simple command sequences for GDB extension. I am defining a new command called print_matrix.

(gdb) define print_matrix
Type commands for definition of "print_matrix".
End with a line saying just "end".
>set $s_arr = $arg0
>set $i=0
>while($i < $arg1)
 >p (int [][$arg2]) *($s_arr + $i)
 >set $i = $i + 1
 >end
>end
(gdb) print_matrix arr 10 10
$90 = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
$91 = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
$92 = {{2, 3, 4, 5, 6, 7, 8, 9, 10, 11}}
$93 = {{3, 4, 5, 6, 7, 8, 9, 10, 11, 12}}
$94 = {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13}}
$95 = {{5, 6, 7, 8, 9, 10, 11, 12, 13, 14}}
$96 = {{6, 7, 8, 9, 10, 11, 12, 13, 14, 15}}
$97 = {{7, 8, 9, 10, 11, 12, 13, 14, 15, 16}}
$98 = {{8, 9, 10, 11, 12, 13, 14, 15, 16, 17}}
$99 = {{9, 10, 11, 12, 13, 14, 15, 16, 17, 18}}
(gdb)

You could also save these commands as a script and use -x option

gdb -x <commands file name> binary.out
清眉祭 2024-12-29 06:53:17

我不知道如何在 to_string 函数中获取变量的名称,但是您可以获取该值的地址(如果它是可寻址的)并且可以获得它的类型。 (有关更多信息,请参阅文档。)

有了这个,您可以获取地址并将其转换为指向给定类型的指针并访问它。例如,我使用以下代码在参数上调用 toStyledString().c_str()

eval_string = f"(({self.val.type.name}*)self.val.address})->toStyledString().c_str()"
return gdb.parse_and_eval(eval_string).string()

在您的情况下,您可能需要如下所示的内容:

eval_string = f"(*(({self.val.type.name}*)self.val.address}))[{i}]"

I don't know of a way to get the name of the variable in the to_string function, but you can get the address of the value (if it is addressable) and you can get it's type. (See the docs for more information.)

With this, you can take the address and cast it to pointer to the given type and access it. For example, I used the following to call toStyledString().c_str() on the argument:

eval_string = f"(({self.val.type.name}*)self.val.address})->toStyledString().c_str()"
return gdb.parse_and_eval(eval_string).string()

In your case, you probably want something like the following:

eval_string = f"(*(({self.val.type.name}*)self.val.address}))[{i}]"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文