Как избежать рекурсии в нативных визуализаторах?
Я отлаживаю программу на C++, которая содержит довольно много CPtrArray
объекты.
Используя настроенный скрипт heap_stat, я знаю значения указателя CPtrArray
объекты, которые содержат много записей.
Используя нативные визуализаторы, я действительно могу видеть количество записей в каждом CPtrArray
объект, настоящим моя соответствующая запись natvis:
<Type Name="CArray<*,*>">
<AlternativeType Name="CPtrArray"/>
<DisplayString>{{size = {m_nSize}}}</DisplayString>
Проблема в том, что это показывает мне количество элементов, но не значение указателя. Я решил решить эту проблему очень просто, используя следующую запись natvis:
<Type Name="CArray<*,*>">
<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
вы не сможете получить желаемый результат, потому что он запускает отображаемую строку с указателем.