linux应用程序段错误调试

本文介绍了如何在Linux环境下分析和调试应用程序段错误。首先,解释了堆和栈的概念,堆用于开发者分配和释放内存,栈则由操作系统自动管理。接着,详细阐述了如何通过修改内核设置、分析错误信息以及利用栈回溯来定位段错误的源头。通过反汇编代码和理解汇编指令,可以确定导致问题的具体代码行。
摘要由CSDN通过智能技术生成

一、堆、栈

在分析段错误之前,先了解一下什么是堆?什么是栈?

堆:一般由开发者分配释放,如果没有释放,程序结束时,在有的OS中可能会被自动释放,分配方式类似于链表。堆的操作方式为,队列优先,先进先出的原则。

栈:由操作系统自动分配,存放函数的参数值,局部变量。栈的操作方式为,先进后出的原则。

堆栈中定义了一些操作。 两个最重要的是PUSH和POP。 
PUSH:操作在堆栈的顶部加入一个元素。
POP:操作相反,在堆栈顶部移去一个元素,并将堆栈的大小减一

二、分析应用程序段错误

1、修改内核,让内核有打印应用程序段错误的能力。

在内核arch/arm/目录下检索,grep -nr "Unable to handle kernel"。在mm/fault.c中找到相应的处理函数。

static void
__do_user_fault(struct task_struct *tsk, unsigned long addr,
		unsigned int fsr, unsigned int sig, int code,
		struct pt_regs *regs)
{
	struct siginfo si;

	if (addr > TASK_SIZE)
		harden_branch_predictor();

	clear_siginfo(&si);

#ifdef CONFIG_DEBUG_USER
	if (((user_debug & UDBG_SEGV) && (sig == SIGSEGV)) ||
	    ((user_debug & UDBG_BUS)  && (sig == SIGBUS))) {
		printk(KERN_DEBUG "%s: unhandled page fault (%d) at 0x%08lx, code 0x%03x\n",
		       tsk->comm, sig, addr, fsr);
		show_pte(tsk->mm, addr);
		show_regs(regs);
	}
#endif

	tsk->thread.address = addr;
	tsk->thread.error_code = fsr;
	tsk->thread.trap_no = 14;
	si.si_signo = sig;
	si.si_errno = 0;
	si.si_code = code;
	si.si_addr = (void __user *)addr;
	force_sig_info(sig, &si, tsk);
}

在.config文件中检查是否打开了这个宏CONFIG_DEBUG_USER。没有打开,就make menuconfig配置。内核一般默认是打开的。其次就是user_debug,这个变量在u-boot中指定,之前测试的u-boot一直没有打开。重启开发板,设置user_debug = 0xff,暴力一点吧。

set bootargs noinitrd root=/dev/mtdblock4 rw init=/linuxrc rootfstype=yaffs2 console=ttySAC0,115200 user_debug=0xff

这里简单写了一个段错误的测试代码:测试一下。

#include <stdio.h>

void C(int *p){
	*p =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值