【ARM】程序快速定位segmentation fault core dumped错误

您所在的位置:网站首页 Arm跑x86汇编 【ARM】程序快速定位segmentation fault core dumped错误

【ARM】程序快速定位segmentation fault core dumped错误

2023-09-01 06:03| 来源: 网络整理| 查看: 265

1.应用场景

ARM开发过程中经常进程运行着出现段错误,这时候单纯靠加日志打log效率太低。使用gdb的话,由于APP进程太多,生成的core的文件特别大,而且gdb在arm板子也不好单步调试,不太友好还是pass掉。 目前使用段错误捕捉SIGSEGV信号,通过backtrace和backtrace_symbols函数进行堆栈信息定位,再使用addr2line工具将指令的地址和可执行映像转换成文件名、函数名和源代码行数。

root@chenwr-pc:/home/workspace/chenwr/study/test# ./out ./out [2020/07/21 09:38:15.249517 INFO]: [libcwr.c:0193]: =========>>>catch signal 11 fd = popen(cmd, "r"); if (NULL == fd) { perror("popen error\n"); break; } while (NULL != fgets(result, len, fd)) { offset = strlen(result); result += offset; } rc = pclose(fd); if (-1 == rc) { perror("pclose error\n"); break; } if (!WIFEXITED(rc)) { perror("Run command failed\n"); break; } else { ret = WEXITSTATUS(rc); } } while (0); if (NULL == fd || -1 == rc) { strncpy(result, strerror(errno), len); //FK_TRACE_INFO("errno = %s\n", strerror(errno)); } fd = NULL; return ret; } /******************************************************************* ** 函数名: get_curprocess_name ** 函数描述: 获取当前进程名字 ** 参数: [out] process_name: 进程名 ** 返回: 成功返回0,失败返回-1。 ********************************************************************/ INT32S get_curprocess_name(INT8S *process_name) { FILE *fd = NULL; INT8S proc_pid_path[100] = {0}; INT8S buf[100] = {0}; //获取进程名字 snprintf(proc_pid_path, sizeof(proc_pid_path), "/proc/%d/status", getpid()); do { fd = fopen(proc_pid_path, "r"); if (NULL == fd) { FK_TRACE_ERROR("fopen %s fail\n", proc_pid_path); break; } if (NULL == fgets(buf, sizeof(buf)-1, fd)) { fclose(fd); FK_TRACE_ERROR("get current process name fail\n"); break; } sscanf(buf, "%*s %s", process_name); fclose(fd); return EXIT_OK; } while(0); return EXIT_ERROR; } /******************************************************************* ** 函数名: print_coredumped_msg ** 函数描述: 输出段错误详细信息,具体到函数行数。 ** 参数: [in] symbols: 符号信息 (backtrace_symbols的返回值);[in] catch_num: 捕获信息元素个数(backtrace的返回值) ** 返回: 成功返回0,失败返回-1。 ** 说明: ** int backtrace(void **buffer, int size); ** 该函数获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针数组,参数size用来指定buffer中可以保存多少个void*元素。 ** 函数的返回值是实际返回的void*元素个数。buffer中的void*元素实际是从堆栈中获取的返回地址。 ** ** char **backtrace_symbols(void *const *buffer, int size); ** 该函数将backtrace函数获取的信息转化为一个字符串数组,参数buffer是backtrace获取的堆栈指针,size是backtrace返回值。 ** 函数返回值是一个指向字符串数组的指针,它包含char*元素个数为size。 ** 每个字符串包含了一个相对于buffer中对应元素的可打印信息,包括函数名、函数偏移地址和实际返回地址。 ********************************************************************/ INT32S print_coredumped_msg(INT8S **symbols, INT32S catch_num) { INT8S tools[100] = "addr2line"; INT8S process_name[100] = {0}; INT8S cmd[100] = {0}; INT8S buf[100] = {0}; INT8S result[MAXBUF_SIZE] = {0}; INT8S *front_position = NULL; INT8S *back_position = NULL; INT8S *tmp = NULL; INT32S ret, i; //判断addr2line工具是否存在 ret = run_shell_cmd(tools, result, MAXBUF_SIZE); if (127 == ret) { FK_TRACE_ERROR("%s is not exist\n", tools); return EXIT_ERROR; } //获取当前进程名 ret = get_curprocess_name(process_name); if (ret) { return EXIT_ERROR; } //打印段错误详细行数 for (i = 0; i return EXIT_ERROR; } //结果包含??全部过滤掉 tmp = strstr(result, "??"); if (!tmp) { FK_TRACE_INFO("%s\n", result); } } front_position = NULL; back_position = NULL; tmp = NULL; return EXIT_OK; } /******************************************************************* ** 函数名: catch_core_dump ** 函数描述: 捕捉段错误信息 ** 参数: [in] signo: 信号 ** 返回: 无 ********************************************************************/ void catch_core_dump(INT32S signo) { INT32S catch_num; void *buf[MAXBUF_SIZE] = {0}; INT8S **symbols = NULL; FK_TRACE_INFO("\n=========>>>catch signal %d


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3