尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

2024-06-20

我尝试过使用 sigaction 和 ctypes 设置信号处理程序。 (我知道它可以与python中的信号模块一起使用,但我想尝试学习。)

当我向该进程发送 SIGTERM 时,但它没有调用我设置的处理程序,只打印“终止”。 为什么它不调用处理程序?

我使用 Ubuntu 19.10 和 Python 3.7.5 x64。

import ctypes
from ctypes import *
from ctypes.util import *
from os import getpid


class sigset_t(Structure):
    __fields__ = [
        ("__val",               c_ulong*16)        
    ]

class sigval_t(Union):
    __fields__ = [
        ("sival_int",           c_int),
        ("sival_ptr",           c_void_p)
    ]



class siginfo_t(Structure):
    __fields__ = [
        ("si_signo",            c_int),
        ("si_errno",            c_int),
        ("si_code",             c_int),
        ("si_trapno",           c_int),
        ("si_pid",              c_uint),
        ("si_status",           c_int),
        ("si_utime",            c_long),
        ("si_stime",            c_long),
        ("si_value",            sigval_t),
        ("si_int",              c_int),
        ("si_ptr",              c_void_p),
        ("si_overrun",          c_int),
        ("si_timerid",          c_int),
        ("si_addr",             c_void_p),
        ("si_band",             c_long),
        ("si_fd",               c_int),
        ("si_addr_lsb",         c_short),
        ("si_call_addr",        c_void_p),
        ("si_syscall",          c_int),
        ("si_arch",             c_uint)

    ]

sa_handler_functype = CFUNCTYPE(None, c_int)
sigaction_functype = CFUNCTYPE(None, c_int, siginfo_t, c_void_p)


class SIGACTION(Structure):
    __fields__ = [
        ("sa_handler",          sa_handler_functype),
        ("sa_sigaction",        sigaction_functype),
        ("sa_mask",             sigset_t),
        ("sa_flags",            c_int),

    ]


def p(sig): # signal handler function
    libc.puts("bye")

libc_path = find_library("c")
libc = CDLL(libc_path)

libc.sigaction.restype = c_int
libc.sigaction.argtypes = [c_int, POINTER(SIGACTION), POINTER(SIGACTION)]

act = SIGACTION(sa_handler=sa_handler_functype(p))
print(act)
res = libc.sigaction(15, act, None)
print(res)
print("pid:", getpid()) # show pid
while True: # wait until receive sigterm signal
    pass

Listing [Python 3.Docs]:ctypes - Python 的外部函数库 https://docs.python.org/3/library/ctypes.html#module-ctypes.

代码存在一些问题:

  • ctypes.结构体后代需要定义_fields_ (and not __字段__)。相应地改变了结构
  • 通过了struct sigaction *(指针)作为参数信号动作
  • 根据以下文件的内容修改结构定义/usr/include/位 (on my 乌布图 16 x64 VM)
  • Defined argtypes and restype对于任何使用的函数(puts)。查看[SO]:通过 ctypes 从 Python 调用的 C 函数返回不正确的值(@CristiFati 的答案) https://stackoverflow.com/questions/58610333/c-function-called-from-python-via-ctypes-returns-incorrect-value/58611011#58611011更多细节
  • 其他(次要)变更

代码00.py:

#!/usr/bin/env python3

import sys
import os
import time
from ctypes import Structure, Union, POINTER, CFUNCTYPE, CDLL, byref, sizeof, \
    c_short, c_int, c_uint, c_long, c_ulong, c_char_p, c_void_p


SIGTERM = 15


class sigset_t(Structure):
    _fields_ = [
        ("__val", c_ulong * (1024 // (8 * sizeof (c_long)))),
    ]


'''
class sigval_t(Union):
    _fields_ = [
        ("sival_int", c_int),
        ("sival_ptr", c_void_p),
    ]


class siginfo_t(Structure):
    _fields_ = [
        ("si_signo", c_int),
        ("si_errno", c_int),
        ("si_code", c_int),
        ("_pad", c_int * 29),
    ]


sa_sigaction_functype = CFUNCTYPE(None, c_int, POINTER(siginfo_t), c_void_p)
'''
sa_handler_functype = CFUNCTYPE(None, c_int, use_errno=True)


class SIGACTION(Structure):
    _fields_ = [
        ("sa_handler", sa_handler_functype),
        ("sa_mask", sigset_t),
        ("sa_flags", c_int),
        ("sa_restorer", c_void_p),
    ]


libc = CDLL(None)


def sighandler(sig):  # Signal handler function
    libc.puts.argtypes = [c_char_p]
    libc.puts.restype = c_int
    libc.puts("Custom signal handler called for signal {0:d}".format(sig).encode())


def main(*argv):

    libc.sigaction.argtypes = [c_int, POINTER(SIGACTION), POINTER(SIGACTION)]
    libc.sigaction.restype = c_int

    signal_number = SIGTERM
    act = SIGACTION(sa_handler=sa_handler_functype(sighandler))
    #print(act)

    res = libc.sigaction(signal_number, byref(act), None)
    print("sigaction result: {0:d}".format(res))
    print("PId {0:d} waiting for SIG {1:d}...".format(os.getpid(), signal_number))

    while 1:
        time.sleep(0.1)


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main(*sys.argv[1:])
    print("\nDone.")

Output(程序运行时,发送SIGTERM然后两次SIGKILL从另一个终端):

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> uname -m
x86_64
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> cat /etc/lsb-release | grep DESCR
DISTRIB_DESCRIPTION="Ubuntu 16.04.6 LTS"
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q059521251]> python3 code00.py
Python 3.5.2 (default, Oct  8 2019, 13:06:37) [GCC 5.4.0 20160609] 64bit on linux

sigaction result: 0
PId 20050 waiting for SIG 15...
Custom signal handler called for signal 15
Custom signal handler called for signal 15
Killed
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它 的相关文章

随机推荐

  • Android Studio 无法识别 Mac/Linux 上的 OnePlus2

    我的 Android Studio 1 3 2 无法识别我的手机 一加二号 我有 Mac OS x Yosemite 10 10 5 和最新的 Android SDK 更新1 我的Mac上安装的文件传输软件 Android File Tra
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • django Q 对象嵌套reduce

    得到非常复杂的查询 请不要尝试解决示例 问题更复杂 crit crit append Q firstcond name Q firstcond isnull True crit append Q secondcond name Q firs
  • 提交表单并重定向页面

    我在 SO 上看到了很多与此相关的其他问题 但没有一个对我有用 我正在尝试提交POST表单 然后将用户重定向到另一个页面 但我无法同时实现这两种情况 我可以获取重定向或帖子 但不能同时获取两者 这是我现在所拥有的
  • 如何使用 LINQ2SQL 连接两个不同上下文的表?

    我的应用程序中有 2 个数据上下文 不同的数据库 并且需要能够通过上下文 B 中的表的右连接来查询上下文 A 中的表 我该如何在 LINQ2SQL 中执行此操作 Why 我们正在使用 SaaS 产品来跟踪我们的时间 项目等 并希望向该产品发
  • 向上滚动时固定项目

    所以我有以下屏幕 我正在寻找一种方法 使得当用户向上滚动时 包含进度条和这 4 个数据字段 ItemHeader 的小部件将向上滚动 但搜索容器 SearchTextField 将被固定 到顶部 当然 当用户向下滚动时 它应该重新出现 我找
  • UIView 圆角 - Swift 2.0?

    我会尝试将一些项目更新到 Swift 2 0 我有一个视图 左上角有一个圆角 在 Swift 没有警告 没有错误 只是没有圆角 这就是它在 Swift let maskPath UIBezierPath roundedRect conten
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • 由 IHttpClientFactory 注入时模拟 HttpClient 处理程序

    我创建了一个自定义库 它会自动为依赖于特定服务的 Polly 策略设置HttpClient 这是使用以下方法完成的IServiceCollection扩展方法和类型化客户端方法 一个简化的例子 public static IHttpClie
  • 关于 Hadoop 和压缩输入文件的非常基本的问题

    我已经开始研究 Hadoop 如果我的理解是正确的 我可以处理一个非常大的文件 它会被分割到不同的节点上 但是如果文件被压缩 那么文件就无法分割 并且需要由单个节点处理 有效地破坏了运行一个mapreduce 一个并行机器集群 我的问题是
  • 如何匹配 R 中的所有匹配项?

    我有 1000 个名字的列表 说A 我还有另外 5 个名字的清单 说B 我想找出这5个名字出现在1000个号码列表中的第几行 例如 Amy 在 A 中可以出现 25 次 B 里有艾米 我想知道 Amy 出现在 A 中的哪些行 我以前使用过
  • firebase :: 无法读取 null 的属性“props”

    你好 我正在尝试将react router与firebase一起使用 但它给了我这个错误 无法读取 null 的属性 props 这正是代码 我正在其中使用我的反应路由器 向下代码位于作为登录面板组件的组件上 else if this em
  • 现在 CSS3 供应商前缀有多必要? [复制]

    这个问题在这里已经有答案了 我只是想知道现在在 CSS 中指定 webkit moz ms 或 o 等供应商前缀在多大程度上仍然有必要 如果我理解正确的话 opera 切换到了 webkit 所以会删除 o 对吗 IE 在 IE10 中不再
  • Grails 在 javascript 内的 GSP 站点中使用 grails var

    我有一个在 GSP 文件中的 javascript 代码中使用 grails 变量值的问题 例如 我有一个会话值session getAttribute selectedValue 我想在 javascript 代码部分使用这个值 我现在的
  • 将 Word 文档另存为图像

    我正在使用下面的代码将 Word 文档转换为图像文件 但是图片显得太大 内容不适合 有没有办法渲染图片或将图片保存到合适的尺寸 private void btnConvert Click object sender EventArgs e
  • 在 iFrame 内维护会话状态

    不确定我是否疯了 但我在 iFrame 内的会话状态遇到问题 它是一个域在另一个域中的简单设置 我不需要跨域共享任何内容 我想做的就是将一个网站嵌入到另一个网站中 并且我希望该嵌入网站能够使用 cookie 会话状态登录 编辑 更新 等 为
  • META-INF/服务应该在 sbt 中的哪里

    META INF 目录应该放在哪里 以便 sbt 获取自定义配置 我在尝试使用 ServiceLoader 时遇到了这个问题 并且我试图在 META INF services 中创建自定义服务 如果您将 META INF 文件夹放在 src
  • 非 Spring 托管类中 DI 的编译时编织

    我想为标记为的类配置编译时编织 Configurable注释能够将 spring 依赖项注入到初始化的类中new操作员 我不想使用加载时编织 因为我无权访问应用程序服务器的运行脚本 因此无法修改它 另外 我希望能够在测试中使用此类 我的意思
  • Typescript导入别名+桶文件

    我最近花了很多时间 因为 Angular ngrx typescript 生态系统中某些事物的特定行为 并且我无法识别可能的根本原因 场景 我已经构建了一些效果 并将它们导出到桶文件中 index ts import MyEffects f
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序