我有一个 C++ Linux 命令行应用程序,它会执行一系列操作,然后自行关闭。我使用信号量阻塞主线程,当后台线程完成其活动时,它会解锁信号量,释放从 int main() 返回的主线程。
// Static definition of the semaphore object. This semaphore object is
// declared as a static array of 32 bytes in class A
uint8_t A::semaphore[sizeof(sem_t)];
-----------------------------------------------------------------------
// In int main()
if(sem_init ((sem_t *) A::semaphore, 0, 0)) {
// failed to initialize semaphore
}
printf("semaphore = %p\n", A::semaphore); // Prints 0x129ba01
// Create another thread(s) to execute work
// Main thread gets blocked here... until thread(s) complete their work.
sem_wait ((sem_t *) A::semaphore);
// Once main thread gets unblocked, return from int main() with return value
我还使用 sigaction 附加了我自己的异常处理程序。事实证明,当主线程到达sem_wait时,我的异常处理程序将被调用,信号编号值为 7,这是一个
SIGBUS
异常。我还使用传递给异常处理程序的 siginfo_t
对象打印了更多详细信息。
// Exception handler belonging to Class B
void B::handleException(int32_t signum, siginfo_t * info, void * context) noexcept
{
printf("signo = %d\n", info->si_signo); // Prints 7
printf("errno = %d\n", info->si_errno);
printf("code = %d\n", info->si_code);
printf("si_addr = %p\n", info->si_addr); // Prints 0x129ba01
....
}
如上所示,捕获的异常是
SIGBUS
,si_addr
的siginfo
属性——指向故障的内存位置,打印信号量的地址。然后,signal 文档对 SIGBUS
进行了以下说明:
例如,导致在一个 CPU 架构上传送 SIGSEGV 的无效内存访问可能会导致在另一种架构上传送 SIGBUS,反之亦然。
我认为我真正得到的是一个
SIGSEGV
异常...并且存在一些内存访问冲突...但我找不到它。
我在这里缺少什么?
注意:
SIGBUS
仅在 Linux arm64 上抛出。我的应用程序在 Linux x64 上运行良好。
您将
sem_t
填充到字节数组中,该数组没有对齐要求,但 sem_t
几乎肯定有。 因此,当您实际使用它时,您会因访问未对齐的内存而出错。
如果您想要
sem_t
,您应该使用 sem_t
。 或者直接使用 C++ 中已有十年的线程和 IPC 原语。