Linux嵌入式由於諸多的限制,調試方法有限,常常出現面對Bug束手無策的情況,現在介紹一種通過信號處理對Linux嵌入式應用程序進行調試的方法。
linux中一共有32種信號,在/usr/include/bits/signum.h 頭文件中可以看到,具體如下:SIGHUP ;SIGINT ;SIGQUIT ;SIGILL ;SIGTRAP ;SIGABRT ;SIGIOT ;SIGBUS ;SIGFPE ;SIGKILL ;SIGUSR1 ;SIGSEGV ;SIGUSR2 ;SIGPIPE ;SIGALRM ;SIGTERM ;SIGSTKFLT ;SIGCLD ;SIGCHLD ;SIGCONT ;SIGSTOP ;SIGTSTP ;SIGTTIN ;SIGTTOU ;SIGURG ;SIGXCPU ;SIGXFSZ ;SIGVTALRM ;SIGPROF ;SIGWINCH ;SIGPOLL ;SIGIO ;SIGPWR ;SIGSYS ;SIGUNUSED
其中SIGUSER1信號用戶可以自己定義其處理行為,處理范例如下:
#include <stdio.h> #include <signal.h> void signal_handle(int sig_num) { if(sig_num == SIGUSR1) { printf("Capture SIGUSR1\n"); } printf("signal_handle running ...\n"); } int main(int argc,char **argv) { signal(SIGUSR1, signal_handle); while(1) { sleep(100); } return 0 ; }
通過向上述進程發送SIGUSR1信號,即可執行signal_handle()函數:
#向指定的pid進程發送SIGUSR1信號 kill -s SIGUSR1 pid
針對如上的特性,我們設計了一種信號處理函數,如果收到SIGUSR1信號,我們應用程序中的一個標志位將會置位真,再次收到置為假,達到通過發送信號控制應用程序運行的目的,用於調試應用程序。信號處理函數設計如下:
#include <stdio.h> #include <signal.h> //該變量可以在應用程序中使用 static bool flag = false; void signal_handle(int sig_num) { if(SIGUSR1 != sig_num) { return; } flag = flag ? false : true; } int main(int argc,char **argv) { signal(SIGUSR1, signal_handle); while(1) { if(flag) { printf("flag is true!\n"); } else { printf("flag is false\n"); } sleep(5); } return 0 ; }
如上我們就可以在程序運行過程中控制程序運行的分支,達到控制應用程序的目的。
另外對於多線程卡死問題,線程卡死情況不明的情況下(線程運行狀態無法反應真實情況),可以增加該方法,通過在線程運行路徑添加打印日志的方法檢測線程是否真正運行。
if(flag) { debug("Thread is running!\n"); }