0
点赞
收藏
分享

微信扫一扫

使用信号机制在Linux程序中打印函数调用栈

343d85639154 2022-03-22 阅读 47
linuxc++
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <execinfo.h>
#include <ucontext.h>

void handler(int signo, siginfo_t *info, void *context)
{
        ucontext_t* ctx = (ucontext_t*)context;

        void *trace[16];
        char **messages = (char **)NULL;
        int i, trace_size = 0;

        trace_size = backtrace(trace, 16);

        /* overwrite sigaction with caller's address */
        trace[1] = (void *)ctx->uc_mcontext.gregs[REG_RIP];
        messages = backtrace_symbols(trace, trace_size);

        /* skip first stack frame (points here) */
        printf("[bt] Execution path:\n");
        for (i = 1; i < trace_size; ++i)
        {
                printf("[bt] #%d %s\n", i, messages[i]);

                /* find first occurence of '(' or ' ' in message[i] and assume
                 * everything before that is the file name. (Don't go beyond 0 though
                 * (string terminator)*/
                size_t p = 0;
                while(messages[i][p] != '(' && messages[i][p] != ' ' && messages[i][p] != 0)
                        ++p;

                char syscom[256];

                /* /usr/bin/addr2line */
                sprintf(syscom,"addr2line %p -e %.*s", trace[i], p, messages[i]);

                //last parameter is the file name of the symbol
                system(syscom);
        }

        exit(EXIT_SUCCESS);
}

int func_a(int a, char b) 
{
        char *p = (char *)0xdeadbeef;
        a = a + b;
        *p = 10;  /* CRASH here!! */

        return 2 * a;
}


int func_b() 
{
        int res, a = 5;
        res = 5 + func_a(a, 't');
        return res;
}


int main() 
{
        struct sigaction sa={0} ;

        /* Install our signal handler */
        sa.sa_sigaction = &handler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = SA_RESTART;

        sigaction(SIGSEGV, &sa, NULL);
        sigaction(SIGUSR1, &sa, NULL);

        /* Do something */
        printf("%d\n", func_b());
        //raise(SIGSEGV);
}

编译

gcc -g -rdynamic *.cpp -o bs
 

运行

 

举报

相关推荐

0 条评论