• 利用Linux信号SIGUSR1调试程序


    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
    ");  
        }  
        printf("signal_handle running ...
    ");  
    }  
    
    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!
    ");
            }
            else
            {
                printf("flag is false
    ");
            }
            sleep(5);  
        }  
        return 0 ;  
    }

    如上我们就可以在程序运行过程中控制程序运行的分支,达到控制应用程序的目的。

    另外对于多线程卡死问题,线程卡死情况不明的情况下(线程运行状态无法反应真实情况),可以增加该方法,通过在线程运行路径添加打印日志的方法检测线程是否真正运行。

    if(flag)
    {
        debug("Thread is running!
    ");
    }
  • 相关阅读:
    JS中的if语句内如何加or使多个条件通过
    对计算属性中get和set的理解
    如何在vue里实现同步阻塞请求,请求完成之前不加载页面或组件?
    vue 路由传参 params 与 query两种方式的区别
    vue中通过路由跳转的三种方式
    vue生成单文件组件和组件嵌套步骤
    this.$router.push() 在新窗口怎么打开
    Vue路由获取路由参数
    vue的v-for循环普通数组、对象数组、对象、数字
    element el-cascader设置默认值
  • 原文地址:https://www.cnblogs.com/zafu/p/9267215.html
Copyright © 2020-2023  润新知