РЕДАКТИРОВАТЬ 1 : Платформа x86_64 для примера программы.
РЕДАКТИРОВАТЬ 2: Я редактирую это для лучшего понимания. Ниже приведены два разных вопроса. Первый вопрос: может ли неправильное чтение / запись вызвать SIGBUS? и второй вопрос: пригодится ли Valgrind для анализа SIGBUS? Пример кода для второго вопроса подтверждает мое мнение о том, что Valgrind не будет полезен вообще в случае ошибки SIGBUS. Я могу ошибаться здесь.
Фактический сценарий: У нас есть приложение для чтения с экрана, которое дает сбой после 2 дней непрерывного тестирования (один раз сбой из-за SIGBUS). У меня есть файл coredump, но у меня нет нужных двоичных и отладочных пакетов. По сути, я должен проверить это в другом двоичном файле, и coredump не работает должным образом в GDB из-за несоответствия в пакетах отладки. Я могу видеть некоторые некорректные чтения / записи в модуле чтения с экрана во время анализа Valgrind. Мой товарищ по команде предположил, что исправление этих недопустимых операций чтения / записи решит эту проблему, но я думаю, что это не решит ее. Ниже мое понимание обоих сигналов.
SIGSEGV: Адрес действителен, но разрешения на чтение / запись отсутствуют.
SIGBUS: Сам адрес недействителен (ЦП не может найти адрес из-за неправильной привязки и т. Д.)
У меня есть вопрос, связанный с сигналом SIGBUS. Я искал похожие вопросы о переполнении стека, но не нашел четкого ответа на этот вопрос.
Может ли неправильное чтение / запись вызвать ошибку шины (SIGBUS)? .
Насколько я понимаю, неправильное чтение / запись всегда будет вызывать ошибку сегментации (SIGSEGV), и лучший способ исправить ошибку шины - запустить приложение gdb. Анализ Valgrind в случае ошибки шины не поможет. Ниже код объясняет это более подробно.
#include<stdlib.h>
#include<stdio.h>
typedef struct {
char *name;
int val;
}data;
void fun1()
{
data *ptr = malloc(sizeof(data));
ptr->val = 100;
ptr->name = "name in structure";
printf("val:%d name:%s\n",ptr->val,ptr->name);
free(ptr);
ptr = NULL;
printf("val:%d name:%s\n",ptr->val,ptr->name); //SIGSEGV
return;
}
int fun2()
{
#if defined(__GNUC__)
# if defined(__i386__)
/* Enable Alignment Checking on x86 */
__asm__("pushf\norl $0x40000,(%esp)\npopf");
# elif defined(__x86_64__)
/* Enable Alignment Checking on x86_64 */
__asm__("pushf\norl $0x40000,(%rsp)\npopf");
# endif
#endif
char *cptr = malloc(sizeof(int) + 1);
char *optr = cptr;
int *iptr = (int *) ++cptr;
*iptr = 42; //SIGBUS
free(optr);
return 0;
}
void fun()
{
fun2();
//fun1();
}
int main()
{
fun();
return 0;
}
В случае ошибки сегментации в отчете Valgrind будут содержаться сведения о коде, вызывающем сбой, но в случае сбоя SIGBUS я не нашел таких подробностей в отчете Valgrind.
Отчет Valgrind для SIGSEGV:
==28128== Memcheck, a memory error detector
==28128== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28128== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28128== Command: ./a.out
==28128== Parent PID: 27953
==28128==
==28128== Invalid read of size 8
==28128== at 0x400619: fun1 (tmp.c:18)
==28128== by 0x400695: fun (tmp.c:46)
==28128== by 0x4006A6: main (tmp.c:51)
==28128== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==28128==
==28128==
==28128== Process terminating with default action of signal 11 (SIGSEGV)
==28128== Access not within mapped region at address 0x0
==28128== at 0x400619: fun1 (tmp.c:18)
==28128== by 0x400695: fun (tmp.c:46)
==28128== by 0x4006A6: main (tmp.c:51)
==28128== If you believe this happened as a result of a stack
==28128== overflow in your program's main thread (unlikely but
==28128== possible), you can try to increase the size of the
==28128== main thread stack using the --main-stacksize= flag.
==28128== The main thread stack size used in this run was 8388608.
==28128==
==28128== HEAP SUMMARY:
==28128== in use at exit: 0 bytes in 0 blocks
==28128== total heap usage: 2 allocs, 2 frees, 1,040 bytes allocated
==28128==
==28128== All heap blocks were freed -- no leaks are possible
==28128==
==28128== For counts of detected and suppressed errors, rerun with: -v
==28128== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Отчет Valgrind для SIGBUS:
==28176== Memcheck, a memory error detector
==28176== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==28176== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==28176== Command: ./a.out
==28176== Parent PID: 27953
==28176==
==28176==
==28176== HEAP SUMMARY:
==28176== in use at exit: 0 bytes in 0 blocks
==28176== total heap usage: 1 allocs, 1 frees, 5 bytes allocated
==28176==
==28176== All heap blocks were freed -- no leaks are possible
==28176==
==28176== For counts of detected and suppressed errors, rerun with: -v
==28176== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)