Linux C程序中信号量触发SIGABRT终止的原因排查
字节对齐导致信号量操作失败问题排查
开发环境
[root@dev src]# uname -a Linux dev 3.10.0-1160.24.1.el7.x86_64 #1 SMP Thu Apr 8 19:51:47 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux [root@dev src]# [root@dev src]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [root@dev src]# [root@dev src]# gcc --version gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9) Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [root@dev src]#
问题场景
定义包含信号量的结构体:
#include <semaphore.h> typedef struct euclid_command { char *bytes; char *result; sem_t sem; } EuclidCommand;
原本代码中为结构体分配内存时额外预留4字节,程序可正常执行:
/** * 为EuclidCommand结构体对象分配内存,额外预留4字节作为附加信息 */ int hidden = 4; void *obj_head = malloc(hidden + sizeof(EuclidCommand)); memset(obj_head, 0, hidden + sizeof(EuclidCommand)); EuclidCommand *task = obj_head + hidden; task->bytes = buf; sem_init(&(task->sem), 0, 0); /** * 将任务对象提交至其他线程处理,线程执行完成后会将信号量值加1 */ submit_command(task); sem_wait(&(task->sem)); sem_destroy(&(task->sem)); // do something
当把预留字节数改为2后,程序在执行sem_wait(&(task->sem));时触发失败,gdb查看的程序栈显示信号量操作相关函数异常。
问题原因
确实是字节对齐导致的问题:
- 在x86_64架构的CentOS 7系统中,
sem_t类型的对象要求4字节对齐(其内部成员依赖该对齐规则)。 - 当预留2字节时,
obj_head + 2的地址无法满足EuclidCommand结构体的对齐要求,结构体中sem_t成员的地址会落在非对齐位置。 - 信号量相关函数(
sem_init、sem_wait)依赖sem_t对象处于正确对齐的内存地址,非对齐访问会破坏信号量内部数据结构,直接导致操作失败。 - 之前预留4字节时,
obj_head + 4刚好是4字节对齐地址,符合结构体的对齐要求,因此程序正常运行。
解决方案
- 保证结构体地址对齐:计算结构体的对齐要求,调整预留空间或偏移量,确保
task指针指向的地址满足对齐规则:
#include <stdalign.h> // 获取EuclidCommand的对齐要求 size_t align = alignof(EuclidCommand); int hidden = 2; // 计算需要补充的偏移量,使最终地址对齐 size_t offset = (align - (hidden % align)) % align; void *obj_head = malloc(hidden + offset + sizeof(EuclidCommand)); memset(obj_head, 0, hidden + offset + sizeof(EuclidCommand)); EuclidCommand *task = (void*)((char*)obj_head + hidden + offset);
- 调整内存布局:将附加信息存储在结构体末尾,或使用独立内存块存储,避免破坏结构体的对齐。
- 使用对齐分配函数:通过
posix_memalign分配对齐的内存块,再在头部预留附加信息空间,从对齐地址开始初始化结构体。
内容的提问来源于stack exchange,提问作者czg
相关产品推荐
相关产品推荐

