초과된 한도를 확인하는 방법은 무엇입니까? (ulimit로 인해 프로세스가 종료되었습니다.)

초과된 한도를 확인하는 방법은 무엇입니까? (ulimit로 인해 프로세스가 종료되었습니다.)

프로세스가 무제한 환경에서 실행되고 있다고 가정해 보겠습니다.

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

프로그램이 종료됩니다.

이유는 다양할 수 있습니다. 단순한 세그먼트 오류로 인해 메모리/시간/파일 제한이 초과되었거나 반환 코드 0으로 정상적으로 종료되는 경우도 있습니다.

프로그램을 수정하지 않고 프로그램이 종료된 이유를 어떻게 확인할 수 있나요?

PS 나는 "바이너리가 주어졌을 때"를 의미했습니다. 어쩌면 일부 래퍼(ptrace-ing 등)가 도움이 될 수 있을까요?

답변1

일반적으로 불행하게도 나는 당신이 할 수 없다고 생각합니다. (일부 운영 체제에서는 이 기능을 제공할 수 있지만 어느 운영 체제에서 지원하는지 모르겠습니다.)

리소스 제한 참조 문서: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_ASRLIMIT_DATAmake만 하고 malloc()다른 일부는 실패하기 시작합니다(또는 SIGSEGVLinux에서 스택을 확장하려고 할 때 AS 제한에 도달하면 수신합니다). 프로그램이 잘 작성되지 않으면 무작위로 실패할 수 있습니다.

간단히 말해서, 일반적으로 실패는 프로세스 종료의 다른 이유와 크게 다르지 않으므로 확신할 수 없거나 프로그램에서 완전히 처리할 수 있습니다. 이 경우 진행 여부/언제/방법을 결정합니다. 반면 당신은 외부에서 온 것이 아닙니다.

내가 아는 한, 당신이 할 수 있는 최선은 프로그램을 분기하고 기다린 다음 다음과 같은 코드를 작성하는 것입니다.

  • 감지할 종료 상태를 확인합니다 SIGXCPU( SIGXFSZAFAIK, 이러한 신호는 리소스 제한 문제에 대해 운영 체제에서만 생성됩니다). 특정 요구 사항에 따라 리소스 제약과 관련이 있다고 가정할 수도 있지만 SIGKILL이는 SIGSEGV다소 무리한 일입니다.
  • getrusage(RUSAGE_CHILDREN,...)다른 구현에 대한 팁을 얻으려면 구현에서 무엇을 얻을 수 있는지 확인하세요 .

ptrace여기서는 OS별 도구( Linux 또는 Solaris의 도구 )나 디버거 유형의 기술이 도움이 될 수 있지만 dtrace이는 특정 구현과 더 관련이 있습니다.


(나는 내가 전혀 모르는 마법 같은 질문에 다른 누군가가 대답해 줄 수 있기를 바랍니다.)

답변2

나는 현재 같은 문제에 대해 몇 가지 작업을 수행 중입니다. 부분적으로 해결이 되었습니다. 나는 사용했다심사하위 시스템. [1]에서 작업을 추적할 수 있습니다.

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

관련 정보