You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plain C:定时器ID无法传入信号处理函数及siginfo.h异常问题

问题分析与临时解决及上报指引

问题现象

在信号处理函数中尝试通过siginfo_t的si_timerid获取定时器ID时,即便timer_create()执行成功,运行时si_timerid的值始终为0。进一步排查系统头文件后发现:

  • man signals手册中明确标注siginfo_t结构包含si_timerid字段(用于存储POSIX.1b定时器ID)
  • 实际头文件(由signal.h引入的siginfo.h)并未直接定义该字段,而是通过宏定义实现:
    #define si_timerid _sifields._timer.si_tid
    
  • 测试代码显示,直接访问s_info->_sifields._timer.si_sigval.sival_int能获取到正确的定时器ID,但si_timerid无法正常工作;同时直接访问s_info->_sifields._timer.si_overrun会触发编译错误——因为si_overrun同样是宏定义:
    #define si_overrun    _sifields._timer.si_overrun
    
    宏展开后会变成s_info->_sifields._timer._sifields._timer.si_overrun,属于重复替换导致的语法错误。

问题根源

这是系统头文件的宏定义实现缺陷:

  1. si_timerid的宏指向了错误的底层字段(si_tid而非实际存储定时器ID的si_sigval.sival_int)
  2. si_overrun的宏定义存在符号冲突,手动访问底层结构字段会触发重复展开

临时解决方案

在官方修复前,可绕过宏定义直接访问正确的底层字段:

// 获取正确的定时器ID
timer_t timer_id = s_info->_sifields._timer.si_sigval.sival_int;

对于si_overrun,直接使用宏定义访问即可避免错误:

// 用宏定义访问si_overrun,避免手动展开引发的重复替换
int overrun = s_info->si_overrun;

问题上报途径

若确认是系统头文件bug,可根据使用的操作系统选择对应渠道:

  • Linux系统:通过Linux内核邮件列表(如linux-api@vger.kernel.org或linux-man@vger.kernel.org)提交问题,附上测试代码、头文件版本、系统环境信息;也可在发行版自带的bug跟踪系统(如Debian BTS、Red Hat Bugzilla)提交报告。
  • BSD类系统:提交至对应BSD的开发者邮件列表或官方bug跟踪平台(如FreeBSD Bugzilla)。
  • 其他UNIX-like系统:参考官方文档的bug提交指引,提供清晰的复现步骤、环境信息和问题分析。

内容的提问来源于stack exchange,提问作者Hoks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 19:27:05