Автоматическое добавление журналов функций входа / выхода в проект

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

25
задан Benji Mizrahi 18 February 2010 в 10:50
поделиться

5 ответов

Помимо обычных методов отладчика и аспектно-ориентированного программирования, вы также можете вводить свои собственные инструментальные функции, используя опции командной строки gcc -finstrument-functions . Вам нужно будет реализовать свои собственные функции __cyg_profile_func_enter() и __cyg_profile_func_exit() (объявите их как extern "C" в C ++).

Они предоставляют средства для отслеживания того, какая функция была вызвана откуда. Однако интерфейс немного сложен в использовании, поскольку, например, адрес вызываемой функции и ее сайт вызова передаются вместо имени функции. Вы можете записать адреса, а затем извлечь соответствующие имена из таблицы символов, используя что-то вроде objdump --syms или nm , при условии, конечно, символы не были удалены из двоичные файлы.

Это может быть проще в использовании gdb. YMMV. :)

28
ответ дан Void 18 February 2010 в 10:50
поделиться

Вы сказали «и при этом я не хочу трогать любой исходный файл» ... честную игру, если вы позволите сценарию сделать это за вас?

Запустите это на всех ваших файлах .cpp

sed 's/^{/{ENTRY/'

Чтобы преобразовать их в это:

void foo()
{ENTRY
  // code here
}

Поместите это в заголовок, который может быть # # включен каждой единицей:

#define ENTRY EntryRaiiObject obj ## __LINE__ (__FUNCTION__);

struct EntryRaiiObject {
  EntryRaiiObject(const char *f) : f_(f) { printf("Entered into %s", f_); }
  ~EntryRaiiObject() { printf("Exited from %s", f_); }
  const char *f_;
};

Возможно, вам придется стать более изощренным со скриптом sed. Вы также можете поместить макрос ENTRY в любое другое место, где хотите исследовать, например, в какую-то глубоко вложенную область видимости функции.

11
ответ дан Dan 18 February 2010 в 10:50
поделиться

Используйте / Gh (Включить _penter Hook Function) и / GH (Включить _pexit Hook Function) переключатели компилятора (если вы можете скомпилировать источники конечно)

ПРИМЕЧАНИЕ: вы не сможете использовать эти макросы. См. Здесь («вам нужно получить адрес функции (в регистре EIP) и сравнить его с адресами в файле карты, которые могут быть сгенерированы компоновщиком (при условии, что перебазировка не произошла). быть очень медленным, хотя. ")

4
ответ дан RvdK 18 February 2010 в 10:50
поделиться
  • 1
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 21 May 2013 в 15:39
  • 2
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 21 May 2013 в 15:39
  • 3
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 21 May 2013 в 15:39
  • 4
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 21 May 2013 в 15:39
  • 5
    Вы уверены там, что действительно ли такая вещь как ':input' псевдоселектор? Я haven' t бывший в состоянии для нахождения ссылки для этого. – julien_c 21 May 2013 в 15:39

Согласитесь с Уильямом, используйте gdb, чтобы увидеть поток времени выполнения.
Есть некоторый статический анализатор кода, который может сказать, какие функции вызывают, и может дать вам некоторый граф потока вызовов. Одним из инструментов является «Понимание C ++» (поддержка C / C ++), но это не бесплатно, я думаю. Но вы можете найти похожие инструменты.

2
ответ дан Adil 18 February 2010 в 10:50
поделиться

Если вы используете gcc, флаг волшебного компилятора будет -g. Скомпилируйте с символами отладки, запустите программу под GDB и сгенерируйте трассировки стека. Вы также можете использовать ptrace, но, вероятно, намного проще просто использовать gdb.

1
ответ дан William Pursell 18 February 2010 в 10:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: