2015-12-09 2 views
1

У меня есть ситуация, когда я запускаю ряд модульных тестов, и один из них вызывает ошибку сегментации. Симптом, похоже, связан с другим тестовым случаем, который проходит примерно 30 тестовых случаев до неудачного. Очевидно, что существует определенная зависимость между тестовыми примерами, и я могу легко включить и отключить ошибку сегментации, комментируя предыдущий тестовый пример. Google Test/Mock 1.6.0 используется в качестве тестовой среды. Бинарный файл теста полностью написан на C++ (gcc 4.6.3). Он однопоточный (если только Google Test не создает потоки).Почему ошибка сегментации не воспроизводится в gdb?

Однако, когда я запускаю все тестовые примеры в gdb, нет ошибки сегментации, и это то, что меня озадачивает.

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

Я просто делаю это не видеть никакой вины:

gdb MyBinary 
run 

Последние строки терминала распечатке:

[ PASSED ] 368 tests. 
[Inferior 1 (process 28349) exited normally] 

И это, чтобы увидеть ошибку:

MyBinary 

Последняя строка терминальная распечатка:

Segmentation fault 
+1

Вы, вероятно, не будете знать, пока не найдете ошибку. До тех пор, пока вы можете каким-то образом воспроизвести ошибку, вы не должны слишком одержимы обстоятельствами, в которых это происходит, пока у вас не будет причин думать, что они важны. –

+0

Вы можете попробовать запустить единичный тест под valgrind, чтобы узнать, какие ошибки памяти ему удалось обнаружить. –

+0

Кстати, вы можете ограничить размер дампа 'core' до разумной цифры (например, 500 Мбайт по крайней мере) и запустить' gdb' post mortem на 'core' –

ответ

5

Каковы реалистичные причины, по которым возникла ошибка сегментации при работе двоичного файла в терминале, но не при запуске одного и того же двоичного кода через gdb?

Два наиболее распространенными из них являются:

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

Вы можете запретить GDB отключать ASLR с помощью set disable-randomization off.

Возможно, вы должны проверить свои тесты, используя MemorySanitizer и ThreadSanitizer.

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