而 return si_addr 与 sigwaitinfo 函数的偏移导致分段错误
While return si_addr with offset from sigwaitinfo function causing segmentation fault
我正在研究 signal handler
来处理收割信号,当我调用 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
。它仅适用于有限数量的信号,并且不包括任何 real-time 信号。
Per POSIX、si_addr
不适用于SIGILL
、SIGFPE
、SIGSEGV
和SIGBUS
以外的信号。 Linux 还为 SIGTRAP
:
提供 si_addr
数据
SIGILL
, SIGFPE
, SIGSEGV
, SIGBUS
, and SIGTRAP
fill in si_addr
with the address of the fault.
没有其他信号提供 si_addr
的值。
填写si_addr
的The source code linux/kernel/signal.c
清楚地表明si_addr
不用于列出的信号以外的任何信号。
请注意,根据 the Linux signal(7)
man page:
Real-time signals are distinguished by the following:
Multiple instances of real-time signals can be queued. By
contrast, if multiple instances of a standard signal are
delivered while that signal is currently blocked, then only one
instance is queued.
If the signal is sent using sigqueue(3)
, an accompanying value
(either an integer or a pointer) can be sent with the signal. If
the receiving process establishes a handler for this signal using
the SA_SIGINFO
flag to sigaction(2)
, then it can obtain this data
via the si_value
field of the siginfo_t
structure passed as the
second argument to the handler. Furthermore, the si_pid
and
si_uid
fields of this structure can be used to obtain the PID and
real user ID of the process sending the signal.
...
我正在研究 signal handler
来处理收割信号,当我调用 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
。它仅适用于有限数量的信号,并且不包括任何 real-time 信号。
Per POSIX、si_addr
不适用于SIGILL
、SIGFPE
、SIGSEGV
和SIGBUS
以外的信号。 Linux 还为 SIGTRAP
:
si_addr
数据
SIGILL
,SIGFPE
,SIGSEGV
,SIGBUS
, andSIGTRAP
fill insi_addr
with the address of the fault.
没有其他信号提供 si_addr
的值。
si_addr
的The source code linux/kernel/signal.c
清楚地表明si_addr
不用于列出的信号以外的任何信号。
请注意,根据 the Linux signal(7)
man page:
Real-time signals are distinguished by the following:
Multiple instances of real-time signals can be queued. By contrast, if multiple instances of a standard signal are delivered while that signal is currently blocked, then only one instance is queued.
If the signal is sent using
sigqueue(3)
, an accompanying value (either an integer or a pointer) can be sent with the signal. If the receiving process establishes a handler for this signal using theSA_SIGINFO
flag tosigaction(2)
, then it can obtain this data via thesi_value
field of thesiginfo_t
structure passed as the second argument to the handler. Furthermore, thesi_pid
andsi_uid
fields of this structure can be used to obtain the PID and real user ID of the process sending the signal....