PavelK
@PavelK

Тестированое «ошибками», или как эмулировать их при дебаге и отладке?

Приветствую!
Есть большой проект на Qt (C++). Возникают ошибки из разряда неуловимый Джо.
Есть обычные тесты функционала (Средствами Qt), но этого мало. Хочется эмулировать ошибки в функциях (например, какая либо переменная вернула неожиданное значение внутри самой функции) и смотреть, что происходит. Сейчас я делаю в дебагере, вручную меняя значения, но это утомительно, хочется автоматизации (да, можно было бы натыкать дефайнов, но по-моему это костыльное решение). Что можно придумать в такой ситуации, что бы прогонять тесты автоматически, но что бы как в дебагере имелась простая возможность изменить значение переменной?

P.S. Да, я предполагаю, что тут основная проблема в самой архитектуре и т.д. - она в процессе исправления по мере обнаружения ошибок.
  • Вопрос задан
  • 200 просмотров
Решения вопроса 1
@4rtzel
Можете посмотреть в сторону fault injection концепции. Она используются как дополнительный шаг в тестировании программы для проверки как ведёт себя код при возникновении ошибок. Минус у всего этого - требуется дополнительная модификация кода (что в вашем случае может быть слишком затратным и избыточным), но существуют вроде и внешние тулзы для модификации кода на лету.

Как другой вариант - написать скрипт для дебагера, который бы при старте программы расставлял брейкпоинты на retq (если надо, чтобы тело функции выполнилось) инструкции и выполнял кастомный ретурн со ошибочным значением.
Пример (gdb):
Файл:
int my_function() {
  return 42;
}
 
int main(void) {
  int a = my_function();
  printf("%d\n", a);
  return 0;
}


Находим адрес ret(q):
(gdb) disassemble my_function
Dump of assembler code for function my_function:
   0x08048388 <+0>:     push   %ebp
   0x08048389 <+1>:     mov    %esp,%ebp
   0x0804838b <+3>:     mov    $0x2a,%eax
   0x08048390 <+8>:     pop    %ebp
   0x08048391 <+9>:     ret


В файле .gdbinit:
b *0x08048391
commands
return (int)43
continue
end


Запускаем:
(gdb) run
Starting program: /root/a.out
Breakpoint 1, 0x08048391 in foo ()
43             <=== новое значение
[Inferior 1 (process 127) exited normally]
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
bogolt
@bogolt
Пишите логи всех действий совершаемых программой. Например
2018-11-01 15:12:12.123 Menu 'Open file' activated
2018-11-01 15:12:12.223 Opening file '/home/user/abc.txt'
2018-11-01 15:12:12.223 Operation failed with system error: Permission denied


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

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

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы