假设进程在有限的环境中运行:
(
ulimit ... -v ... -t ... -x 0 ...
./program
)
程序终止。
可能有很多原因:超出了内存/时间/文件限制;只是简单的段错; 甚至正常终止,返回码为0。
如何在不修改程序的情况下检查程序终止的原因?
PS我的意思是“当给定二进制文件时”。也许一些包装器(ptrace-ing等)可能会有所帮助?
假设进程在有限的环境中运行:
(
ulimit ... -v ... -t ... -x 0 ...
./program
)
程序终止。
可能有很多原因:超出了内存/时间/文件限制;只是简单的段错; 甚至正常终止,返回码为0。
如何在不修改程序的情况下检查程序终止的原因?
PS我的意思是“当给定二进制文件时”。也许一些包装器(ptrace-ing等)可能会有所帮助?
Answers:
一般来说,我认为您不能不幸。(某些操作系统可能会为此提供支持,但是我不知道我所知道的支持此功能的。)
有关资源限制的参考文档:getrlimit
来自POSIX 2008。
以CPU限制为例RLIMIT_CPU
。
SIGXCPU
SIGKILL
如果可以wait()
在程序上执行,则可以确定该程序是否已被杀死SIGXCPU
。但是您无法区分SIGKILL
因违反硬限制而派遣的派遣人员与外部的普通老杀手。而且,如果程序处理XCPU
,您甚至不会从外部看到它。
同样的事情RLIMIT_FSIZE
。如果程序不处理,则可以SIGXFSZ
从wait()
状态中看到。但是一旦超出文件大小限制,唯一发生的事情就是将再次收到尝试再次测试该限制的I / O,EFBIG
这将由程序内部处理(或不幸的是,不会)。如果程序处理SIGXFSZ
,则与上述相同-您将不会知道。
RLIMIT_NOFILE
?好吧,您甚至都没有收到信号。open
和朋友只需返回EMFILE
该程序。它不会以其他方式困扰,因此在这种情况下,无论采用哪种编码方式,它都会失败(或不会失败)。
RLIMIT_STACK
?好老SIGSEGV
,无法与其他原因得分相提并论。(您将从状态中得知这是杀死进程的原因wait
。)
RLIMIT_AS
并且RLIMIT_DATA
只会使malloc()
其他一些失败(或者SIGSEGV
在尝试扩展Linux上的堆栈时达到了AS限制时接收失败)。除非程序编写得非常好,否则在那时可能会相当随机地失败。
简而言之,总的来说,这些失败与其他进程死因没有明显的不同,因此您不能确定,或者可以完全由程序处理,在这种情况下,它决定是否/何时/如何进行,而不是您从外部。
据我所知,您能做的最好的事情就是编写一些代码,将其分叉到您的程序中,然后等待,然后:
SIGXCPU
和SIGXFSZ
(AFAIK,这些信号仅在操作系统出现资源限制问题时才产生)。根据您的确切需求,您可以假设SIGKILL
且SIGSEGV
也与资源限制有关,但这有点麻烦。getrusage(RUSAGE_CHILDREN,...)
实现中获得什么,以获取有关其他实现的提示。可能存在特定于OS的工具来帮助您(可能ptrace
在Linux或Solaris上类似dtrace
),或者可能是调试器类型的技术,但这将与您的特定实现更加紧密地联系在一起。
(我希望其他人会回答一些我完全不知道的不可思议的事情。)
LD_PRELOAD
荷兰国际集团说的界线为贵“不修改的过程中”约束,它会有点帮助,但不是真的- ,,malloc
并且将失败,完全一样,如果你真的是在内存不足的情况(但远低于内存限制)。时限为,我不知道挂钟的时限。brk
sbrk
mmap
ENOMEM
RLIMIT_CPU
brk
。如我所见,由于waitpid,要求“程序未处理信号X,Y,Z ...”将解决SIGXCPU,SIGXFSZ,SIGSEGV的问题(如果我错了,请纠正我)。
brk
。如我所见,由于waitpid,要求“程序未处理信号X,Y,Z ...”将解决SIGXCPU,SIGXFSZ,SIGSEGV的问题。我对吗?
我目前正在就同一问题进行一些工作。我已经能够部分解决它。我已经使用了审计系统。您可以在[1]上跟踪作品。
malloc
但是不幸的是,它通常不能解决内存问题,因为总的来说,它与系统调用有关brk
(我对吗?)。