Плюс, прогоны программы на устройстве руки, выполняющем Linux,, я могу распечатать информацию о стеке и зарегистрировать значения в обработчике сигналов-seg, который я присваиваю. Проблема, я не могу добавить-g опцию к исходному файлу, так как ошибка может не воспроизводить из-за снижения производительности.
Компиляция с параметром -g
для gcc
не вызывает «снижение производительности». Все, что он делает, это включает символы отладки; он не влияет на оптимизацию или генерацию кода.
Если вы устанавливаете обработчик SIGSEGV
с помощью члена sa_sigaction
структуры sigaction
, переданной в sigaction ()
, то член si_addr
структуры siginfo_t
, переданный вашему обработчику, содержит адрес сбоя.
Я обычно использую valgrind
, который показывает утечки и ошибки доступа к памяти.
Кажется, это работает. http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
static void signal_segv(int signum, siginfo_t* info, void*ptr) {
// info->si_addr is the illegal address
}
Если вас беспокоит использование -g для двоичного файла, который вы загружаете на устройство, вы можете использовать gdbserver на устройстве ARM с урезанной версией исполняемого файла и запустите arm-gdb на своей машине разработки с незарезанной версией исполняемого файла. Урезанная версия и несвязанная версия должны соответствовать для этого, поэтому сделайте следующее:
# You may add your own optimization flags
arm-gcc -g program.c -o program.debug
arm-strip --strip-debug program.debug -o program
# or
arm-strip --strip-unneeded program.debug -o program
Вам нужно будет прочитать документацию по gdb и gdbserver, чтобы понять, как их использовать. Это не так уж сложно, но и не так отполировано, как могло бы быть. В основном очень легко случайно указать gdb сделать что-то, что он в конечном итоге думает, что вы собираетесь сделать локально, поэтому он выйдет из режима удаленной отладки.
Если опция -g заставляет ошибку исчезнуть, то знание места сбоя вряд ли будет полезным в любом случае. Вероятно, в функции A происходит запись в неинициализированный указатель, а затем функция B пытается законно использовать эту память и умирает. Ошибки памяти - это боль.
Вы также можете использовать функцию backtrace (), если она доступна, которая предоставит стек вызовов во время сбоя. Это можно использовать для сброса стека, как это происходит на языке программирования высокого уровня, когда программа C получает ошибку сегментации, ошибку шины или другую ошибку нарушения памяти.
backtrace () доступен как в Linux, так и в Mac OS X