확인 방법, 어느 한도를 초과 했습니까? (ulimit로 인해 프로세스가 종료되었습니다.) 종료되었습니다. 여러 가지 이유가있을 수 있습니다. 메모리 /

프로세스가 ulimited 환경에서 실행된다고 가정 해 봅시다.

(
ulimit  ... -v ... -t ... -x 0 ...
./program
)

프로그램이 종료되었습니다.

여러 가지 이유가있을 수 있습니다. 메모리 / 시간 / 파일 제한이 초과되었습니다. 그냥 간단한 segfault; 또는 리턴 코드가 0 인 정상적인 종료.

프로그램을 수정하지 않고 프로그램 종료 이유를 확인하는 방법은 무엇입니까?

추신 : 나는 “이진이 주어질 때”를 의미합니다. 어쩌면 일부 래퍼 (ptrace-ing 등)가 도움이 될 수 있습니까?



답변

일반적으로, 불행히도 당신이 할 수 있다고 생각하지 않습니다. (일부 운영 체제가 제공 할 수도 있지만이를 지원하는 운영 체제는 알 수 없습니다.)

자원 제한에 대한 참조 문서 : getrlimitPOSIX 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리눅스 스택을 확장하려고 노력하는 동안 AS 제한이 충돌되는 경우). 프로그램이 잘 작성되지 않으면, 그 시점에서 아마도 무작위로 실패 할 것입니다.

간단히 말해서 일반적으로 실패는 다른 프로세스 사망 원인과 눈에 띄게 다르지 않으므로 확실하지 않거나 프로그램이 아닌 경우 / 진행 / 진행 방법을 결정하는 프로그램에서 완전히 처리 할 수 ​​있습니다. 외부에서.

내가 아는 한 최선을 다하는 것은 프로그램의 포크를 작성하고 기다리는 코드를 작성하는 것입니다.

  • 종료 상태를 감지하여 감지 SIGXCPU하고 SIGXFSZ(AFAIK, 해당 신호는 OS에서 리소스 제한 문제에 대해서만 생성합니다). 당신의 정확한 필요에 따라, 당신은 가정 수 SIGKILLSIGSEGV도 자원 제한 관련이 있었다, 그러나 그것은 약간의 신축성입니다.
  • getrusage(RUSAGE_CHILDREN,...)다른 구현에 대한 힌트를 얻기 위해 구현에서 얻을 수있는 것을 살펴보십시오 .

여기에 도움이되는 OS 별 기능 ( ptraceLinux 또는 Solaris 와 같은 것 dtrace) 또는 디버거 유형 기술이있을 수 있지만 이는 특정 구현과 더 관련이 있습니다.


(나는 다른 사람이 내가 완전히 알지 못하는 마술로 대답하기를 바라고 있습니다.)


답변

나는 현재 같은 문제에 대해 몇 가지 작업을하고 있습니다. 나는 그것에 대한 부분적인 해결책을 가질 수있었습니다. 감사 susbsystem 을 사용 했습니다. [1]에서 작업을 추적 할 수 있습니다.

[1] https://github.com/PaulDaviesC/Logging-limits.conf


답변