2015-05-30 3 views
4

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

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

Глядя на другие варианты, я видел, что с БГД можно использовать точки останова, чтобы напечатать что-нибудь, а затем автоматически продолжит выполнение:

break foo 
commands 
silent 
printf "Called foo: x is %d\n",x 
cont 
end 

Разве это лучше, чем положить printf в мой код?

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

Дополнительная информация: приложение написано на C и работает на Linux.

ответ

2

Это лучше, чем положить печать в мой код?

Нет, это много хуже. Каждая точка останова, которая попала в GDB запускает следующую цепочку событий:

  • переключение контекста от запуска потока для GDB
  • GDB останавливает все другие темы (предполагая, что режим по умолчанию все-стоп)
  • GDB оценивает команды точки останова
  • GDB возобновляет работу со всеми темами (это само по себе сложный многоступенчатый процесс, который я бы не стал здесь).

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

Суть в том, что GDB в целом совершенно непригоден для отладки данных гонок.

Я второй рекомендация ThreadSanitizer от Кристофера Яна Стерна.

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

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

Во-вторых, ThreadSanitizer обнаруживает скачки данных, даже если они не вызывают вид изменений поведения. Вполне может оказаться, что вам вообще не нужно запускать на своей производственной машине: просто запускайте тесты (у вас do есть тесты, верно?) На вашей машине разработки может оказаться достаточным.

+0

Спасибо за дополнительную информацию: они очень полезны! Похоже, мне действительно нужно попробовать ThreadSanitizer, тогда :) – Muffo

2

Поскольку вы работаете в Linux, я бы рекомендовал ThreadSanitizer. Это использование последней версии gcc или clang и передача -fsanitize = thread в сборку. Это не распечатка printf, но вы должны прямо указать вам какие-либо условия гонки в вашем коде. Даже после решения этой проблемы, если вы работаете с многопоточным кодом, вы захотите использовать этот инструмент. В качестве альтернативы, или, кроме того, у меня были хорошие результаты с детектором детектора данных Valgrind http://valgrind.org, но я бы начал с ThreadSanitizer.

+0

Спасибо за предложение. Я не знал ThreadSanitizer, но я обязательно посмотрю на него. Единственная проблема с этой ошибкой в ​​том, что я делаю отладку на производственном компьютере, где я не могу установить другой SW ... – Muffo