日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

linux信号以及core

發(fā)布時間:2024/2/28 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux信号以及core 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

linux信號以及core

何為信號

信號(signal)用于通知進程發(fā)生了某種情況。進程有以下3種處理信號的方式:

  • 忽略信號。有些信號表示硬件異常,例如,除以0或訪問進程地址空間以外的存儲單元等,因為這些異常產(chǎn)生的后果不確定,所以不推薦使用這種處理>方式。
  • 按系統(tǒng)默認方式處理。對除數(shù)為0,系統(tǒng)默認方式是終止進程。
  • 提供一個函數(shù),信號發(fā)生時調(diào)用該函數(shù),這被稱為捕抓該信號。通過提供自編的函數(shù),我們就能知道什么時候產(chǎn)生了信號,并按期望的方式處理它。
  • 以上摘自《APUE》中文版14頁

    信號類型

    [root@test ~]# kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX

    每個信號有其默認的處理方式,參考manpage,分為以下幾種類型

    Term Default action is to terminate the process.

    Ign Default action is to ignore the signal.

    Core Default action is to terminate the process and dump core (see
    core(5)).

    Stop Default action is to stop the process.

    Cont Default action is to continue the process if it is currently
    stopped.

    例如我們常用的kill的默認信號SIGTERM(15),以及強制結(jié)束信號SIGKILL(9),其對應(yīng)的處理方式都是Term,我們經(jīng)常使用SIGABRT(6)對應(yīng)處理方式是Core,可以用來產(chǎn)生core-dump文件

    core文件詳解

    core文件是ELF-formatted文件,可以使用readelf查看core的elf信息。它包含了程序運行時的內(nèi)存,寄存器狀態(tài),堆棧指針,內(nèi)存管理信息等

    配置coredump

    • 開啟coredump
    # 開啟coredump ulimit -c unlimited # 持久化方式 echo "ulimit -c unlimited" >> /etc/profile
    • 設(shè)置coredump的命名規(guī)則
    # 在/etc/sysctl.conf文件中加入 # 例如下面這個命令,可以通過在%e前面增加/home/之類的路徑使其保存到特定路徑 kernel.core_pattern=%e.core.%s_%t 并保存退出,執(zhí)行下面指令使其生效 sysctl -p# 參數(shù)含義%% output one '%'%p pid%u uid%g gid%s signal number%t UNIX time of dump%h hostname%e executable filename# 默認是這樣的 |/usr/share/apport/apport %p %s %c %PIf the first character of the pattern is a '|', the kernel will treatthe rest of the pattern as a command to run. The core dump will bewritten to the standard input of that program instead of to a file.
    • 通過cat /proc/sys/kernel/core_pattern 驗證設(shè)置的pattern
    • 每個進程也可以通過setrlimit的RLIMIT_CORE配置進程級別的core大小

    控制coredump的mapping

    /proc/[pid]/coredump_filter可以指定怎樣的進程空間內(nèi)存可以保存到core文件里,它是由下面的bitmask組成

    • (bit 0) anonymous private memory(匿名私有內(nèi)存段,例如:動態(tài)變了)
    • (bit 1) anonymous shared memory(匿名共享內(nèi)存段)
    • (bit 2) file-backed private memory(file-backed 私有內(nèi)存段)
    • (bit 3) file-backed shared memory(file-bakced 共享內(nèi)存段,例如:動態(tài)鏈接庫)
    • (bit 4) ELF header pages in file-backed private memory areas (it is effective only if the bit 2 is cleared)(ELF 文件映射,只有在bit 2 復(fù)位的時候才起作用)
    • (bit 5) hugetlb private memory(大頁私有內(nèi)存)
    • (bit 6) hugetlb shared memory(大頁共享內(nèi)存)
    • bit 7 (since Linux 4.4) Dump private DAX pages.
    • bit 8 (since Linux 4.4) Dump shared DAX pages.

    默認配置是0x33,也就是說bits 0 (anonymous private mappings), 1 (anonymous shared mappings), 4 (ELF headers) and 5 (private huge pages) 都會被dump出。如果想改變bitmask,可以使用如下方法:

    echo 0x00000001 > /proc/[pid]/coredump_filter

    也可以配置在當前shell生效的coredump_filter

    # 如果沒有下面的文件,請檢查內(nèi)核參數(shù)CONFIG_ELF_CORE是否配置 $ echo 0x7 > /proc/self/coredump_filter $ ./some_program

    注意:

  • 如果你想設(shè)置全局的coredump_filter,可以參考這篇文章
  • MMIO的頁永遠不會被dump出來
  • 產(chǎn)生core-dump的方法

  • 發(fā)信號SIGABRT,會終止進程
  • gcore,gcore會調(diào)用gdb產(chǎn)生coredump,不會終止進程,但是產(chǎn)生core的時候進程會處于stopped狀態(tài)
  • 設(shè)置信號處理函數(shù),信號處理函數(shù)fork()后abort()
  • google-coredumper上述的方法1終止進程,方法2會暫停進程,所以谷歌就做了個coredump庫,支持在運行時coredump
  • gcore

    • gcore實際上就是gdb里面的一個命令,它的作用是把進程的memory全部dump出來,和系統(tǒng)調(diào)用abort()等方法的實現(xiàn)方式是不同的。最直觀的感受是gcore會把進程全部的VIRT內(nèi)存dump出來。產(chǎn)生的core文件有可能會很大,并且它的大小不受ulimit -c限制。
    • 使用gcore dump出的core文件,在gdb中使用info files查看每段內(nèi)存的大小,比使用abort()dump出的要大的多,原因應(yīng)該是gcore把沒有用到的虛擬內(nèi)存也dump出來了
    • gcore執(zhí)行過程中程序處于stopped狀態(tài)
    • 命令行中的gore命令其實是RedHat linux制作的一個shell script用來調(diào)用gdb,所以如果你調(diào)用了命令行g(shù)core [pid],它實際上會執(zhí)行如下的gdb命令,如下,以進程40923為例:
    gdb --nx --batch -ex set pagination off -ex set height 0 -ex set width 0 -ex attach 40923 -ex gcore core.40923 -ex detach -ex quit

    所以,如果你沒有g(shù)core命令,也可以使用如下命令產(chǎn)生gcore

    gdb --pid=40923 --batch -ex gcore

    signal 函數(shù)

  • 信號處理函數(shù)signal 規(guī)定了在某種信號signo情況下調(diào)用func處理
  • 正在處理的時候,其他信號是不能遞交的,必須等當前信號處理完畢,其他信號才能遞交
  • #include <signal.h> typedef void Sigfunc(int); Sigfunc *signal(int signo, Sigfunc *func)

    SIGCHLD

  • 子進程終止時,會給父進程發(fā)一個SIGCHLD信號(其實這個信號是由內(nèi)核在進城終止時發(fā)給父進程的(《UNIX網(wǎng)絡(luò)編程》P103)),如果父進程不處理的話,子進程機會變成僵尸進程
  • 父進程只需要在信號處理函數(shù)里面調(diào)用wait即可。
  • 如果不想子進程產(chǎn)生僵尸進程,可以設(shè)置SIG_IGN signal(SIGCHLD, SIG_IGN);
  • signal(SIGCHLD, sig_chld);void sig_chld(int signo) {pid_t pid;int stat;pid = wait(&stat);printf("child %d terminated\n", pid);return; }

    僵尸進程的危害

    所謂僵尸進程,形象來說,進程已死,但其尸體還在,沒人收尸啊,冤魂不散,仍然占用一個進程號,如果主進程不妥善處理,當僵尸進程數(shù)量巨大之后,就沒法再次fork了,所以對于大型并發(fā)服務(wù)器來說,當建立了進程池,一定要想辦法處理掉所有僵尸進程。

    SIGPIPE

    《UNP》中文版113頁

  • A與B連接, B異常終止了,這是B會終止socket連接并且給A發(fā)一個fin,
  • 這時如果A再給B發(fā)一個寫, B的套接字會回一個RST
  • 如果A再再給B發(fā)一個寫, 會引發(fā)SIGPIPE信號, 這個信號試圖終止進程A, 如果A不情愿被終止,那么必須signal捕獲該信號并處理,但是無論如何,寫操作都會fail并且errno=EPIPE
  • signal函數(shù)最簡單的方法就是把SIGPIPE置成SIG_IGN,這樣進程就會忽略SIGPIPE信號。
  • signal(SIGPIPE, SIG_IGN);

    SIGIO

    信號驅(qū)動式I/O模型, 利用信號,讓內(nèi)核在描述符就緒時發(fā)送SIGIO信號通知進程

    其他相關(guān)函數(shù)

    sigation

    • 在一些較早的系統(tǒng)上(《UNP》P105),signal設(shè)置的信號句柄只能起一次作用,信號被捕獲一次后,信號句柄就會被還原成默認值了。我們現(xiàn)在用的linux系統(tǒng)應(yīng)該沒有關(guān)系的
    • sigaction設(shè)置的信號句柄,可以一直有效,直到你再次改變它的設(shè)置。
    struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction( SIGPIPE, &sa, 0 );

    sigation的定義:

    struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags; // 一般置0, 有一些特殊的標志位會用到這個, 如SA_NOCLDSTOP等void (*sa_restorer)(void); };

    wait和waitpid函數(shù)

    wait 函數(shù)可以用來處理已終止的子進程

    #include <sys/wait.h> pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); // 成功返回進程ID, 出錯返回0或-1
  • 通過返回,返回已終止子進程的ID
  • 通過statloc指針返回子進程終止狀態(tài)
  • waitpid()

    《UNIX網(wǎng)絡(luò)編程》 P110

    通過waitpid設(shè)置WNOHANG選項,可以告知waitpid在有尚未終止的子進程在運行時不要阻塞

    參考鏈接

  • Linux信號(一):信號類型
  • What’s the easiest way to detect what signals are being sent to a process?
  • signal(7) — Linux manual page信號的不同用處
  • core(5) — Linux manual page
  • 線上內(nèi)存泄漏的正確查找姿勢
  • 總結(jié)

    以上是生活随笔為你收集整理的linux信号以及core的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。