如何避免本机可视化器中的递归?

How to avoid recursion in native visualisers?

我正在调试一个 C++ 程序,其中包含很多 CPtrArray 个对象。
使用自定义的 heap_stat 脚本,我知道 CPtrArray 对象的指针值,其中包含很多条目。

使用本机可视化工具,我确实可以看到每个 CPtrArray 对象中的条目数量,特此是我对应的 natvis 条目:

<Type Name="CArray&lt;*,*&gt;">
  <AlternativeType Name="CPtrArray"/> 
  <DisplayString>{{size = {m_nSize}}}</DisplayString> 

问题是:这显示了元素的数量,而不是指针值。我想到了使用以下 natvis 条目很容易地解决这个问题:

<Type Name="CArray&lt;*,*&gt;">
  <AlternativeType Name="CPtrArray"/> 
  <DisplayString>{{size = {m_nSize}, pointer = {this}}}</DisplayString> 

但是,这向我显示了指针值,还有更多::-)

{size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 {size = , pointer = }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}

有人知道如何避免这种递归吗?

在第一次评论和回答后编辑

我已将我的 heap_stat 脚本改编如下:

if type_name.endswith("CPtrArray"):
  collection_Size = typedVar('CPtrArray', ptr).m_nSize
...
dprintln(("0x" + pointer_format + "\t%s\t Size:[%d]") % (ptr, type_name, collection_Size))

因此,我在 heap_stat 报告中得到 CPtrArray(和其他)对象的大小:

0x0732517c  mfc110u!CStringArray     Size:[0]
0x073256d4  mfc110u!CPtrArray    Size:[584]

我有 COLUMN 个对象,它们具有 CPtrArray 属性,我想知道哪个对应于那个特定的 CPtrArray 对象,因此我添加了所有COLUMN 我手表中的对象 window:

((COLUMN*)0x073256d0)->paData   {size = 584, pointer = 0x073256d4 {size = 584, pointer = 0x073256d4 ...
((COLUMN*)0x07325780)->paData   {size = 0, pointer = 0x01234567 {size = 0, pointer = 0x01234567 ...
((COLUMN*)0x07325830)->paData   {size = 0, pointer = 0x02345678 {size = 0, pointer = 0x02345678 ...

如您所见,递归为我提供了大量信息(并严重降低了我的分析性能),因此我想避免它,而无需扩展每个 COLUMN用于查看所需信息的对象。

一些跟进后编辑

由于这个问题看起来像是 Natvis 处理中的错误,我决定在 MSDN 网站上写一个副本 post。 That post 最近被标记为 "Triaged",我希望这意味着 MSDN 开发人员已将其考虑在内。

提前致谢

问题是您通过 natvis 要求递归显示它。 this 将显示 this 的 DisplayString,现在您有一个无限递归。实际上很少有 natvis 文件在 DisplayString.

中有 this

改为添加包含数组内容和其他内容的 <Expand> 部分,这不会递归。

您可以改为显示指向数据的指针,这很容易实现,如果您想进行某种检查以识别相同的数组,但是使用 this,您将无法得到你想要的结果,因为它用指针触发显示字符串。

递归展开是因为调试器知道 this 是类型 CArray 以及该类型应该如何显示。如果您只想要不扩展的指针,您可以通过将指针转换为 void* 来删除 CArray 类型的知识,如

<DisplayString>{{size = {m_nSize}, pointer = {(void*)this}}}</DisplayString>