Как избежать рекурсии в нативных визуализаторах?

Я отлаживаю программу на 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))

В результате этого я получаю размеры CPtrArray (и другие) объекты в моем отчете heap_stat:

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

я имею COLUMN объекты, которые имеют CPtrArray атрибут, и я хотел бы знать, какой из них соответствует этому конкретному CPtrArray объект, поэтому я добавил все 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 ...

Как вы можете видеть, рекурсия дает мне огромное количество информации (и сильно снижает производительность моего анализа), поэтому я бы хотел ее избежать, без необходимости расширять каждый COLUMN Объект для просмотра необходимой информации.

Изменить после некоторого продолжения

Поскольку эта проблема выглядела как ошибка в обработке Natvis, я решил написать дубликат поста на веб-сайте MSDN. Этот пост недавно был помечен как "Triaged", что, я надеюсь, означает, что его учли разработчики MSDN.

заранее спасибо

2 ответа

Решение

Рекурсивное расширение выполнено, потому что отладчик знает, что this имеет тип CArray и как этот тип будет отображаться. Если вы просто хотите указатель без расширения, вы можете отказаться от знания CArray введите указатель на void* как в

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

Проблема в том, что вы просите через natvis отобразить это рекурсивно. this будет отображать DisplayString для this и теперь у вас есть бесконечная рекурсия. На самом деле очень немногие файлы natvis имеют this в их DisplayString,

Добавить вместо <Expand> раздел с содержимым массива и другим содержимым, и это не будет повторяться.

Вместо этого вы можете отобразить указатель на данные, это очень легко сделать, если вы хотите иметь какую-то проверку для распознавания идентичных массивов, но с thisвы не сможете получить желаемый результат, потому что он запускает отображаемую строку с указателем.

Другие вопросы по тегам