标签: signal-handling

在Linux中使用signal.h编译错误

我正在编写一个必须处理信号的shell程序.我的相关信号处理相关代码如下:

#include <signal.h>
...
#include <sys/types.h>
...
void installSigactions( int, struct sigaction* );

void handler_function( int signal_id );
...
/*define signal table*/
struct sigaction signal_action;

/*insert handler function*/
signal_action.sa_handler = handler_function;

/*init the flags field*/
 signal_action.sa_flags = 0;

/*are no masked interrupts*/
sigemptyset( &signal_action.sa_mask );

/*install the signal_actions*/
sigaction( SIGINT, &signal_action, NULL );
Run Code Online (Sandbox Code Playgroud)

编译给我以下警告和错误:

gcc -Wall -ggdb -ansi -static -pedantic -o os1shell2 os1shell2.c
os1shell2.c:35: warning: 'struct sigaction' declared inside parameter list
os1shell2.c:35: warning: its scope is only this definition or …
Run Code Online (Sandbox Code Playgroud)

c linux signals system-calls signal-handling

15
推荐指数
1
解决办法
2万
查看次数

我如何删除信号处理程序

我做了跟随信号处理程序

struct sigaction pipeIn;
pipeIn.sa_handler = updateServer;
sigemptyset(&pipeIn.sa_mask);
sa.sa_flags = SA_RESTART;

if(sigaction(SIGUSR1, &pipeIn, NULL) == -1){

    printf("We have a problem, sigaction is not working.\n");
    perror("\n");
    exit(1);    

}
Run Code Online (Sandbox Code Playgroud)

如何删除或阻止此特定处理程序,以便我可以设置另一个使用相同信号的信号处理程序?谢谢.

c posix signal-handling

15
推荐指数
1
解决办法
8452
查看次数

std::atomic_flag 可以在信号处理程序中使用吗

根据C++17 标准 [support.signal],原子对象应满足以下要求才能在信号处理程序中使用:

\n
\n
    \n
  • [...], 或者
  • \n
  • f是在对象上调用的非静态成员函数A,这样A.is_\xc2\xadlock_\xc2\xadfree()会产生true,或
  • \n
  • fA是一个非成员函数,并且对于传递给 的每个指向原子参数的指针fatomic_\xc2\xadis_\xc2\xadlock_\xc2\xadfree(A)都会产生true
  • \n
\n
\n

std::atomic_flag正式地不适合这里(没有is_lock_free方法并且atomic_is_lock_free不能用std::atomic_flag对象调用)。虽然直观上来说,它非常接近(它是原子的且无锁的)。这是否意味着std::atomic_flag不能在信号处理程序中使用,或者它只是一个需要澄清的 C++ 标准?

\n

c++ atomic signal-handling language-lawyer c++17

15
推荐指数
1
解决办法
654
查看次数

什么构成异步安全

据说你应该只在信号处理程序中调用异步安全函数.我的问题是,什么构成异步安全?我认为一个可重入线程安全的函数是异步安全的吗?或没有?

c linux synchronization asynchronous signal-handling

14
推荐指数
1
解决办法
3699
查看次数

多线程环境中的信号处理函数

在我的多线程GUI应用程序中,我有以下信号处理代码.我想改进这个代码,以便它是正确的和线程安全的但是在信号处理中有一些我不完全理解的东西:

  • 是在进程或线程级别处理的信号(我可以使用特定于线程的信号处理程序)吗?
  • 哪个线程上下文是signal_handler函数执行的?
  • 是否可以在短时间内发送许多SIGTERM信号?
  • 使用互斥锁来阻止signal_handler的并行执行是否有意义?

void signal_handler(int sig)
{
        switch (sig)
        {
        case SIGTERM:
            ::wxLogMessage(wxT("SIGTERM signal received ..."));
            break;
        case SIGINT:
            ::wxLogMessage(wxT("SIGINT signal received ..."));
            break;
        case SIGUSR1:
            ::wxLogMessage(wxT("SIGUSR1 signal received ..."));
            break;
        default:
            ::wxLogMessage(wxT("Unknown signal received ..."));
        }

        // send wxCloseEvent to main application window
        ::wxGetApp().GetTopWindow()->Close(true);
}
Run Code Online (Sandbox Code Playgroud)

我在init函数中注册信号处理程序:

// register signal handlers
signal(SIGTERM, signal_handler);
signal(SIGINT,  signal_handler);
signal(SIGUSR1, signal_handler);
Run Code Online (Sandbox Code Playgroud)

c c++ multithreading signal-handling

14
推荐指数
3
解决办法
1万
查看次数

python:相当于SIGALRM的windows

我有这个装饰:

def timed_out(timeout):
    def decorate(f):
        if not hasattr(signal, "SIGALRM"):
            return f

        def handler(signum, frame):
            raise TimedOutExc()

        @functools.wraps(f)
        def new_f(*args, **kwargs):
            old = signal.signal(signal.SIGALRM, handler)
            signal.alarm(timeout)
            try:
                result = f(*args, **kwargs)
            finally:
                signal.signal(signal.SIGALRM, old)
            signal.alarm(0)
            return result

        new_f.func_name = f.func_name
        return new_f

    return decorate
Run Code Online (Sandbox Code Playgroud)

但代码只能在linux上执行任何操作,因为在Windows上,没有SIGALRM.在Windows中使用此代码的最简单方法是什么?

python windows signals signal-handling alarm

12
推荐指数
1
解决办法
2万
查看次数

longjmp和RAII

所以我有一个库(不是我写的),不幸的是它abort()用来处理某些错误.在应用程序级别,这些错误是可恢复的,所以我想处理它们而不是用户看到崩溃.所以我最终编写这样的代码:

static jmp_buf abort_buffer;
static void abort_handler(int) {
    longjmp(abort_buffer, 1); // perhaps siglongjmp if available..
}

int function(int x, int y) {

    struct sigaction new_sa;
    struct sigaction old_sa;

    sigemptyset(&new_sa.sa_mask);
    new_sa.sa_handler = abort_handler;
    sigaction(SIGABRT, &new_sa, &old_sa);

    if(setjmp(abort_buffer)) {
        sigaction(SIGABRT, &old_sa, 0);
        return -1
    }

    // attempt to do some work here
    int result = f(x, y); // may call abort!

    sigaction(SIGABRT, &old_sa, 0);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

代码不是很优雅.由于这种模式最终必须在代码的几个点重复,我想简化一点,并可能将它包装在一个可重用的对象中.我的第一次尝试涉及使用RAII来处理信号处理程序的设置/拆除(需要完成,因为每个函数需要不同的错误处理).所以我想出了这个:

template <int N>
struct signal_guard {
    signal_guard(void (*f)(int)) {
        sigemptyset(&new_sa.sa_mask);
        new_sa.sa_handler = …
Run Code Online (Sandbox Code Playgroud)

c++ raii signal-handling longjmp

10
推荐指数
1
解决办法
843
查看次数

python-daemon中的信号处理

我安装了python-daemon,现在我正在尝试正确处理信号.我的代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import signal, time, syslog
import daemon

def runDaemon():
    context = daemon.DaemonContext()

    context.signal_map = { signal.SIGTERM: programCleanup }

    context.open()
    with context:
        doMainProgram()

def doMainProgram():
    while True:
        syslog.syslog("pythonDaemon is running")
        time.sleep(5)

def programCleanup():
    syslog.syslog("pythonDaemon STOP")

if __name__ == "__main__":
    runDaemon()
Run Code Online (Sandbox Code Playgroud)

当我启动代码时,一切都按预期工作:正在运行的文本pythonDaemon/var/log/syslog每5秒写一次.但是当我想终止守护进程时kill -TERM *PID*守护进程被终止但是syslog中缺少文本pythonDaemon STOP.

我究竟做错了什么?

注意:我没有在from daemon import runner这里工作,因为这给了我一个错误(看起来我需要一个旧版本lockfile),我不会解决这个问题,除非它是唯一能够正确处理信号的可能性.

python linux signal-handling python-2.7 python-daemon

10
推荐指数
1
解决办法
4224
查看次数

捕获对地址范围的所有访问(Linux)

背景

我正在编写一个框架来实现在模拟器和未修改的主机软件中运行的RTL的协同仿真.编写主机软件以控制实际硬件,通常以两种方式之一工作:

  1. 通过驱动程序读/写呼叫
  2. 使用mmap进行内存映射访问

前一种情况非常简单 - 编写一个库,它实现与驱动程序相同的读/写调用,并在运行模拟时与之相关联.这一切都非常有效,我可以运行未经修改的生产软件作为我的RTL模拟的刺激.

第二种情况比第一种情况要困难得多......

陷阱mmap

最初我以为我可以LD_PRELOAD用来拦截mmap调用.在我的实现中,mmap我会分配一些页面对齐的内存,然后mprotect设置一个信号处理程序来捕获SIGSEGV.

这种方法存在许多问题:

读取与写入

我可以确定访问的地址,siginfo_t->si_addr但不能确定访问是读还是写.

捕获重复访问

在信号处理程序中,我需要取消保护内存区域,否则SIGSEGV只要我的处理程序退出并且主机代码永远不会继续,我就会重复.但是,如果我取消保护区域,那么我的信号处理程序将不会捕获后续访问.

信号处理程序的肮脏

在模拟器驱动RTL并返回结果时阻塞信号处理程序违反了各种编程规则 - 特别是假设模拟器可以触发各种其他事件并在从此访问返回结果之前执行任意代码.

其他方法

我想知道是否可以创建一个类似文件的对象,其行为类似于磁盘,而不是mprotect在缓冲区上使用.我没有找到任何表明这是可行的信息.

问题

是否可以捕获对mmap区域的所有访问以及如何?

  • 访问需要阻止不确定的时间段(模拟器运行时)
  • 读取访问需要检索由我的陷阱放置的新值

假设LD_PRELOAD并且mprotect是最佳路线:

  • 我可以确定访问是读取还是写入调用?
  • 如何捕获后续访问,因为我必须访问mprotect该区域?

相关问题

如何编写信号处理程序来捕获SIGSEGV?

可以捕获写入地址(x86 - linux)

c linux mmap system-calls signal-handling

9
推荐指数
1
解决办法
2382
查看次数

使用qemu-user进行信号处理

在我的机器上,我有一个aarch64二进制文件,它是静态编译的.我使用带-g 6566标志的qemu-aarch64-static运行它.在另一个终端,我启动gdb-multiarch并连接为target remote localhost:6566.

我希望二进制文件引发一个信号,我在二进制文件中定义了一个处理程序.我gdb-multiarch在连接到远程后从内部设置了一个断点.但是,当信号出现时,断点不会在gdb-multiarch上命中.相反,在运行二进制文件的终端上,我得到一条消息:

[1]     + 8388 suspended (signal)  qemu-aarch64-static -g 6566 ./testbinary
Run Code Online (Sandbox Code Playgroud)

为什么会这样?如何在处理程序上设置断点并对其进行调试?我尝试过SIGCHLD和SIGFPE.

linux gdb signals qemu signal-handling

9
推荐指数
1
解决办法
543
查看次数