Как я узнаю, к какому незаконному адресу обращается программа, когда происходит ошибка сегментации - PullRequest
6 голосов
/ 12 мая 2010

Plus, программа запускается на устройстве под управлением Linux , Я могу распечатать информацию о стеке и зарегистрировать значения в обработчике sig-seg, который я назначил. Проблема в том, что я не могу добавить опцию -g к исходному файлу, поскольку ошибка может не воспроизводиться из-за снижения производительности.

Ответы [ 6 ]

13 голосов
/ 12 мая 2010

Компиляция с параметром -g для gcc делает не причиной «снижения производительности». Все, что он делает, это вызывает включение символов отладки; не влияет на оптимизацию или генерацию кода.

Если вы устанавливаете обработчик SIGSEGV с помощью члена sa_sigaction структуры sigaction, переданной в sigaction(), то член si_addr структуры siginfo_t, переданной вашему обработчику, содержит ошибочный адрес.

3 голосов
/ 12 мая 2010

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

1 голос
/ 13 мая 2010

Вы также можете использовать функцию backtrace (), если она доступна, которая обеспечит стек вызовов во время сбоя. Это может быть использовано для выгрузки стека, как это происходит на языке программирования высокого уровня, когда программа C получает ошибку сегментации, ошибку шины или другую ошибку нарушения памяти.

Функция backtrace () доступна как в Linux, так и в Mac OS X

1 голос
/ 12 мая 2010

Если вас беспокоит использование -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 сделать что-то, что он в конечном итоге думает, что вы должны делать локально, так что он переключится из режима удаленной отладки.

1 голос
/ 12 мая 2010

Это похоже на работу 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
}
0 голосов
/ 13 мая 2010

Если опция -g делает ошибку исчезающей, то в любом случае вряд ли будет полезно знать, где она падает. Вероятно, он записывает неинициализированный указатель в функцию A, а затем функция B пытается законно использовать эту память и умирает. Ошибки памяти - боль.

...