• 使用linux backtrace打印出错函数堆栈信息


    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的。

    在glibc头文件"execinfo.h"中声明了三个函数用于获取当前线程的函数调用堆栈。

    int backtrace(void **buffer,int size) 

    /*judge whether process is exist*/
    bool processExists(char * process_name) {
    FILE *ptr;
    int RE_BUF_SIZE = 32;
    char rebuff[RE_BUF_SIZE];
    char ps[128];
    snprintf(ps, sizeof(ps), "ps | grep %s |grep -v grep| wc -l", process_name);
    if((ptr = popen(ps, "r")) != NULL) {
    int count = 0;
    fgets(rebuff, RE_BUF_SIZE, ptr);
    if(rebuff != NULL) {
    count = atoi(rebuff);
    }
    pclose(ptr);
    return count >= 1;
    }

    printf("Current process %s is not Exist!!!!\n",process_name);
    return false;
    }

    static char *signal_str[] = {
    [1] = "SIGHUP", [2] = "SIGINT", [3] = "SIGQUIT", [4] = "SIGILL", [5] = "SIGTRAP",
    [6] = "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",
    };

    void sig_handler(int signo)
    {
    char cmd[64] = {};
    void *array[10];
    int size = 0;
    char **strings = NULL;
    int i = 0;

    #if 0
    printf("\n\n[%s: %d] bitbox crashed by signal %s.\n", __func__, __LINE__, signal_str[signo]);

    printf("Call Trace:\n");
    size = backtrace(array, 10);
    strings = backtrace_symbols(array, size);
    if (strings) {
    for (i = 0; i < size; i++)
    printf (" %s\n", strings[i]);
    free (strings);
    } else {
    printf("Not Found\n\n");
    }

    if (signo == SIGSEGV || signo == SIGBUS ||
    signo == SIGTRAP || signo == SIGABRT) {
    sprintf(cmd, "cat /proc/%d/maps", getpid());
    printf("Process maps:\n");
    system(cmd);
    }
    #else
    wdt_stop_count();
    #endif

    exit(-1);
    }

    int main(int argc, char **argv)
    {
    int c = -1;
    int daemonize = 0;
    printf("watchdog V1.7 start!!!!@_@\n");

    signal(SIGPIPE, SIG_IGN);
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);
    signal(SIGBUS, sig_handler);
    signal(SIGSEGV, sig_handler);
    signal(SIGABRT, sig_handler);

    while (1) {
    c = getopt(argc, argv, "bBf:h");
    if (c < 0)
    break;
    switch (c) {
    case 'b':
    case 'B':
    daemonize = 1;
    break;
    case 'f':
    break;
    case 'h':

    return 0;
    default:
    return -1;
    }
    }

    /* run in the background */
    if (daemonize) {
    if (daemon(0, 1)) {
    perror("daemon");
    return -1;
    }
    }

    }

  • 相关阅读:
    java.security.ProviderException: java.security.KeyException
    DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容
    mysql timestamp类型字段的CURRENT_TIMESTAMP与ON UPDATE CURRENT_TIMESTAMP属性
    阿里云composer 镜像
    封装redis操作 php版本
    金钱数友好显示 php版本
    php代码规范->如何写出规范且易于理解的项目代码-ZX版
    hibernate 注解大全
    国家省市区县乡镇三级,五级地址数据
    java基础 数据类型转换
  • 原文地址:https://www.cnblogs.com/wangym/p/10783951.html
Copyright © 2020-2023  润新知