Debugging Persistent Segmentation Fault in Multi-threaded C++ Program on AMD Barcelona CPUs
I have been wrestling with a persistent segmentation fault in a multi-threaded C++ program running on a cluster of AMD Barcelona CPUs Linux/x86_64. The code causing the crashes is a heavily used function, and under load, running 1000 instances of the program same optimized binary can generate 1 to 2 crashes per hour.
Now here's the interesting part, the crashes happen on different machines within the cluster although the machines themselves are almost identical, and they all share the same characteristics - same crash address and call stack.
Solution:Jump to solution
Tools like GDB can help you track memory access patterns in different threads , and you know that mutexes are synchronization mechanisms you should add around critical sections of
foo
to allow you have thread safe access to shared data . How's it going ? @Marvee Amasi7 Replies
The crash Details:
Signal: Segmentation fault (SIGSEGV)
Faulting Instruction Address: 0x17bd9fc (mid-instruction in function Foo)
My code around the crash location:
The crash happens in the middle of the instruction at
0x17bd9fc
, which is after a call to a virtual function through a pointer at offset 0x70
from memory pointed to by %eax
.
Examining the virtual table shows it's not corrupted, and it points to the expected function Foo::Get()
.
Foo::Get()
itself seems to be simple and well-behaved (will be shown in disassembly below).
The return address on the stack ($rsp-8) points to the correct instruction after the call to Foo::Get().Disassembly of Foo::Get():
It's as if during the return from Foo::Get(), something increments the program counter (%rip) by 4 bytes, leading to the crash mid-instruction in Foo.
Has anyone encountered anything similar? Any suggestions on how to approach debugging this further?
Solution
Tools like GDB can help you track memory access patterns in different threads , and you know that mutexes are synchronization mechanisms you should add around critical sections of
foo
to allow you have thread safe access to shared data . How's it going ? @Marvee AmasiYh @UC GEE so I was able to identify the issue as a data race condition within the Foo function. Multiple threads were like accessing or modifying shared data concurrently, it coused the corruption and the crash
I synchronized thread with a(n) semaphore around the critical sections of Foo that involved shared data access. I wanted to ensure that only one thread can access that data at a time, preventing race conditions