2009-02-04 2 views
3

Ищете быстрый и грязный способ идентификации вызывающего объекта конструктора (или любой функции, если на то пошло) Я пишу макросы, чтобы помочь идентифицировать утечки памяти, сбросив указатели this на OutputDebugString.Поиск вызывающего конструктора в C++

Знание того, откуда были вызваны ctor и dtor, поможет определить проблему.

Тпх \ 0

+0

«OutputDebugString» звучит как функция Windows API. Я предлагаю добавить «окна» или аналогичный тег. – foraidt

ответ

6

Лучшим способом я могу думать о том, чтобы запустить программу в отладчике и поставить точку останова в конструкторе. Затем изучите стек вызовов.

Если вы хотите целевую один конкретное распределение в одном конкретном классе, вы можете держать счет распределения и увидеть, распределение числа не получаете свободу. Запустите программу еще раз и сломайте правый номер выделения.


Если вам нужно иметь стек вызовов сбрасывали в журнал, я знаю, что можно создавать дамп стека, используя, например, win32 API. Более общий подход заключался бы в том, чтобы поддерживать явный стек вызовов как глобальное/зависящее от потока состояние, например, в объекте std::vector<std::string>. (Используйте RAII для обеспечения того, чтобы каждый push_back сопровождался pop_back)

+0

Не работает, если этот конструктор получает много раз, и только одна из вызывающих функций забывает убирать ... –

+0

graham.reeds: True. Я добавил небольшой абзац об использовании счетчика распределения. –

2

Для этого нет быстрого и грязного способа, C++ не предлагает никакого портативного способа поиска в трассировке стека. Если вы хотите найти утечки памяти, я бы рекомендовал посмотреть на valgrind и аналогичные инструменты, они отлично справятся. В качестве руководства по кодированию избегайте утечек памяти в первую очередь с помощью RAII (у вас всегда есть владелец ресурса).

+0

Не обижайтесь, но я не понимаю, как вы пришли к выводу, что быстрый и грязный способ (сделать что-то вроде этого, который, скорее всего, останется в коде только временно), действительно должен быть * переносимым * :) – Reunanen

+0

: D jepp, вы прямо сейчас на вашем слепом месте ... – gimpf

0

Вы работаете под Windows? Visual Leak Detector помог мне в прошлом найти утечки памяти.

Использование RAII помогает уменьшить утечку памяти тоже.

Если вы чувствуете себя авантюристом, вы можете перегрузить новые и удалить функции. Paul Nettle does this in his MMGR.

0

Можете ли вы манипулировать ctor и dtor? Я не разработчик на C++, и вы должны легко это увидеть, но, возможно, в этом случае вы можете передать, например, ссылку на вызывающего объекта на конструктор.

1

Если вы используете Linux, то Valgrind делает все, что вы хотите, и многое другое. Я считаю это незаменимым при разработке на C++.

0

В принципе нет, вместо того, чтобы сохранять все выделения/открепление и узнать, кто don't свободные объекты/областей.

Смотреть это отвечает
Heap corruption under Win32; how to locate?

хороший замок.

0

советовании использовать отладчик и стек вызовов звук и, вероятно, самое лучшее решение возможно. Однако, если у вас нет отладчика, это не поможет.

вы знаете calling convention используется для конструктора ли? Если это так, вы можете использовать некоторый встроенный ассемблер (если ваш компилятор его поддерживает), чтобы проверить порядок вызовов функций.При вызове std наиболее распространенное соглашение для Win32, выбирая стек, покажет указатель на адрес, возвращаемый после того, как функция была вызвана (т. Е. Какое-то место в вызывающей функции). Это не идеально, но вы можете вернуться назад с этой точки, пока не достигнете адреса, который, как вам известно, станет началом функции. Единственная проблема заключается в том, что вам нужно получить адреса для всех ваших функций, чтобы это сделать ... это можно сделать, используя простой трюк, чтобы получить значение eip в другой регистр прямо в верхней части функции , затем переместить это значение в массив сверять позже при отладке, что-то вроде (синтаксис Intel):

call label 
label: 
pop eax 
mov [address of next array entry], eax 
0

Если вы используете г ++, вы можете создать свой проект для покрытия. Когда вы запускаете некоторый пример кода, вы можете просмотреть охват своей программы, используя gcov.

Этот вывод включает дерево вызовов, и вы должны иметь возможность видеть вызовы конструкторам и функциям, которые их вызывают.

Единственный недостаток, о котором я могу думать, это то, что вы получите только результат для фактически выполненного кода, и поэтому вам понадобятся хорошие тестовые примеры. При этом выполнение анализа покрытия в любом случае стоит того. Наконец, я очень рекомендую вам использовать lcov для просмотра результатов!

8

Если вы используете визуальную студию, вы можете присоединить отладчик и вместо того, чтобы иметь точку останова, имеет точку трассировки. Вы делаете это, щелкнув правой кнопкой мыши точку останова и выбрав When Hit.... Затем выберите для печати сообщения, включая трассировку стека. Это сообщение будет отправлено на панель вывода, и вы сможете анализировать все звонки в свободное время.

hit-point http://lanzkron.googlepages.com/hit-point.jpg

3

Это, кажется, вы на окнах (OutputDebugString). Таким образом, вы можете использовать api-файл StackWalk64 для получения stacktrace. Для получения дополнительной информации см. Вопрос «Printing the stack trace in C++ (MSVC)».

Существует также множество средств обнаружения утечек (BoundsChecker и т. Д.).

0

Спасибо всем за отзыв. ставить точку прерывания в ctor не является вариантом из-за сотен вызовов новых объектов даже в течение короткого жизненного цикла программы.

Трассировка макросов в ctor и dtor сделала трюк.

Визуальный детектор утечек и Stackwalk64 выглядят очень многообещающими

также обнаружили AfxDumpStack (AFX_STACK_DUMP_TARGET_ODS); // OutputDebugString
, но это ОЧЕНЬ шумно

+0

Добро пожаловать в Stack Overflow! :) Обычно принято добавлять такие благодарности и резюме к вашему вопросу. Ответы сортируются по голосам, поэтому ваши комментарии здесь могут показаться немного неуместными. Также принято отмечать ответ как принятый, если вы считаете, что данный ответ «правильный». Повеселись :) –

 Смежные вопросы

  • Нет связанных вопросов^_^