확인 방법, 어느 한도를 초과 했습니까? (ulimit로 인해 프로세스가 종료되었습니다.)


11

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

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

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

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

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

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

답변:


6

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

자원 제한에 대한 참조 문서 : 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) 또는 디버거 유형 기술이있을 수 있지만 이는 특정 구현과 더 관련이 있습니다.


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


확인. (Mem) 메모리 한도 초과, (Time) 시간 제한, (Err) 기타 오류? 나는 래퍼를 만드는 것에 대해 알고 malloc있지만 불행히도 일반적으로 메모리 문제를 해결하지 못합니다. 일반적으로 시스템 호출에 관한 brk것입니다 (맞습니까?).
Grzegorz Wierzowiecki

1
프로그램을 제어하지 않으면 malloc을 래핑해도 도움이되지 않습니다. 당신은 같은 해킹에 대해 얘기하는 경우 LD_PRELOAD귀하의 "과정을 수정하지"제약 조건이의 경계선을 보내고, 그것은 조금 도움이되지만 정말 것이다 - malloc, brk, sbrkmmap함께 실패합니다 ENOMEM당신이 정말로 메모리 부족 상황에 있었다 정확히 것처럼, (하지만 메모리 한계보다 훨씬 낮습니다). 시간 제한은 RLIMIT_CPU입니다. 벽시계 시간 제한을 모릅니다.
Mat

에 대해 알려 주셔서 감사합니다 brk. 보시다시피, 요구 사항 '프로그램이 X, Y, Z 신호를 처리하지 않습니다 ...'는 waitpid 덕분에 SIGXCPU, SIGXFSZ, SIGSEGV의 문제를 해결할 것입니다 (잘못된 경우 수정하십시오).
Grzegorz Wierzowiecki

1
SIGSEGV는 리소스 제한 위반이 아닌 상황에서 발생할 수 있습니다 (널 포인터 역 참조가 가장 일반적인 원인 임). ulimit 히트가 원인 일 수 있습니다.
Mat

에 대해 알려 주셔서 감사합니다 brk. 내가 본 것처럼 '프로그램이 X, Y, Z 신호를 처리하지 않습니다 ...'라는 요구 사항은 waitpid 덕분에 SIGXCPU, SIGXFSZ, SIGSEGV의 문제를 해결할 것입니다. 내가 맞아?
Grzegorz Wierzowiecki

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.