Кодирование для простоты отладки - PullRequest
1 голос
/ 14 января 2010

Я ищу советы о том, как помочь в отладке, добавив код в мое приложение. Пример для того, чтобы стало более понятным, что мне нужно: для обнаружения висячих объектов, находящихся в shared_ptrs, я создал класс трекера, который позволяет мне отслеживать, сколько объектов живы и где они были изначально созданы, что затем используется так:

class MyClass {
    TRACK_THIS_TYPE(MyClass);
};

boost::shared_ptr<MyClass> myObj(new MyClass);
TRACK_THIS_OBJECT(myObj);

где TRACK_THIS_TYPE (t) - это макрос, который гарантирует, что я получаю количество экземпляров (и количество созданных объектов) для класса, а TRACK_THIS_OBJECT - это макрос, в котором хранится файл и строка, в которой был создан объект вместе со слабым_птром к объекту.

Это позволяет мне обнаруживать висячие объекты и где они были созданы. Это не позволяет мне узнать, какие объекты содержат shared_ptr для моих объектов, что может быть улучшением вышеописанного. Я думаю, что можно создать что-то вроде макроса TRACK_THIS_PTR (T), в котором будут храниться файл и строка, в которой создается экземпляр shared_ptr.

Другим примером будет старый

assert(condition && "My descriptive text");

, который позволяет вам помещать значимые комментарии прямо в ваш аргумент.

Есть ли у кого-нибудь хитрые трюки на С ++ для сбора статистики, автоматических трассировок стека, отслеживания объектов / указателей / ресурсов, обнаружения тупиковых ситуаций / голодания или других проблем с многопоточностью, чтобы убедиться, что исключения где-то обрабатываются, помощь в документации или подобное? Все идет действительно, будь то что-то, что помогает предотвратить ошибки или что-то, что помогает после факта.

Редактировать: В дополнение к ответам на этот вопрос я получил советы о google-glog в качестве утилиты ведения журнала.

Ответы [ 6 ]

4 голосов
/ 14 января 2010

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

Это заставляет вас задуматься о том, какие значения могут взять ваши данные, и может упростить быстрый поиск рефакторинга, который оставил некоторую глупую ошибку.

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

Что касается управления памятью, я широко использую RAII и стараюсь сделать все возможное, чтобы использовать как можно меньше указателей и ручное распределение памяти. Если в вашем коде всего 2 или 3 указателя, проще избежать ошибки.

3 голосов
/ 14 января 2010

Интересно, что у нас довольно похожий проект для отслеживания проблем с памятью.

Многие люди клянутся RAII, но даже при использовании shared_ptr вы можете создавать утечки, проблема в основном из-за циклов ссылок(вот почему сборщики мусора на основе подсчета ссылок имеют специальные алгоритмы для определения циклов): x

Компания, в которой я работаю (Амадеус), в настоящее время разрабатывает AMPolice , которая по размерам valgrind.Он все еще находится в стадии разработки, особенно в отделе документации.

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

Поэтому это намного проще в использовании, хотя в наших тестах это влияет на время (4x или 5x).

Инструмент довольно универсален, поэтому обычно может использоваться многими людьми, но, конечно, основной проблемой остается размер среза бревен, так как отслеживание каждого new довольно дорого: x

2 голосов
/ 14 января 2010

Следующее в основном для простоты отладки после выпуска.

Stackwalker и аналогичные инструменты обеспечивают простой способ получения пригодных для использования стеков вызовов на компьютерах конечных пользователей без использования отладчика. Скорее всего, Google Breakpad можно использовать для простого извлечения мини-дампов из аварийных процессов.

1 голос
/ 14 января 2010

Я бы лично предпочел не писать ошибки в первую очередь. Добавление пакетов отладочного кода в приложение может иметь нежелательные побочные эффекты. Очевидно, что это влияет на производительность и, в случае многопоточных приложений, может изменить время приложения, что приводит к скрытию ошибок MT.

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

1 голос
/ 14 января 2010

Вы можете посмотреть в журнале статистику, которую вы производите с чем-то вроде "log4cxx"

http://logging.apache.org/log4cxx/index.html

Это должно позволить вам контролировать уровень трассировки, который вы выполняете во время выполнения (или, по крайней мере, через файл конфигурации, считываемый во время выполнения).

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

0 голосов
/ 19 января 2010

Мой c ++ сейчас немного ржавый, но я помню, что всякий раз, когда мне приходилось выделять объект, у меня был макрос, который выполнял его примерно так:

NEW (класс)

и затем макрос для освобождения объектов, называемый RELEASE. Тогда каждый макрос будет хранить класс и номер строки, где объект был создан и уничтожен.

Это позволило бы легко обнаруживать утечки памяти, позволяя видеть, где объекты не освобождаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...