'kill -9'가 작동하지 않으면 어떻게합니까?


467

내가 죽일 수없는 프로세스가 있습니다 kill -9 <pid>. 특히 내가 그 프로세스의 소유자이기 때문에 그러한 경우의 문제는 무엇입니까? 나는 그 kill옵션을 피할 수 없다고 생각했다 .

답변:


561

kill -9( SIGKILL )은 프로세스를 종료 할 권한이있는 경우 항상 작동합니다. 기본적으로 프로세스는 setuid 또는 setgid가 아니어야 시작하거나 루트 여야합니다. 한 가지 예외가 있습니다. root조차도 치명적인 신호를 PID 1 ( init프로세스)로 보낼 수 없습니다 .

그러나 즉시kill -9 작동하지는 않습니다 . SIGKILL을 포함한 모든 신호는 비동기 적으로 전달됩니다. 커널이 신호를 전달하는 데 시간이 걸릴 수 있습니다. 일반적으로 신호를 전달하는 데 최대 몇 마이크로 초가 걸리며, 대상이 시간 조각을 얻는 데 걸리는 시간입니다. 그러나 대상이 신호차단 한 경우 대상이 차단을 해제 할 때까지 신호가 대기됩니다.

일반적으로 프로세스는 SIGKILL을 차단할 수 없습니다. 그러나 커널 코드는 시스템 호출 을 호출 할 때 커널 코드를 실행할 수 있고 프로세스는 커널 코드를 실행할 수 있습니다 . 커널 호출은 시스템 호출을 방해 할 때 모든 신호를 차단하여 커널 어딘가에 데이터 구조가 잘못 형성되거나 더 일반적으로 일부 커널 불변이 위반 될 수 있습니다. 따라서 (버그 또는 잘못된 설계로 인해) 시스템 호출이 무기한으로 차단되면 프로세스를 종료시킬 수있는 방법이 사실상 없을 수 있습니다. 그러나 시스템 호출이 완료되면 프로세스 가 종료됩니다 .

시스템 호출에서 차단 된 프로세스는 무정전 절전 상태 입니다. ps또는 top명령 (대부분의 유닉스에) 상태로 표시됩니다 D(원래 "에 대한 개발 ISK"나는 생각한다).

중단없는 긴 절전 모드의 전형적인 경우 는 서버가 응답하지 않을 때 NFS를 통해 파일에 액세스하는 프로세스입니다 . 현대적인 구현에서는 중단없는 절전 모드를 적용하지 않는 경향이 있습니다 (예 : Linux의 경우 intrmount 옵션을 사용하면 신호가 NFS 파일 액세스를 방해 할 수 있음).

때때로 또는 출력에 표시된 항목 Z(또는 HLinux에서는 구별이 무엇인지 모르겠습니다)이 표시 될 수 있습니다 . 이들은 기술적으로 프로세스가 아니며 좀비 프로세스이며 프로세스 테이블의 항목에 불과하므로 부모 프로세스가 자식의 죽음을 알 수 있습니다. 부모 프로세스 가주의를 기울 이거나 죽으면 사라집니다 .pstop


92
답장 자체가 모순되는 것 같습니다. SIGKILL이 항상 작동한다고 말하기 시작하지만 중단 할 수없는 수면을 인용하면 SIGKILL은 커널을 종료 한 후에는 작동하지 않을 수 있습니다. SIGKILL이 작동하지 않는 두 가지 경우도 있습니다. 좀비를 사용하면 이미 죽은 프로세스를 죽일 수 없으며 초기화로 SIGKILL 신호를 무시하는 init을 사용할 수 있습니다.
jlliagre

41
@jlliagre : 좀비를 죽이는 것은 말이되지 않습니다. 그리고 인터럽트 잠에서 프로세스를 죽이는 수행 은 비동기 (다른 신호와 같은) 단지, 일을. 편집에서 이것을 명확히하려고했습니다.
Gilles

3
나는 좀비를 죽이는 것이 의미가 없지만 많은 사람들이 그것을 시도하고 불평하는 것을 막지는 않습니다. 인터럽트 가능한 수면 상태에서 프로세스를 종료하는 것은 실제로 의도적으로 작동하지만, 시스템 호출이 절대로 일어나지 않으면 실패 할 수있는 무정전 수면 상태에서 프로세스를 종료하는 것에 대해 이야기했습니다.
jlliagre

11
man 5 nfs: " intr/ nointrmount 옵션은 커널 2.6.25 이후에는 더 이상 사용되지 않습니다. SIGKILL 만이 커널에서 보류중인 NFS 작업을 중단 할 수 있으며, 지정된 경우이 마운트 옵션은 무시되어 이전 커널과의 하위 호환성을 제공합니다."
Martin Schröder

4
@ imz--IvanZakharyaschev 내가 아는 바는 없지만 알 수는 없습니다. 최후의 수단으로 sshfs를 사용하면 sshfs프로세스를 강제 종료 할 수 있습니다 (다른 FUSE 파일 시스템과 마찬가지로 강제로 마운트 해제 할 수 있음).
Gilles

100

때때로 프로세스가 존재하며 다음으로 인해 종료 될 수 없습니다.

  • 좀비 인 것. 즉, 어떤 부모가 종료 상태를 읽지 않은 프로세스입니다. 이러한 프로세스는 PID 입력 이외의 리소스를 사용하지 않습니다. 에 top그것은 Z 신호입니다
  • 잘못된 무정전 수면. 버그 커널 코드 및 / 또는 버그 하드웨어가 결합되어 발생해서는 안됩니다. 유일한 방법은 재부팅하거나 기다리는 것입니다. 에서 top그것은 D.에 의해 신호입니다

2
좀비는 자원을 소비하지 않습니까?
Luc M

7
@Luc M : AFAIK 아니오 (적어도 Linux에서는)-프로세스 테이블의 항목 (예 : 소유자, 종료 상태 등과 같은 PID와 함께)을 제외하고. 그것은 종료 된 부분으로부터 승인을 기다리는 프로세스 일뿐입니다.
Maciej Piechotka

18
@xenoterracide : 결국 그렇습니다. 그러나 부모 프로세스가 여전히 존재한다면 (예를 들어 그놈 세션이거나 비슷한 역할을하는 것) 좀비가있을 수 있습니다. 기술적으로 정리하는 것은 부모의 일이지만 좀비가 고아 인 경우 청소가 끝난 후에 청소합니다 (용어는 유닉스 수업이 닫힌 문으로 수행되는 이유입니다-고아, 좀비에 대해 듣고 한 문장으로 살인하는 사람에게는 잘못된 인상을 줄 수 있습니다).
Maciej Piechotka

5
"... 유일한 방법은 재부팅하거나 기다리는 것입니다."얼마나 오래 기다려? 5 개월이 지났는데 내 좀비가 아직 남아 있습니다.
DarenW

3
부모가 자녀의 죽음을 인정할 때까지 @DarenW. 자세한 내용은 프로그램 작성자에게 문의하십시오.
Maciej Piechotka

32

좀비 프로세스 가있는 것 같습니다 . 이것은 해롭지 않습니다. 좀비 프로세스가 소비하는 유일한 리소스는 프로세스 테이블의 항목입니다. 부모 프로세스가 죽거나 아이의 죽음에 반응하면 사라집니다.

top또는 다음 명령 을 사용하여 프로세스가 좀비인지 확인할 수 있습니다 .

ps aux | awk '$8=="Z" {print $2}'

13
음, 나는 항상 이런 종류의 "하드"필드 이름을 싫어합니다 ps. 모든 Unices에서 모든 구현 을 통해 필수 필드가 항상 8 일 것이라고 누가 확신 할 수 ps있습니까?
syntaxerror

26

단서가 있는지 /var/log/kern.log/var/log/dmesg/ 또는 동등한 것을 확인하십시오 . 내 경험상 이것은 NFS 마운트의 네트워크 연결이 갑자기 끊어 지거나 장치 드라이버가 충돌했을 때만 발생했습니다. 하드 드라이브가 충돌하면 발생할 수 있다고 생각합니다.

lsof프로세스가 어떤 장치 파일을 열 었는지 확인할 수 있습니다 .


6
NFS에 대해서는 +1입니다. 몇 년 전, 두 달마다 이런 일이 일어났습니다. NFS 서버가 충돌하면 모든 패치 된 RHEL 박스의 NFS 클라이언트가 중단됩니다. kill -9보통 60 분을 기다린 후에도 작동하지 않았습니다. 유일한 해결책은 재부팅이었습니다.
Stefan Lasiewski

17

@ Maciej 와 @ Gilles 의 답변으로 문제가 해결되지 않고 프로세스를 인식하지 못하면 (그리고 배포판에 무엇이 있는지 묻는 것이 답변을 얻지 못합니다). 루트킷 및 소유 한 다른 징후를 확인하십시오 . 루트킷은 프로세스를 종료시키지 못하게 할 수 있습니다. 실제로 많은 사람들이 당신이 그들을 보지 못하게 할 수 있습니다. 그러나 1 개의 작은 프로그램을 수정하는 것을 잊어 버린 경우 발견 될 수 있습니다 (예 : 수정 top되었지만 수정 되지 않음 htop). 아마도 이것은 사실이 아니지만 미안보다 안전합니다.


많은 루트킷이 커널에 자신을 삽입하여 더 간단하게 만듭니다 (사용자가 가지고있는 것을 추측하고 MB의 패치 된 프로그램을 다운로드 할 필요가 없습니다). 그러나 여전히 검사 할 가치가 있습니다 (++ 투표).
Maciej Piechotka

11

킬은 실제로 신호를 보내는 것을 의미합니다. 보낼 수있는 여러 신호가 있습니다. kill -9는 특별한 신호입니다.

신호를 보낼 때 응용 프로그램이 신호를 처리합니다. 그렇지 않으면 커널이 처리합니다. 애플리케이션에 신호를 포착 할 수 있습니다.

그러나 나는 살인 9가 특별하다고 말했다. 응용 프로그램이 얻지 못한다는 점에서 특별합니다. 커널로 직접 이동하여 가능한 첫 번째 기회에서 응용 프로그램을 실제로 종료합니다. 다른 말로하면 죽었다

kill -15는 SIGNAL TERMINATE를 나타내는 SIGTERM 신호를 전송합니다. 즉, 응용 프로그램이 종료되도록 지시합니다. 이것은 응용 프로그램에 종료 시간을 알려주는 친숙한 방법입니다. 그러나 응용 프로그램이 응답하지 않으면 kill -9가 종료합니다.

kill -9가 작동하지 않으면 아마도 커널에 문제가 있음을 의미합니다. 재부팅이 순서대로 이루어집니다. 나는 그 일이 일어났다는 것을 기억할 수 없다.


5
15는 SIGHUP이 아니라 SIGTERM (친절한 킬)입니다. SIGHUP은 제어 터미널이 닫히거나 통신 채널이 손실되는 경우입니다.
JoelFan

11

먼저 좀비 프로세스가 있는지 확인하십시오 (매우 가능합니다).

ps -Al

다음과 같은 것을 보게 될 것입니다 :

0 Z  1000 24589     1  0  80   0 -     0 exit   ?        00:00:00 soffice.bin <defunct>

(왼쪽의 "Z"참고)

5 번째 열이 1이 아니면 상위 프로세스가 있음을 의미합니다. 해당 부모 프로세스 id를 강제 종료하십시오 .

만약 PPID가 1이라면, 그것을 죽이지 마라 !! 다른 기기 나 프로세스와 관련이있을 수 있습니다.

예를 들어, 마운트 된 장치 또는 Samba를 사용중인 경우 마운트 해제하십시오. 좀비 프로세스가 해제 될 수 있습니다.

참고 : ps -Al(또는 top)에 "Z"대신 "D"가 표시되면 원격 마운트 (NFS와 같은)와 관련이있을 수 있습니다. 내 경험에 따르면 재부팅하는 것이 유일한 방법이지만 해당 사례를 자세히 다루는 다른 답변을 확인할 수 있습니다.


1
부모 프로세스에 SIGCHLD를 보내면 부모가 프로세스가 종료되었음을 인식하게 할 수 있습니다. 이것은 PPID = 1 일 때도 작동해야합니다. 이것은 일반적으로 커널에 의해 전송되지만 kill을 통해서도 부모와 함께 전송 될 수 있습니다 (Linux에서는 kill -17, 다른 * nix의 맨 페이지 확인). 이러한 살인 사용은 실제로 부모를 "살해"하는 것이 아니라 오히려 아이가 사망하여 청소해야 함을 알려줍니다. sigchld는 좀비 자체가 아니라 좀비의 부모에게 보내 져야합니다.
Stephanie

10

초기화 과정은 SIGKILL에 면역입니다.

이것은 커널 스레드, 즉 PPID가 0 인 "프로세스"에도 적용됩니다.


1
커널 작업은 SIGKILL에 영향을 줄 수 있습니다. 이것은 종종 Btrfs에서 충분합니다.
Tobu

9

다른 사람들이 언급했듯이, 무정전 수면 과정은 즉시 (또는 경우에 따라) 죽일 수 없습니다. 특정 프로세스, 특히 프로세스가 NFS를 기다리는 일반적인 경우에이 문제를 해결하기 위해 TASK_KILLABLE이라는 다른 프로세스 상태가 추가되었다는 점은 주목할 가치가 있습니다. http://lwn.net/Articles/288056/을 참조 하십시오

불행히도 이것이 커널의 어느 곳에서나 NFS가 아니라고 생각합니다.


원격 서버에 연결할 수 없을 때 마운트에 ls액세스 하는 프로세스를 종료 하는 데 문제가있었습니다 sshfs. 이러한 상황을 피하기 위해 나중에 사용할 수있는 FUSE 또는 sshfs에 대한 솔루션이 있습니까? 2.6.30 커널
imz-Ivan Zakharyaschev

@imz sshfs를 죽이는 Gilles의 조언은 unix.stackexchange.com/a/5648/4319 입니다.
imz-Ivan Zakharyaschev

6

좀 더 살펴볼 수 있도록 작은 스크립트를 만들었습니다!

이것을 사용하여 경로에 주어진 이름을 가진 프로세스를 죽일 수 있습니다 (주의하십시오!) 또는 "-u username"매개 변수를 사용하여 주어진 사용자의 프로세스를 죽일 수 있습니다.

#!/bin/bash

if [ "$1" == "-u" ] ; then\n
        PID=`grep "$2" /etc/passwd | cut -d ":" -f3`
        processes=`ps aux | grep "$PID" | egrep -v "PID|ps \-au|killbyname|grep" | awk '{ print $2}'`
        echo "############# Killing all processes of user: $2 ############################"
else
        echo "############# Killing processes by name: $1 ############################"
        processes=`ps aux | grep "$1" | egrep -v "killbyname|grep" | awk '{ print $2}' `
fi


for process in $processes ; do
        # "command" stores the entire commandline of the process that will be killed
        #it may be useful to show it but in some cases it is counter-productive
        #command=`ps aux | grep $process | egrep -v "grep" | awk '{ print $2 }'`
        echo "Killing process: $process"
        echo ""
        kill -9 $process
done

4
연결하는 대신 여기에 코드를 게시 할 수 있습니다.
tshepang

3
코드에 대한 약간의 설명을 추가하십시오 (또는 적어도 대신).
vonbrand

그래도 "$ name"은 더 집계되고 있습니다. 실행 경로에 "$ name"이있는 모든 프로세스가 종료됩니다. 이 거대한 명령 줄이 있고 프로세스 이름이 무엇인지 모르는 경우 매우 유용 할 수 있습니다.
user36035

5

프로세스에 kill -9를 보내더라도 pid는 중지되지만 프로세스는 자동으로 다시 시작됩니다 (예 :로 시도 gnome-panel하면 다시 시작됨). 여기에 해당 될 수 있습니까?


8
이와 같은 일이 발생하면 PID가 실제로 변경됩니다. 그래서 나는 알아 차렸을 것이다.
tshepang

2

원래 부터 :

strace에 아무것도 표시되지 않는지 확인

strace -p <PID>

gdb로 프로세스에 연결해보십시오

gdb <path to binary> <PID>

프로세스가 마운트 해제 할 수있는 장치와 상호 작용하는 경우 커널 모듈을 제거하거나 물리적으로 분리 / 분리하십시오 ... 그런 다음 시도하십시오.


나를 위해 일했다! (숭고한 텍스트를 걸고 있던 USB 장치를 분리)
nmz787

1

나는 이런 종류의 문제가 있었다. 이것은 내가 시작 strace하고 Ctrl+로 중단 한 프로그램이었습니다 C. 결국 T(추적 또는 중지) 상태가되었습니다. 나는 그것이 어떻게 일어 났는지 모르겠지만,로 살해 할 수 없었습니다 SIGKILL.

간단히 말해, 나는 그것을 죽이는 데 성공했습니다 gdb:

gdb -p <PID>
> kill
Kill the program being debugged? (y or n) y
> quit

-1

gilles의 대답에 대한 단서를 기반으로 <defunct>시스템 리소스를 사용하는 상단에 "Z"라고 표시된 프로세스 가 있고, 청취 중이었던 포트가 열려있어 해당 포트에 연결할 수 있습니다. 이것은에 대한 실행 후였습니다 kill -9. 그것의 부모는 "1"(즉 init)이므로 이론적으로 그냥 반복해서 사라져야합니다. 그러나 그렇지는 않았지만 달리지 않고 "죽지 않았다"

제 경우에는 좀비이지만 여전히 리소스를 소비합니다 ... FWIW.

그리고 그것은 임의의 수에 의해 killable하지 않았다 kill -9'의

그리고 부모는 init있었지만 거두지 않았습니다. 즉 init, 좀비 아이가있었습니다.

그리고 문제를 해결하기 위해 재부팅 할 필요가 없었습니다. 재부팅으로 문제가 해결되었지만 더 빨리 종료되었습니다. 우아하지는 않았지만 여전히 가능했습니다.

그리고 좀비 프로세스가 소유 한 LISTEN 포트였습니다 (로컬 호스트에 로컬 호스트에 연결된 CLOSE_WAIT 상태와 같은 다른 포트도 있습니다). 그리고 그것은 여전히 ​​연결을 받아 들였습니다. 좀비로도. 포트를 정리하지는 않았지만 들어오는 연결은 여전히 ​​TCP 수신 포트의 백 로그에 추가되었지만 허용 될 가능성은 없었습니다.

위의 많은 것들이 웹의 여러 곳에서 "불가능"하다고 언급되어 있습니다.

내부에 스레드가있어 "시스템 호출"(이 인스턴스에서는 ioctl)을 실행하는 데 몇 시간이 걸렸습니다 (예상 동작이었습니다). 분명히 시스템은 ioctl호출 에서 돌아올 때까지 프로세스를 "종료"종료 할 수 없습니다 . 커널 랜드로 들어가는 것 같습니다. 몇 시간이 지난 후, 물건이 치워지고 소켓이 예상대로 모두 자동으로 닫혔습니다. 그것은 죽음의 행에 약간의 고통스러운 시간입니다! 커널은 참을성있게 죽이기를 기다리고있었습니다.

따라서 OP에 응답하려면 때로는 기다려야합니다. 오랜만이야 그러면 죽일 것이다.

또한 dmesg를 검사하여 커널 패닉 (예 : 커널 버그)이 있는지 확인하십시오.


이것은 당신이 질문에 대한 대답보다는 자신의 특정 시나리오를 설명하는 것으로 보입니다. 귀하의 경우 프로세스가 오래 실행되어 문제 자체에서 언급되지 않았기 때문에 자체적으로 프로세스가 수정되었습니다. 그러나 새로운 질문을 제기하고 이에 대한 답변을 제공 할 수 있습니다. 그 결과는 구현에 따라 다르기 때문에 그 질문이 "재연 불가능"으로 종결 될까 걱정됩니다.
Centimane

사실, 어떤 경우에는 가능하기 때문에 OP에 어떻게 대답하는지 추가했습니다.
rogerdpack
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.