如何避免本地可视化工具中的递归?

时间:2018-12-10 16:03:53

标签: c++ debugging natvis

我正在调试一个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对象相对应,因此我添加了所有{{ 1}}对象在我的监视窗口中:

COLUMN

如您所见,递归为我提供了大量信息(并且极大地降低了我的分析性能),因此我想避免使用它,而无需为每个对象扩展每个((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 ... 对象查看所需的信息。

进行一些后续修改

由于此问题看起来像是Natvis处理中的错误,所以我决定在MSDN网站上写一篇重复的文章。 That post最近被标记为“ Triaged”,我希望这意味着MSDN开发人员已将其考虑在内。

预先感谢

2 个答案:

答案 0 :(得分:2)

完成递归扩展是因为调试器知道this的类型为CArray,并且该类型将如何显示。如果只希望指针不扩展,则可以通过将指针强制转换为CArray来放弃void*类型的知识,如

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

答案 1 :(得分:0)

问题是您要求通过natvis递归显示此内容。 this将显示this的DisplayString,现在您可以进行无限递归了。实际上,很少有natvis文件的this中有DisplayString

使用数组内容和其他内容添加<Expand>节,这将不会递归。

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