Improve Article
Save Article
Improve Article
Save Article
Segmentation fault(SIGSEGV) and Bus error(SIGBUS) are signals generated when serious program error is detected by the operating system and there is no way the program could continue to execute because of these errors.
1) Segmentation Fault (also known as SIGSEGV and is usually signal 11) occur when the program tries to write/read outside the memory allocated for it or when writing memory which can only be read.In other words when the program tries to access the memory to which it doesn’t have access to. SIGSEGV is abbreviation for “Segmentation Violation”.
Few cases where SIGSEGV signal generated are as follows,
-> Using uninitialized pointer
-> De-referencing a NULL pointer
-> Trying to access memory that the program doesn’t own (eg. trying to access an array element
out of array bounds).
-> Trying to access memory which is already de-allocated (trying to use dangling pointers).
Please refer this article for examples.
2) Bus Error (also known as SIGBUS and is usually signal 10) occur when a process is trying to access memory that the CPU cannot physically address.In other words the memory tried to access by the program is not a valid memory address.It caused due to alignment issues with the CPU (eg. trying to read a long from an address which isn’t a multiple of 4). SIGBUS is abbreviation for “Bus Error”.
SIGBUS signal occurs in below cases,
-> Program instructs the CPU to read or write a specific physical memory address which is not valid / Requested physical address is unrecognized by the whole computer system.
-> Unaligned access of memory (For example, if multi-byte accesses must be 16 bit-aligned, addresses (given in bytes) at 0, 2, 4, 6, and so on would be considered aligned and therefore accessible, while addresses 1, 3, 5, and so on would be considered unaligned.)
The main difference between Segmentation Fault and Bus Error is that Segmentation Fault indicates an invalid access to a valid memory, while Bus Error indicates an access to an invalid address.
Below is an example of Bus Error taken from wikipedia.
C
#include <stdlib.h>
int
main(
int
argc,
char
**argv)
{
#if defined(__GNUC__)
# if defined(__i386__)
__asm__("pushfnorl $0x40000,(%esp)npopf");
# elif defined(__x86_64__)
__asm__("pushfnorl $0x40000,(%rsp)npopf");
# endif
#endif
char
*cptr =
malloc
(
sizeof
(
int
) + 1);
int
*iptr = (
int
*) ++cptr;
*iptr = 42;
return
0;
}
Output :
Bad memory access (SIGBUS)
This article is contributed by Prashanth Pangera. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Get this book -> Problems on Array: For Interviews and Competitive Programming
In this article, we will be discussing about «Bus Error In C++» and SIGBUS signal in detail.
Contents:
- Introduction to Bus Error
- Main causes of Bus Errors
- Non-existent address
- Unaligned access
- Paging errors
- Program Code
- Explanation
- Quiz
Introduction
When a process attempts to access memory that the CPU cannot physically address, hardware will raise an error to alert the operating system which is known as a bus error.
The bus error also known as SIGBUS is typically signal 10. The acronym SIGBUS stands for «bus error.»
In other words, «bus error» means trying to access memory that does not exist.
For Example
if you attempt to access a 12G address but only have 8G of memory.
Or
if you exceed the limit of usable memory.
The following factors affect bus error:
1 . Non-existent address
2 . Unaligned access
3 . Paging errors
1 . Non-existent address
The software gives the CPU instructions to read from or write to a particular physical memory address.
The CPU then assigns this physical address to its address bus and instructs all other hardware to respond in a certain way.
If no response is received from hardware, then the CPU raises an exception that the physical address is unknown or non-existent.
2. Unaligned access
In most CPUs, each memory address corresponds to a single 8-bit byte.
In general, CPUs can access individual bytes from each memory address, but cannot access larger units unless they are «aligned» to a specific boundary.
trying to read a multi-byte value (such as an int, 32-bits) from an odd address generated a bus error.
A 16-bit alignment requirement for multi-byte access would mean that addresses 0, 4, 8, 12, and so on would be aligned and therefore accessible, but all other addresses are unaligned.
A 32-bit alignment requirement for multi-byte access would mean that addresses 0, 4, 8, 12, and so on would be aligned and therefore accessible, but all other addresses are unaligned.
3. Paging errors
When virtual memory pages cannot be paged in or newly created memory is physically allocated because the disc is full, FreeBSD, Linux, and Solaris can raise a bus fault.
Bus error can also result from the operating system’s failure to back a virtual page with virtual memory at least on Linux.
Program Code 1
#include <signal.h>
int main(void)
{
raise(SIGBUS);
return 0;
}
Output
Bus error
Explanation:
In this case, it raise a bus error.
Program Code 2
#include <signal.h>
int main()
{
char *value = 0;
*value = 'X';
}
Output
Bus error
Explanation:
In this case, it raise a bus error.This program is tested on PowerPC Mac .
On modern hardware, it results segmentation fault instead of a bus error.
Program Code 3
#include<stdio.h>
#include<string.h>
int main()
{
char *c="Hello World";
printf("n Normal String = : %sn",c);
int i,j;
char temp;
int len=strlen(c);
//print Reverse String
for(i=0,j=len-1;i<=j;i++,j--)
{
temp=c[i];
c[i]=c[j];
c[j]=temp;
}
printf("n reversed string is : %snn",c);
}
Output
Normal String = : Hello World
Bus Error
Explanation:
In this case,char *str = «Hello Wolrd» is treated as literal. It is the same as const char *str , a constant to string pointer, and attempting to modify a constant string is not enabled.As as a result it raise a bus error.
Program Code 4
#include<stdio.h>
#include<string.h>
int main(void)
{
char *str;
str="Hello World";
printf("n Normal String = : %sn",str);
int i,j;
char temp;
int len=strlen(str);
char *ptr=NULL;
ptr=malloc(sizeof(char)*(len));
ptr=strcpy(ptr,str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=temp;
}
printf("Reverse String = : %sn",ptr);
}
Output
Normal String = : Hello World
Reverse String = : dlroW olleH
Explanation:
In this case ,we used malloc() and created a copy of the original string. here ,ptr is not of the ‘const char *’ type (constant) , so modifiying will not raise any errors. As a result, the reverse string is printed.
LETS CHECK YOUR KNOWELDGE :
Question
Which of the follwoing case is not an example of SIGBUS signal?
Non-existent address
Segmentation fault
Unaligned access
Paging errors
SIGBUS signal occurs in below cases Non-existent address,Unaligned access,Paging errors.So Segmentation fault is correct option.
From Wikipedia, the free encyclopedia
In computing, a bus error is a fault raised by hardware, notifying an operating system (OS) that a process is trying to access memory that the CPU cannot physically address: an invalid address for the address bus, hence the name. In modern use on most architectures these are much rarer than segmentation faults, which occur primarily due to memory access violations: problems in the logical address or permissions.
On POSIX-compliant platforms, bus errors usually result in the SIGBUS signal being sent to the process that caused the error. SIGBUS can also be caused by any general device fault that the computer detects, though a bus error rarely means that the computer hardware is physically broken—it is normally caused by a bug in software.[citation needed] Bus errors may also be raised for certain other paging errors; see below.
Causes[edit]
There are at least three main causes of bus errors:
Non-existent address[edit]
Software instructs the CPU to read or write a specific physical memory address. Accordingly, the CPU sets this physical address on its address bus and requests all other hardware connected to the CPU to respond with the results, if they answer for this specific address. If no other hardware responds, the CPU raises an exception, stating that the requested physical address is unrecognized by the whole computer system. Note that this only covers physical memory addresses. Trying to access an undefined virtual memory address is generally considered to be a segmentation fault rather than a bus error, though if the MMU is separate, the processor cannot tell the difference.
Unaligned access[edit]
Most CPUs are byte-addressable, where each unique memory address refers to an 8-bit byte. Most CPUs can access individual bytes from each memory address, but they generally cannot access larger units (16 bits, 32 bits, 64 bits and so on) without these units being «aligned» to a specific boundary (the x86 platform being a notable exception).
For example, if multi-byte accesses must be 16 bit-aligned, addresses (given in bytes) at 0, 2, 4, 6, and so on would be considered aligned and therefore accessible, while addresses 1, 3, 5, and so on would be considered unaligned. Similarly, if multi-byte accesses must be 32-bit aligned, addresses 0, 4, 8, 12, and so on would be considered aligned and therefore accessible, and all addresses in between would be considered unaligned. Attempting to access a unit larger than a byte at an unaligned address can cause a bus error.
Some systems may have a hybrid of these depending on the architecture being used. For example, for hardware based on the IBM System/360 mainframe, including the IBM System z, Fujitsu B8000, RCA Spectra, and UNIVAC Series 90, instructions must be on a 16-bit boundary, that is, execution addresses must start on an even byte. Attempts to branch to an odd address results in a specification exception.[1] Data, however, may be retrieved from any address in memory, and may be one byte or longer depending on the instruction.
CPUs generally access data at the full width of their data bus at all times. To address bytes, they access memory at the full width of their data bus, then mask and shift to address the individual byte. Systems tolerate this inefficient algorithm, as it is an essential feature for most software, especially string processing. Unlike bytes, larger units can span two aligned addresses and would thus require more than one fetch on the data bus.
It is possible for CPUs to support this, but this functionality is rarely required directly at the machine code level, thus CPU designers normally avoid implementing it and instead issue bus errors for unaligned memory access.
Paging errors[edit]
FreeBSD, Linux and Solaris can signal a bus error when virtual memory pages cannot be paged in, e.g. because it has disappeared (e.g. accessing a memory-mapped file or executing a binary image which has been truncated while the program was running),[2][unreliable source?] or because a just-created memory-mapped file cannot be physically allocated, because the disk is full.
Non-present segment (x86)[edit]
On x86 exists an older memory management
mechanism known as segmentation.
If the application loads segment register with the selector
of non-present segment (which under POSIX-compliant OSes
can only be done with an assembly language), the exception
is generated. Some OSes used that for swapping, but under
Linux this generates SIGBUS.
Example[edit]
This is an example of unaligned memory access, written in the C programming language with AT&T assembly syntax.
#include <stdlib.h> int main(int argc, char **argv) { int *iptr; char *cptr; #if defined(__GNUC__) # if defined(__i386__) /* Enable Alignment Checking on x86 */ __asm__("pushfnorl $0x40000,(%esp)npopf"); # elif defined(__x86_64__) /* Enable Alignment Checking on x86_64 */ __asm__("pushfnorl $0x40000,(%rsp)npopf"); # endif #endif /* malloc() always provides memory which is aligned for all fundamental types */ cptr = malloc(sizeof(int) + 1); /* Increment the pointer by one, making it misaligned */ iptr = (int *) ++cptr; /* Dereference it as an int pointer, causing an unaligned access */ *iptr = 42; /* Following accesses will also result in sigbus error. short *sptr; int i; sptr = (short *)&i; // For all odd value increments, it will result in sigbus. sptr = (short *)(((char *)sptr) + 1); *sptr = 100; */ return 0; }
Compiling and running the example on a POSIX compliant OS on x86 demonstrates the error:
$ gcc -ansi sigbus.c -o sigbus $ ./sigbus Bus error $ gdb ./sigbus (gdb) r Program received signal SIGBUS, Bus error. 0x080483ba in main () (gdb) x/i $pc 0x80483ba <main+54>: mov DWORD PTR [eax],0x2a (gdb) p/x $eax $1 = 0x804a009 (gdb) p/t $eax & (sizeof(int) - 1) $2 = 1
The GDB debugger shows that the immediate value 0x2a is being stored at the location stored in the EAX register, using X86 assembly language. This is an example of register indirect addressing.
Printing the low order bits of the address shows that it is not aligned to a word boundary («dword» using x86 terminology).
References[edit]
- ^ z/Architecture Principles of Operation, SA22-7832-04, Page 6-6, Fifth Edition (September, 2005) IBM Corporation, Poukeepsie, NY, Retrievable from http://publibfp.dhe.ibm.com/epubs/pdf/a2278324.pdf (Retrieved December 31, 2015)
- ^ «What is SIGBUS — Object specific hardware error?».
30.12.2019C
Ошибка сегментации (SIGSEGV) и Ошибка шины (SIGBUS) — это сигналы, генерируемые операционной системой, когда обнаружена серьезная программная ошибка, и программа не может продолжить выполнение из-за этих ошибок.
1) Ошибка сегментации (также известная как SIGSEGV и обычно являющаяся сигналом 11) возникает, когда программа пытается записать / прочитать вне памяти, выделенной для нее, или при записи памяти, которая может быть прочитана. Другими словами, когда программа пытается получить доступ к память, к которой у него нет доступа. SIGSEGV — это сокращение от «Нарушение сегментации».
Несколько случаев, когда сигнал SIGSEGV генерируется следующим образом:
-> Использование неинициализированного указателя
-> Разыменование нулевого указателя
-> Попытка доступа к памяти, которой не владеет программа (например, попытка доступа к элементу массива
вне границ массива).
-> Попытка получить доступ к памяти, которая уже выделена (попытка использовать висячие указатели).
Пожалуйста, обратитесь к этой статье за примерами.
2) Ошибка шины (также известная как SIGBUS и обычно являющаяся сигналом 10) возникает, когда процесс пытается получить доступ к памяти, которую ЦП не может физически адресовать. Другими словами, память, к которой программа пыталась получить доступ, не является действительным адресом памяти. вызвано из-за проблем с выравниванием с процессором (например, попытка прочитать длинный из адреса, который не кратен 4). SIGBUS — сокращение от «Ошибка шины».
Сигнал SIGBUS возникает в следующих случаях,
-> Программа дает указание процессору прочитать или записать конкретный адрес физической памяти, который является недопустимым / Запрашиваемый физический адрес не распознается всей компьютерной системой.
-> Нераспределенный доступ к памяти (например, если многобайтовый доступ должен быть выровнен по 16 битам, адреса (заданные в байтах) в 0, 2, 4, 6 и т. Д. Будут считаться выровненными и, следовательно, доступными, в то время как адреса 1, 3, 5 и т. Д. Будет считаться не выровненным.)
Основное различие между ошибкой сегментации и ошибкой шины заключается в том, что ошибка сегментации указывает на недопустимый доступ к допустимой памяти, а ошибка шины указывает на доступ к недопустимому адресу.
Ниже приведен пример ошибки шины, взятой из википедии .
#include <stdlib.h>
int
main(
int
argc,
char
**argv)
{
#if defined(__GNUC__)
# if defined(__i386__)
__asm__(
"pushfnorl $0x40000,(%esp)npopf"
);
# elif defined(__x86_64__)
__asm__(
"pushfnorl $0x40000,(%rsp)npopf"
);
# endif
#endif
char
*cptr =
malloc
(
sizeof
(
int
) + 1);
int
*iptr = (
int
*) ++cptr;
*iptr = 42;
return
0;
}
Выход :
Bad memory access (SIGBUS)
Эта статья предоставлена Прашант Пангера . Если вы как GeeksforGeeks и хотели бы внести свой вклад, вы также можете написать статью с помощью contribute.geeksforgeeks.org или по почте статьи contribute@geeksforgeeks.org. Смотрите свою статью, появляющуюся на главной странице GeeksforGeeks, и помогите другим вундеркиндам.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
- Базовый дамп (ошибка сегментации) в C / C ++
- Как найти ошибку сегментации в C & C ++? (С использованием GDB)
- Сегментация памяти в микропроцессоре 8086
- Иначе без IF и L-Value Обязательная ошибка в C
- Обработка ошибок в программах на Си
- Программные сигналы об ошибках
- Предопределенные макросы в C с примерами
- Как создать графический интерфейс в программировании на C, используя GTK Toolkit
- Библиотека ctype.h (<cctype>) в C / C ++ с примерами
- Слабые байты в структурах: объяснение на примере
- Разница между итераторами и указателями в C / C ++ с примерами
- C программа для подсчета количества гласных и согласных в строке
- Вложенные циклы в C с примерами
- Программа Hello World: первая программа во время обучения программированию
Ошибка сегментации (SIGSEGV) и ошибка шины (SIGBUS)
0.00 (0%) 0 votes
Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 17:22, 21 мая 2019.
Ошибка на шине (bus error)- это ошибка, которая была вызвана аппаратным обеспечением, уведомляющим операционную систему о том , что процесс пытается получить доступ к памяти, которую процессор не может физически адресовать из-за того, что у адресной шины недопустимый адрес, а следовательно, и имя. В современном использовании на большинстве архитектур они встречаются гораздо реже , чем ошибки сегментации, которые возникают в основном из-за нарушений доступа к памяти: проблем с логическим адресом или разрешениями.
На платформах, совместимых с портативным интерфейсом операционной системы( POSIX), ошибки шины обычно приводят к тому, что сигнал SIGBUS, который сигнализирует об ошибке шины, при обращении к физической памяти, передается процессу, который вызвал ошибку. SIGBUS также может быть вызван любой общей неисправностью устройства, которую обнаруживает компьютер, хотя ошибка шины редко означает, что компьютерное оборудование физически сломано, в основном это вызвано ошибкой в программном обеспечении.
Содержание
- 1 Причины возникновения
- 1.1 Недействующий адрес
- 1.2 Несогласованный доступ
- 1.3 Ошибка страницы
- 1.4 Несуществующий сегмент(x86)
- 2 Источники
Причины возникновения
Существует 4 основных причины возникновения данной ошибки.
Рассмотрим каждую из них.
Недействующий адрес
Программное обеспечение указывает процессору на чтение или запись определенного адреса физической памяти . Соответственно, центральный процессор устанавливает этот физический адрес на своей адресной шине и запрашивает все другое оборудование, подключенное к нему, чтобы ответить с результатами, если они отвечают за этот конкретный адрес. Если никакое другое оборудование не отвечает, центральный процессор вызывает исключение, указывающее, что запрошенный физический адрес не распознан всей компьютерной системой. Состоит отметить, что это касается только физических адресов памяти. Попытка доступа к неопределенному адресу виртуальной памяти обычно считается ошибкой сегментации, а не ошибкой шины, хотя если блок управления памятью (MMU) является отдельным, процессор не может определить разницу.
Несогласованный доступ
В основном центральные процессоры (CPU) являются байт-адресуемыми, где каждый уникальный адрес памяти ссылается на 8-битный байт . Большинство из них могут получить доступ к отдельным байтам из каждого адреса памяти, но они, как правило, не могут получить доступ к более крупным блокам (16 бит, 32 бит, 64 бит и т. д.) без «выравнивания» структуры данных этих блоков к определенной границе.
К примеру, если многобайтовый доступ должен быть 16-битным, адреса (заданные в байтах) в 0, 2, 4, 6 и так далее будут считаться выровненными и, следовательно, доступными, в то время как адреса 1, 3, 5 и так далее будут считаться не выровненными. Аналогично, если многобайтовый доступ должен быть 32-разрядным, адреса 0, 4, 8, 12 и так далее будут считаться выровненными и, следовательно, доступными, а все промежуточные адреса будут считаться не выровненными. Попытка получить доступ к блоку размером больше байта по не выровненному адресу может привести к ошибке шины.
Некоторые системы могут быть смешанные в зависимости от используемой архитектуры. Например, для аппаратного обеспечения, основанного на мэйнфрейме IBM System/360 , включая IBM System z, Fujitsu B8000, RCA Spectra и UNIVAC Series 90 , инструкции должны находиться на 16-разрядной границе, то есть адреса выполнения должны начинаться с четного байта. Попытка ветвления на нечетный адрес приводит к исключению спецификации. Данные, однако, могут быть извлечены из любого адреса в памяти, и могут быть размером от одного байта или больше, в зависимости от инструкции.
Процессоры, как правило, получают доступ к данным на всей ширине своей шины данных в любое время.
Система связи , которая передает данные между компонентами внутри компьютера или между компьютерами.Шина это система связи , которая передает данные между компонентами внутри компьютера или между компьютерами. Чтобы обратиться к байтам, они обращаются к памяти на всей ширине своей шины данных, затем маскируют и сдвигают для обращения к отдельному байту. Системы терпят этот неэффективный алгоритм, так как он является неотъемлемой особенностью большинства программ, особенно обработки строк. В отличие от байтов, большие блоки могут охватывать два выровненных адреса и, таким образом, требуют более одной выборки на шине данных. Процессоры могут поддерживать эту функцию, но эта функциональность редко требуется непосредственно в машинном коде уровень, таким образом, проектировщики центрального процессора обычно избегают его реализации и вместо этого выдают ошибки шины для не выровненного доступа к памяти.
Ошибка страницы
Такие ОС как,FreeBSD, Linux и Solaris могут сигнализировать об ошибке шины, когда страницы виртуальной памяти не могут быть выгружены, например, потому, что она исчезла (например, доступ к файлу с отображением памяти или выполнение двоичного образа, который был усечен во время работы программы), или потому, что только что созданный файл с отображением памяти не может быть физически выделен, потому что диск заполнен.
Несуществующий сегмент(x86)
На x86(емейство архитектур наборов команд,основанных на микропроцессоре Intel 8086 ) существует старый механизм управления памятью, известный как сегментация. Если приложение загружает регистр сегмента с селектором несуществующего сегмента , генерируется исключение. Некоторые ОС использовали это для подкачки, но под Linux это генерирует SIGBUS.
Источники
- https://stackoverflow.com/questions/212466/what-is-a-bus-error
- https://www.geeksforgeeks.org/segmentation-fault-sigsegv-vs-bus-error-sigbus/
- https://studfiles.net/preview/307512/page:15/
System information
Geth version: geth version
Geth
Version: 1.7.0-unstable
Git Commit: ebf41d1
Architecture: amd64
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.8.1
Operating System: linux
GOPATH=
GOROOT=/usr/lib/go-1.8
OS & Version: Ubuntu 14.04.5 LTS (Linux Kernel: 4.4.0-42-generic)
Expected behaviour
Should just work.
Actual behaviour
unexpected fault address 0x7f10dab0e000
fatal error: fault
[signal SIGBUS: bus error code=0x2 addr=0x7f10dab0e000 pc=0x46109b]
Steps to reproduce the behaviour
./build/bin/geth —datadir «/dev/shm/data1» —ethash.dagdir «/dev/shm/ethash» init /root/privGenesis.json
./build/bin/geth —datadir «/dev/shm/data1» —ethash.dagdir «/dev/shm/ethash» —rpc console
personal.newAccount()
personal.unlockAccount(eth.accounts[0])
miner.start()
INFO [08-28|12:07:14] Generating DAG in progress epoch=1 percentage=91 elapsed=2m15.065s
unexpected fault address 0x7f10dab0e000
fatal error: fault
[signal SIGBUS: bus error code=0x2 addr=0x7f10dab0e000 pc=0x46109b]
Backtrace
goroutine 405 [running]:
runtime.throw(0xf48d1b, 0x5)
/usr/lib/go-1.8/src/runtime/panic.go:596 +0x95 fp=0xc424507e48 sp=0xc424507e28
runtime.sigpanic()
/usr/lib/go-1.8/src/runtime/signal_unix.go:287 +0xf4 fp=0xc424507e98 sp=0xc424507e48
runtime.memmove(0x7f10dab0dfc8, 0xc4266d3b40, 0x40)
/usr/lib/go-1.8/src/runtime/memmove_amd64.s:191 +0x67b fp=0xc424507ea0 sp=0xc424507e98
github.com/ethereum/go-ethereum/consensus/ethash.generateDataset.func2(0xc421888080, 0x407fff80, 0x4, 0xc428324000, 0x407f30, 0x407f30, 0x0, 0x7f10ab800008, 0x407fff80, 0x407fff80, ...)
/root/ethereum/go-ethereum/build/_workspace/src/github.com/ethereum/go-ethereum/consensus/ethash/algorithm.go:275 +0x1f4 fp=0xc424507f58 sp=0xc424507ea0
runtime.goexit()
/usr/lib/go-1.8/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc424507f60 sp=0xc424507f58
created by github.com/ethereum/go-ethereum/consensus/ethash.generateDataset
/root/ethereum/go-ethereum/build/_workspace/src/github.com/ethereum/go-ethereum/consensus/ethash/algorithm.go:281 +0x3ad
I have a Raspberry Pi 3B+ with my Qt code on it (Qt 5.12.5). When I run my code, it randomly crashes with a Bus Error after a few hours. I am not sure how to work out the exact cause. I cross compile on Ubuntu for the RPi using the latest Raspberry Pi OS (2020-05-27).
The core dump (I have replaced some irrelevant parts with …)
Code: Select all
pi@raspberrypi: $ gdb TEST core
GNU gdb (Raspbian 8.2.1-2) 8.2.1
...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Core was generated by `./TEST'.
Program terminated with signal SIGBUS, Bus error.
#0 0x755b5b7c in QString::arg(long long, int, int, QChar) const () from /usr/local/qt5pi/lib/libQt5Core.so.5
[Current thread is 1 (Thread 0x6feff440 (LWP 1233))]
(gdb) bt full
#0 0x755b5b7c in QString::arg(long long, int, int, QChar) const () at /usr/local/qt5pi/lib/libQt5Core.so.5
#1 0x0001c0bc in QString::arg(int, int, int, QChar) const (this=0x6fefdc78, a=12, fieldWidth=0, base=10, fillChar=...) at ../raspi/qt5pi/include/QtCore/qstring.h:976
#2 0x00039ff8 in StageState::getStateString() (this=0x6fefdf00) at ../TEST/stage.h:35
...
#7 0x00142124 in TEST::timerExpired() (this=0x7ecd4708) at ../TEST/TEST.cpp:51
__PRETTY_FUNCTION__ = "void TEST::timerExpired()"
locker = {val = 2127384345}
#8 0x0015c188 in TEST::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) (_o=0x7ecd4708, _c=QMetaObject::InvokeMetaMethod, _id=2, _a=0x6fefe9d8) at moc_TEST.cpp:122
_t = 0x7ecd4708
#9 0x75722b08 in QMetaObject::activate(QObject*, int, int, void**) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#10 0x75730c1c in QTimer::timeout(QTimer::QPrivateSignal) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#11 0x75730fc8 in QTimer::timerEvent(QTimerEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#12 0x75724194 in QObject::event(QEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#13 0x768c6b88 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#14 0x768ce29c in QApplication::notify(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#15 0x759b62ec in QCoreApplication::self () at /usr/local/qt5pi/lib/libQt5Core.so.5
(gdb)
../TEST/stage.h:35 in #2 refers to this code:
Code: Select all
QString getStateString() {
switch (state) {
case StageState::AEnum:
return QString("text %1").arg(aInt); # this is line 35 in #2 as refered to bt 'gdb bt' above. aInt is 12 as seen from output above (in line #1, a=12)
...
default:
return QString("Unknown");
}
return QString("text %1").arg(aInt);
Searching online, I found a comment to look a the dmesg output (below).
Code: Select all
pi@raspberrypi:~ $ dmesg
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 5.4.44-v7+ (dom@buildbot) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611)) #1320 SMP Wed Jun 3 16:07:06 BST 2020
[ 0.000000] CPU: ARMv7 Processor [410fd034] revision 4 (ARMv7), cr=10c5383d
...
[ 17.898294] Bluetooth: BNEP filters: protocol multicast
[ 17.898313] Bluetooth: BNEP socket layer initialized
[16092.809350] Alignment trap: not handling instruction e1903f9f at [<755b5b78>]
[16092.809367] 8<--- cut here ---
[16092.815191] Unhandled fault: alignment exception (0x001) at 0x6f577277
[16092.820865] pgd = 6aa8fcbe
[16092.826468] [6f577277] *pgd=3278c835, *pte=2812175f, *ppte=28121c7f
Here is another bus error that is similar but not quite the same as previously using the exact same code:
Code: Select all
pi@raspberrypi:~/TEST/bin $ gdb TEST core
...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
Core was generated by `./TEST'.
Program terminated with signal SIGBUS, Bus error.
#0 0x7568d470 in QString::fromAscii_helper(char const*, int) () from /usr/local/qt5pi/lib/libQt5Core.so.5
[Current thread is 1 (Thread 0x709bf440 (LWP 767))]
(gdb) bt
#0 0x7568d470 in QString::fromAscii_helper(char const*, int) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#1 0x75830da4 in () at /usr/local/qt5pi/lib/libQt5Core.so.5
#2 0x0001c030 in QString::QString(char const*) (this=0x709be71c, ch=0x15fa88 "[0-9| ]{3}") at ../raspi/qt5pi/include/QtCore/qstring.h:700
#3 0x00029da8 in Measurement::doesRececivedDataFormatMatchRegex(QString) (this=0x709be7f4, receivedData=...) at ../TEST/Measurement.h:103
...
#12 0x7580c58c in QSocketNotifier::activated(int, QSocketNotifier::QPrivateSignal) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#13 0x7580c90c in QSocketNotifier::event(QEvent*) () at /usr/local/qt5pi/lib/libQt5Core.so.5
#14 0x769a2b88 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#15 0x769aa29c in QApplication::notify(QObject*, QEvent*) () at /usr/local/qt5pi/lib/libQt5Widgets.so.5
#16 0x75a922ec in QCoreApplication::self () at /usr/local/qt5pi/lib/libQt5Core.so.5
where the function Measurement::doesRececivedDataFormatMatchRegex(QString) from #3 is below:
Code: Select all
bool Measurement::doesRececivedDataFormatMatchRegex(QString receivedData)
{
QRegExp regExp("[0-9| ]{3}"); # this is the line 103 in #3 as refered to in 'gdb bt' above.
return receivedData.indexOf(regExp) != -1;
}
What I have tried so far:
Updating Qt to 5.14 from 5.12.5. I was thinking that since both bus errors occur in QString, maybe something to do with Qt (unlikely I guess).
New MicroSD card
I am also using a QTimer in a thread, maybe this could cause a issue, accessing a object from other threads? I am already using QMutex. I have not yet put everything in the gui thread to test if crashes still occur.
What is the best way of debugging this bus error?
(I originally posted this on Stack Overflow )