【问题标题】:send a signal to lighttpd and the signal can be handled by the LD_PRELOADed library向 lighttpd 发送信号,该信号可由 LD_PRELOADed 库处理
【发布时间】:2017-01-16 15:11:53
【问题描述】:

您好:) 我想使用 LD_PRELOADed 库运行 lighttpd 服务器,我的 LD_PRELOADed 库称为 signal.so,它的代码如下:

#include <signal.h>

struct sigaction sgSA;

static void handler(int signo, siginfo_t *si, void *ptr)
{ 
    if(signo == SIGHUP)
        printf("Get a signal -- SIGHUP\n");
}

sgSA.sa_flags = SA_SIGINFO;
sigemptyset(&sgSA.sa_mask);
sgSA.sa_sigaction = handler;

if (sigaction(SIGHUP, &sgSA, NULL) == -1)
    handle_error("sg sigaction");

raise(SIGHUP);

当我使用命令运行带有库的程序时:

$sudo LD_PRELOAD=./signal.so ./lighttpd -f /usr/local/lighttpd/config/lighttpd.conf

它不打印字符串“Get a signal -- SIGHUP”,我在另一个简单的程序而不是 lighttpd 服务器上尝试了这个,它确实可以打印这个字符串。这让我很困惑。所以,我的问题是:如何让信号由我的 LD_PRELOADed 库中的处理程序处理?谢了!

【问题讨论】:

  • 首先,检查库是否完全是LD_PRELOAD-ed(setuid 二进制文件忽略它)。此外,lighttpd 可能稍后会重置处理程序,以便您可以拦截 signalsigaction 以查看是否是这种情况。
  • 我没有验证具体的原因,但似乎 lighttpd 总是陷入它自己的处理程序中。因此,我改用保留信号SIGUSR2,就可以解决了。谢谢你的提议。

标签: signals lighttpd ld-preload


【解决方案1】:

乍一看,我认为 lighttpd 可能会在其代码逻辑中捕获一些信号,这会覆盖 LD_PRELOADed 信号处理代码。于是我搜索了lighttpd的代码库,发现它确实在src/server.c中捕获了SIGINTSIGHUP等一些信号。

我试图用LD_PRELOAD 捕捉SIGUSR2 之类的信号(不被lighttpd 捕捉),但它仍然不打印任何东西。使用strace打印系统调用日志,说明我们已经进入了预加载的SIGUSR2信号处理器(write(1, "Get a signal ..."))。因此,似乎由于某些原因,lighttpd 抑制了 printf 将日志打印到控制台。

【讨论】:

  • lighttpd 打开 stdinstdout 到 /dev/null。如果你想让 stderr 进入控制台,那么不要在 lighttpd.conf 中定义 server.errorlog 或 server.breakagelog
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-16
相关资源
最近更新 更多