问题标签 [sigaction]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
852 浏览

c - OS X sigaction 错误地设置了 sa_mask

在 macbook (OSX 10.9.5 (13F34)) 上,以下简单程序:

神秘打印:

我希望 的sa_mask成员与给出的osa匹配。masksigprocmask

POSIX 是否为此字段指定任何要求?手册中唯一提到它的是关于不可阻塞的信号,例如SIGKILL,其中未指定该值。

在 linux 上,这个程序打印:

正如预期的那样。

gcc 版本是:

二进制文件链接到:

0 投票
0 回答
825 浏览

macos - 使用 sigaction 和 setitimer 系统调用在 BSD/OS X 上实现汇编语言计时器

我正在尝试使用 sigaction() 和 setitimer() 系统调用在 OS X Lion 上的 32 位汇编程序中实现计时器例程。这个想法是使用 setitimer() 设置一个计时器,然后让生成的警报信号调用之前通过 sigaction() 设置的处理函数。我有这样的机制在 Linux 上运行,但似乎无法让它在 OS X 上运行。我知道 OS X 和 Linux 之间的系统调用约定不同,并且 OS X 有 16 字节对齐要求。尽管对这些进行了补偿,但我仍然无法使其正常工作(通常是“总线错误:10”错误)。认为我在对齐方面做错了,我编写了一个简单的 C 程序来执行我想要的操作,然后使用 clang 3.2 生成汇编代码。然后我通过替换对 sigaction() & 的调用来修改机器生成的程序集 setitimer() 与适当的系统 & int $0x80 调用,以及堆栈对齐指令。结果程序仍然不起作用。

这是我用来生成程序集的 C 程序 sigaction.c。请注意,我注释掉了 printf 和 sleep 的东西,因此生成的汇编代码更容易阅读:

}

这是在上述文件中使用“clang -arch i386 -S sigaction.c”生成的汇编代码:

如果我使用“clang -arch i386 sigaction.s -o sigaction”编译汇编代码,使用 lldb 调试它并在处理函数中放置一个断点,处理函数确实每秒调用一次。所以我知道汇编代码是正确的(C 代码也是如此)。

现在,如果我将对 sigaction() 的调用替换为:

以及对 setitimer() 的调用:

汇编代码不再起作用,并生成与我的手工编码汇编代码相同的“总线错误:10”。

我尝试删除用于对齐堆栈的 subl/addl 指令以及更改值以确保堆栈在 16 字节边界上对齐,但似乎没有任何效果。我要么得到总线错误、分段错误,要么代码在没有调用处理函数的情况下挂起。

我在调试期间确实注意到的一件事是 sigaction 调用似乎对底层系统调用有一个冗长的包装。如果您从 lldb 中反汇编这两个函数,您会看到 sigaction() 有一个冗长的包装器,但 setitimer 没有。不确定这意味着什么,但也许 sigaction() 包装器在传递数据之前正在处理数据。我尝试调试该代码,但还没有找到任何确定的东西。

如果有人知道如何通过用适当的系统调用替换 sigaction() 和 setitimer() 函数来使上述汇编代码工作,将不胜感激。然后我可以进行这些更改并将它们应用到我的手工编码例程中。

谢谢。

更新:我将我的手写汇编代码剥离到可管理的大小,并且能够使用 sigaction() 和 setitimer() 库调用使其工作,但仍然没有弄清楚为什么系统调用不起作用。这是代码(timer.s):

当使用“clang -arch i386 timer.s -o timer”编译并使用 lldb 调试时,处理程序例程每秒调用一次。我放弃了使代码与代码中的系统调用一起工作的努力——它们在 sigaction() 和 setitimer() 调用周围被注释掉了。如果除了教育自己(和其他人)之外没有其他原因,我仍然希望尽可能让系统调用版本正常工作,如果没有,请了解它不起作用的原因。

再次感谢。

更新 2:我让 setitimer 系统调用正常工作。这是修改后的代码:

但是相同的编辑不适用于 sigaction sys 调用,这使我回到了最初的结论 - sigaction() 库函数在进行实际的 syscall 之前做了一些额外的事情。来自 dtruss 的这个片段似乎暗示了同样的事情:

使用 sigaction() 系统调用(不工作):

使用 sigaction() 库调用(工作):

如您所见,两个版本之间的第二个参数是不同的。使用系统调用时,似乎直接传递了 sigaction 结构的地址(0x2030),但使用库调用时传递了其他东西。我猜“其他东西”是在 sigaction() 库函数中生成的。

更新 3:我发现 FreeBSD 9.1 上存在同样的问题。setitimer 系统调用有效,但 sigaction 系统调用无效。与 OS X 一样,sigaction() 库调用确实有效。

BSD 有一些 sigaction 系统调用 - 到目前为止,我只尝试过我在 OS X 中使用的同一个 - 0x2e。也许其他 sigaction 系统调用之一会起作用。知道 BSD 具有相同的行为将使这更容易追踪,因为我可以提取 C 源代码。此外,这向可能已经知道问题所在的更广泛的人群开放了问题。

基于我对系统调用如何工作的理解以及 sigaction 在 Linux 上工作的事实,我不禁认为我的代码做错了什么。然而,用 sigaction() 库函数替换 int $0x80 调用导致我的代码工作的事实似乎与此相矛盾。FreeBSD 开发人员手册中有一整章是关于汇编语言编程的,还有一节是关于进行系统调用的,所以我正在做的应该是可能的:

https://www.freebsd.org/doc/en_US.ISO8859-1/books/developers-handbook/x86-system-calls.html

除非有人能指出我做错了什么(如果有的话),否则我认为下一步是让我查看 sigaction() 的 BSD 源代码。正如我之前提到的,我查看了 OS X 上 sigaction 的反汇编版本,发现它与其他系统调用相比相当长,并且充满了幻数。希望通过查看 C 代码可以清楚地了解它在做什么才能使其正常工作。最后,它可能很简单,例如传入错误的 sigaction 结构(其中有几个)或未能在某处设置一些位。

0 投票
1 回答
325 浏览

signals - 何时(以及为什么)使用“sigaction()”而不是“signal()”?

我正在深入研究系统函数 signal() 和 sigaction()

我阅读了有关这两个功能的一些页面,它们主要讨论了可移植性和“非竞争条件”的区别。

谁能为我澄清这些?

ps 当我们尝试更改控制信号时,我被引导使用 sigaction() 函数而不是 signal() 函数。这是为什么?

任何帮助,将不胜感激。感谢你们!!

0 投票
1 回答
1475 浏览

c - 多个信号到达处理程序

我有一个分叉了一些子进程的主进程。

每个孩子都会做一些事情并阻止自己。SICHLD通过阻塞自己,每个子进程都会向父进程发送信号。

我还在sigaction主流程代码中声明了一个动作,以捕捉SIGCLHD孩子们将发送的动作。

处理程序在SIGCHLD调用时检查哪个孩子发送了SIGCHLD信号并为那个孩子做一些事情。

问题是,如果多个孩子同时发送信号会发生什么?假设孩子(1)发送了SIGCHLD. 处理程序捕获它并且在他完成句柄之前,kid(2) 和kid(3) 都发送信号。处理程序是否会在处理完 child(1) 后针对每个信号运行,还是会忽略这些信号?

0 投票
1 回答
756 浏览

c - sigaction 如何既是结构又是函数?

我注意到它sigaction被定义为一个结构和一个函数(http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html):

使用它的一个例子是:

0 投票
1 回答
853 浏览

shell - 信号与信号

有人可以解释一下sigaction和signal之间的区别吗?我知道它们的信号工作方式不同,具体取决于您在哪台机器上工作,即 Mac、Windows 或 Linux,并且 sigaction 在所有平台上的工作方式都相同。但我的问题是为什么会这样,因为我尝试在不同的平台上使用信号并且得到了相同的结果。另外,你们会推荐使用哪一个来进行更好的练习。

0 投票
0 回答
334 浏览

c++ - sigaction 处理 ctrl+c aka SIGINT 后等待输入的正确方法

Ctrl在通过+发送 SIGINT 后,该程序将无限打印“Enter a:”到命令行C。要退出此循环,我使用Ctrl+ \。如果我取消注释包含 的行std::cin.clear();,一切正常。我的问题是,这是正确的做法吗?必须std::cin.clear();在他希望程序等待的每个 cin/cout 前面设置。这就是为什么这对我来说似乎不是正确的方式。

PS:我知道信号处理程序中的 cout 是个坏主意。

PPS:std::cin.clear();当我使用旧的 (deprecated) 时,一切正常(没有)signal()

PPPS:只是为了说清楚,我不想在Ctrl+上退出程序C

0 投票
1 回答
973 浏览

c - 使用 linux create_timer 和 sigaction API 时出现分段错误

我正在尝试将以下代码集成到在 ARM<->DSP 系统上运行的更大程序(不幸的是,我无法共享)中:

如您所见,这是一个非常简单的代码,在系统上单独运行时,它运行良好。这里的while循环只是为了演示,可以忽略。处理程序和初始化步骤是相同的​​。

当我尝试将它与更大的程序集成时,问题就开始了 -如果我将计时器间隔设置为短于 10 毫秒,我会突然出现分段错误。

我试图将处理程序中的操作简化为一条简单的行,'curr_time = 0',认为它可能与处理程序中的浮点操作有关,但它没有帮助。

应该注意的是,我为 ARM<->DSP 共享内存缓冲区使用了连续内存分配 API,尽管我怀疑它与它有什么关系,因为我没有在处理程序中分配任何新内存。

那么,有没有人知道分段错误的可能原因?

0 投票
2 回答
11659 浏览

c++ - Sigaction 和将 Linux 代码移植到 Windows

我正在尝试将caffe(为 Linux 开发)源代码移植到 Windows 环境。问题在于和处的sigaction结构。源代码如下所示。我的查询是可以进行哪个库或代码替换以使其在 Windows 中工作。signal_handler.cppsignal_handler.hsigaction

///头文件

///源文件

错误是

0 投票
1 回答
819 浏览

linux - Proper way of handling SIGCHLD, EINT, and accept() in Linux

I have a program that creates a TCP server. When the accept() connects to a client, I fork() it and handle the connection. When that client leaves it calls the waitpid() because of the SIGCHLD, but this causes a EINTR in the accept(). My question is how should this be handled? I've read so many different ways.

Most say to ignore it the EINT and try the accept() again. I've even seen a macro to do just that: TEMP_FAILURE_RETRY(). Some say to set the sigaction flags SA_RESTART and SA_NOCLDSTOP. I've tried that and it introduces other errors (errno = ECHILD). Also, how should the child exit? I've seen both _exit(0) and exit(0).

The SIGCHLD handling is: