sem_wait() 触发 SIGBUS 异常

问题描述 投票:0回答:1

我有一个 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 上运行良好。

c++ linux signals semaphore sigbus
1个回答
0
投票

您将

sem_t
填充到字节数组中,该数组没有对齐要求,但
sem_t
几乎肯定有。 因此,当您实际使用它时,您会因访问未对齐的内存而出错。

如果您想要

sem_t
,您应该使用
sem_t
。 或者直接使用 C++ 中已有十年的线程和 IPC 原语。

© www.soinside.com 2019 - 2024. All rights reserved.