IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> LINUX C/C++捕获段错误,打印出错的具体位置(精确到哪一行) ? --Xilinx ARM版本 -> 正文阅读

[C++知识库]LINUX C/C++捕获段错误,打印出错的具体位置(精确到哪一行) ? --Xilinx ARM版本

? ? 之前文章转载了?LINUX C/C++捕获段错误,打印出错的具体位置(精确到哪一行)?, 但再arm-xilinx-linux-gnueabi-gcc 编译是无法通过,现在把能在arm-xilinx-linux-gnueabi-gcc下编译的源码发布如下:

/*
* 作者: leehomwu
* 日期: 2011-05-14
* 修订: 2011-06-11, 处理部分处理器会将出错时的 EIP 也入栈的情况
* 描述: 捕获段错误、浮点错误,输出发生错误时的具体位置、调用路径
* 使用: 在 main 函数所在文件包含该头文件即可
* 示例: 当发生段错误或浮点错误时,会向STDOUT打印调用路径上的指令地址,类似:
			signal[8] catched when running code at 80486f0
			signal[8] catched when running code at 80488ea
			signal[8] catched when running code at 80488d9

		进一步运行命令行,解析指令地址:
			addr2line  80486f0 80488ea 80488d9 -s -C -f -e [可执行文件]

		得到输出:
			main
			newsig.cpp:14
			a()
			kk.cpp:23
			b()
			kk.cpp:19
*/


#ifndef __SEGV_CATCH_H
#define __SEGV_CATCH_H


#include <execinfo.h>
#include <signal.h>
#include <stdio.h>



#ifndef __USE_GNU
	#define __USE_GNU
	#include <ucontext.h>
	#include <ucontext.h>
	#undef __USE_GNU
#else
	#include <ucontext.h>
	#include <sys/ucontext.h>
#endif


#ifdef __cplusplus
	static void initSegvCatch(void);
    class C_SEGVCATCH{
		public:
			C_SEGVCATCH(){
				initSegvCatch();
			}
	};
	static C_SEGVCATCH C_segv_catch;
#else
	static void initSegvCatch(void) __attribute__ ((constructor));
#endif

static void OnSIGSEGV(int,siginfo_t*,void*);
static void initSegvCatch()
{
    struct sigaction act;
	sigemptyset(&act.sa_mask);
	act.sa_sigaction = OnSIGSEGV;
	act.sa_flags = SA_SIGINFO;
	if (sigaction(SIGSEGV, &act, NULL)<0 || sigaction(SIGFPE, &act, NULL)<0)
	{
		//perror("sigaction:");
		printf("set segment catch faile!\n");
	}

	printf("set segment catch ok!\n");
}

static void OnSIGSEGV(int signum, siginfo_t *info, void *ptr)
{
	static int iTime;
	if (iTime++ >= 1)
	{
		//容错处理:如果访问 ucontext_t 结构体时产生错误会进入该分支
		printf("ReEnter %s is not allowed!\n", __FUNCTION__);
		abort();
	}

	void * array[32];
	int nSize = backtrace(array, sizeof(array)/sizeof(array[0]));
	printf("signal: %d \n", nSize);

	int i;
	for (i = nSize-3; i > 2; i--)
	{
		//头尾几个地址不必输出
		//对array修正一下,使地址指向正在执行的代码
		printf("signal[%d] catched when running code at 0x%p\n", signum, array[i] - 1);
	}


	if (NULL != ptr)
	{
		ucontext_t* ptrUC = (ucontext_t*)ptr;


        printf("signal[%d] r0 0x%x\n", signum, ptrUC->uc_mcontext.arm_r0);
        printf("signal[%d] r1 0x%x\n", signum, ptrUC->uc_mcontext.arm_r1);
        printf("signal[%d] r2 0x%x\n", signum, ptrUC->uc_mcontext.arm_r2);
        printf("signal[%d] r3 0x%x\n", signum, ptrUC->uc_mcontext.arm_r3);
        printf("signal[%d] r4 0x%x\n", signum, ptrUC->uc_mcontext.arm_r4);
        printf("signal[%d] r5 0x%x\n", signum, ptrUC->uc_mcontext.arm_r5);
        printf("signal[%d] r6 0x%x\n", signum, ptrUC->uc_mcontext.arm_r6);
        printf("signal[%d] r7 0x%x\n", signum, ptrUC->uc_mcontext.arm_r7);
        printf("signal[%d] r8 0x%x\n", signum, ptrUC->uc_mcontext.arm_r8);
        printf("signal[%d] r9 0x%x\n", signum, ptrUC->uc_mcontext.arm_r9);
        printf("signal[%d] r10 0x%x\n",signum, ptrUC->uc_mcontext.arm_r10);
        printf("signal[%d] ip 0x%x\n", signum, ptrUC->uc_mcontext.arm_ip);
        printf("signal[%d] sp 0x%x\n", signum, ptrUC->uc_mcontext.arm_sp);
        printf("signal[%d] fp 0x%x\n", signum, ptrUC->uc_mcontext.arm_fp);
        printf("signal[%d] lr 0x%x\n", signum, ptrUC->uc_mcontext.arm_lr);
        printf("signal[%d] cpsr 0x%x\n", signum, ptrUC->uc_mcontext.arm_cpsr);
        printf("signal[%d] trap_no 0x%x\n", signum, ptrUC->uc_mcontext.trap_no);
        printf("signal[%d] error_code 0x%x\n", signum, ptrUC->uc_mcontext.error_code);
        printf("fault_address 0x%x\n", ptrUC->uc_mcontext.fault_address);
	}
	else
	{
		printf("signal[%d] catched when running code at unknown address\n", signum);
	}

	abort();
}



#endif // __SEGV_CATCH_H

uc_mcontext 结构体如下

#ifndef _ASMARM_SIGCONTEXT_H
#define _ASMARM_SIGCONTEXT_H

/*
 * Signal context structure - contains all info to do with the state
 * before the signal handler was invoked.  Note: only add new entries
 * to the end of the structure.
 */
struct sigcontext {
	unsigned long trap_no;
	unsigned long error_code;
	unsigned long oldmask;
	unsigned long arm_r0;
	unsigned long arm_r1;
	unsigned long arm_r2;
	unsigned long arm_r3;
	unsigned long arm_r4;
	unsigned long arm_r5;
	unsigned long arm_r6;
	unsigned long arm_r7;
	unsigned long arm_r8;
	unsigned long arm_r9;
	unsigned long arm_r10;
	unsigned long arm_fp;
	unsigned long arm_ip;
	unsigned long arm_sp;
	unsigned long arm_lr;
	unsigned long arm_pc;
	unsigned long arm_cpsr;
	unsigned long fault_address;
};


#endif

运行后可以捕捉到错误地址, 但使用arm-xilinx-linux-gnueabi-add2line 出现错误,继续查找原因。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 07:51:17  更:2022-05-08 07:51:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:00:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码