Как избежать рекурсии в нативных визуализаторах? - PullRequest
0 голосов
/ 10 декабря 2018

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

0 голосов
/ 03 января 2019

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

<DisplayString>{{size = {m_nSize}, pointer = {(void*)this}}}</DisplayString>
0 голосов
/ 10 декабря 2018

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

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

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

...