fish
내 셸에서 (특히) 백그라운드 프로세스에 신호를 보내는 문제를 디버깅하려고 합니다. 프로세스가 어떤 신호를 받고 있는지 식별할 수 있기를 원합니다.
이상적으로는 다음을 수행하는 프로그램을 원합니다.
$ log_signals > signals.txt &
그런 다음 수신된 신호가 출력에 기록됩니다. 하지만 아직 그런 프로그램은 없는 것 같아요.
가급적이면 자체 프로그램을 작성하지 않고도 들어오는 신호를 포착하고 검사하는 가장 간단한 방법은 무엇입니까?
(저는 Linux가 아닌 OS X를 실행하고 있으므로 가능하다면 플랫폼 독립적인 답변을 선호합니다.)
답변1
~부터스티븐이 정보를 다음과 같이 게시하세요.논평, 하지만 이 정보가 기존 답변보다 더 유용하다고 생각하여 댓글을 답변으로 다시 게시하고 있습니다.
Linux에만 해당: strace
신호는 기본적으로 인쇄되므로 이 -e
플래그를 사용하여 신호가 더 명확해지도록 모든 시스템 호출을 무음으로 설정할 수 있습니다.
strace -e 'trace=!all' cmd
내 경우에는 어떤 프로세스가 실행 중인 데몬을 종료하는지 알아내려고 했고, 결과는 다음과 같았습니다.
[hendrenj@underling02 ~]$ strace -p 171869 -e 'trace=!all'
Process 171869 attached
--- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=151513, si_uid=1000} ---
+++ killed by SIGTERM +++
여기에서 내가 PID 171869에 연결했고 해당 프로세스가 PID 151513의 프로세스에 의해 SIGTERM으로 전송되었음을 알 수 있습니다.
자세한 내용은 다음을 확인하세요.이 블로그 게시물auditd
, (SELinux를 사용하는 배포판을 사용하는 경우 SELinux와 함께 제공되는 도구를 믿습니다) 또는 ( 충분히 강력하지 않은 경우) stap
(System Tap) 과 같은 것을 사용하는 것이 좋습니다 .strace
답변2
trap
일부 종속성을 갖는 대신 명령을 직접 연결하여 신호를 감지할 수 있다는 것을 깨달았습니다 . 아래 스크립트는 신호에 일부 "트랩"을 설정한 다음(관련 신호가 들어올 때 함수 실행) 신호를 종료 코드로 출력합니다. 원하는 경우 종료를 콘솔 출력으로 변경할 수 있습니다.
#!/bin/sh
trap cleanup_1 1 # SIGHUP
trap cleanup_2 2 # SIGINT
trap cleanup_3 3 # SIGQUIT
trap cleanup_6 6 # SIGABRT
trap cleanup_15 15 # SIGTERM
cleanup_1()
{
exit 1
}
cleanup_2()
{
exit 2
}
cleanup_3()
{
exit 3
}
cleanup_6()
{
exit 6
}
cleanup_15()
{
exit 15
}
echo "Started"
cat
답변3
gdb
이를 수행하려면 다음 방법을 사용할 수 있습니다 .
gdb --batch -ex 'handle all print' -ex 'handle all nostop' -ex 'handle all pass' -ex 'run' cat
GDB에서 cat을 실행하고 모든 신호를 인쇄하여 실행을 중지하지 않고 프로그램에 전달합니다.
백그라운드 프로그램으로 이것을 하는 것은 GDB가 백그라운드로 들어가려고 하기 때문에 어렵습니다. 디버거를 시작한 cat &
다음 다음을 사용하여 디버거를 다른 창에 연결하는 것이 더 나을 것입니다 gdb -ex 'handle all print' -ex 'handle all nostop' -ex 'handle all pass' -ex 'c' (pgrep cat)[1]
. q[ENTER]
모든 쓰레기를 처리하려면 세 번 누르십시오 . 그런 다음 cat
실행을 볼 수 있습니다.
답변4
strace -o logfile -e signal=all cmdline