我正在研究signal handler
来处理reap信号,当我调用sigwaitinfo
函数时,随机得到带偏移量的信号。所有的信号属性都是正确的,除了info.si_addr
。info.si_addr
中的偏移量导致了分割错误。
这个偏移量看起来是一样的-我试过删除偏移量,这很有效,但我需要一个正确的解决方案来继续。
static void *signalHandler(void *vptr_args __attribute__((unused)))
{
sigset_t signal_set;
siginfo_t info;
sigemptyset(&signal_set);
sigaddset(&signal_set, SIG_REAP);
sigaddset(&signal_set, SIG_ISOC_CANCEL);
sigaddset(&signal_set, SIGTERM);
sigaddset(&signal_set, SIGPIPE);
while (true) {
int rc = sigwaitinfo(&signal_set, &info);
//...
if (rc > 0)
{
if(info.si_signo == SIG_REAP)
{
// Reap URBs after some simple checks
if ((info.si_code != SI_ASYNCIO) &&
(info.si_code != SI_KERNEL)) {
printf("Bad si_code %d in SIG_REAP", info.si_code);
continue;
}
else {
printf("OK si_code %d in SIG_REAP", info.si_code);
}
struct usbdevfs_urb *ioctl_urb = (struct usbdevfs_urb*)info.si_addres
if (!ioctl_urb) {
printf("SIG_REAP gave NULL ioctl_urb");
continue;
}
UrbInfo *urbInfo = ioctl_urb->usercontext;
if (!urbInfo) {
printf("SIG_REAP gave NULL urbInfo");
continue;
}
最佳答案
你误用了si_addr
。它只适用于有限数量的信号,而那些信号不包括任何实时信号。
Per POSIX、si_addr
不适用于SIGILL
、SIGFPE
、SIGSEGV
和SIGBUS
以外的信号。Linux还为si_addr
提供SIGTRAP
数据:SIGILL
、SIGFPE
、SIGSEGV
、SIGBUS
和SIGTRAP
填写故障地址。
没有其他信号提供si_addr
的值。
The source code si_addr
中填写的linux/kernel/signal.c
清楚地表明si_addr
不用于所列信号以外的任何信号。
请注意,perthe Linux si_addr
man page:
实时信号的区别如下:
实时信号的多个实例可以排队。由
对比度,如果一个标准信号的多个实例
在该信号当前被阻止时发送,则只有一个
实例已排队。
如果使用signal(7)
发送信号,则伴随值
(整数或指针)可以随信号一起发送。如果
接收过程使用
将sigqueue(3)
标志设置为SA_SIGINFO
,则可以获取此数据
通过sigaction(2)
结构的si_value
字段
处理程序的第二个参数。此外,siginfo_t
和si_pid
此结构的字段可用于获取PID和
发送信号的进程的实际用户ID。
…