0
点赞
收藏
分享

微信扫一扫

Swagger技术

Sophia的玲珑阁 2023-09-18 阅读 42
开发语言

按照栈生长方向分:可以分为递增栈(向高地址生长);递减栈(向低地址生长)

按照sp执行位置来分:满栈(sp指向栈顶元素的位置);空栈(sp指向即将入栈的元素位置)

我这个环境是满减栈

 其实通过函数栈推导函数调用过程主要就是结合sp的位置以及汇编代码的压栈信息。找到LR寄存器的位置。

代码示例

起了一个内核线程,在函数f3里面会访问空指针,然后进入kdb

void f3(void ) {
  int i     = 0;
  int* addr = NULL; 
  for (i = 0; i < 10; ++i)
  {
     printk("%d\n", i);
  }
  *addr = 0x123;
  return;
}
void f2(int a, int b) {
  int d = 0;
  int *addr = 0;
  f3();
  d = a + b;
  printk("%d, %p\n", d, addr);
  return;
}

void f1(int a, int b) {
  int c = 0;
  c = a + b;
  f2(c,20);
  while (c > 0)
  {  
	printk("%d\n", c);
	--c;
  }
  return;
}
struct timer_list timer;
spinlock_t mylock;
static struct task_struct *test_task;
int test_thread(void* a)
{
	unsigned long flags;
	printk(KERN_EMERG "\r\n softlockup simulate, in_interrupt %u in_softirq %u, cpu id %d\n", in_interrupt(), in_softirq(), smp_processor_id());
	
	/*local_irq_disable();
	while (1){}*/
	f1(10, 20);
	return 0;
}

对应的汇编代码如下 

void f3(void ) {
    3ed0:	e92d4010 	push	{r4, lr}
  int i     = 0;
  int* addr = NULL; 
  for (i = 0; i < 10; ++i)
    3ed4:	e3a04000 	mov	r4, #0
  {
     printk("%d\n", i);
    3ed8:	e1a01004 	mov	r1, r4
    3edc:	e59f001c 	ldr	r0, [pc, #28]	; 3f00 <f3+0x30>
	dev->dev_addr[5] = (u8)(mac_high16 >> 8);
}
void f3(void ) {
  int i     = 0;
  int* addr = NULL; 
  for (i = 0; i < 10; ++i)
    3ee0:	e2844001 	add	r4, r4, #1
  {
     printk("%d\n", i);
    3ee4:	ebfffffe 	bl	0 <printk>
	dev->dev_addr[5] = (u8)(mac_high16 >> 8);
}
void f3(void ) {
  int i     = 0;
  int* addr = NULL; 
  for (i = 0; i < 10; ++i)
    3ee8:	e354000a 	cmp	r4, #10
    3eec:	1afffff9 	bne	3ed8 <f3+0x8>
  {
     printk("%d\n", i);
  }
  *addr = 0x123;
    3ef0:	e3a03000 	mov	r3, #0
    3ef4:	e3002123 	movw	r2, #291	; 0x123
    3ef8:	e5832000 	str	r2, [r3]
    3efc:	e8bd8010 	pop	{r4, pc}
    3f00:	0000034c 	.word	0x0000034c

00003f04 <f2>:
  return;
}
void f2(int a, int b) {
    3f04:	e92d4038 	push	{r3, r4, r5, lr}
    3f08:	e1a04000 	mov	r4, r0
    3f0c:	e1a05001 	mov	r5, r1
  int d = 0;
  int *addr = 0;
  f3();
    3f10:	ebfffffe 	bl	3ed0 <f3>
  d = a + b;
  printk("%d, %p\n", d, addr);
    3f14:	e0841005 	add	r1, r4, r5
    3f18:	e3000000 	movw	r0, #0
    3f1c:	e3a02000 	mov	r2, #0
    3f20:	e3400000 	movt	r0, #0
  return;
}
    3f24:	e8bd4038 	pop	{r3, r4, r5, lr}
void f2(int a, int b) {
  int d = 0;
  int *addr = 0;
  f3();
  d = a + b;
  printk("%d, %p\n", d, addr);
    3f28:	eafffffe 	b	0 <printk>

00003f2c <f1>:
  return;
}

void f1(int a, int b) {
    3f2c:	e92d4010 	push	{r4, lr}
  int c = 0;
  c = a + b;
    3f30:	e0804001 	add	r4, r0, r1
  f2(c,20);
    3f34:	e3a01014 	mov	r1, #20
    3f38:	e1a00004 	mov	r0, r4
    3f3c:	ebfffffe 	bl	3f04 <f2>
  while (c > 0)
    3f40:	e3540000 	cmp	r4, #0
    3f44:	d8bd8010 	pople	{r4, pc}
  {  
	printk("%d\n", c);
    3f48:	e1a01004 	mov	r1, r4
    3f4c:	e59f000c 	ldr	r0, [pc, #12]	; 3f60 <f1+0x34>
    3f50:	ebfffffe 	bl	0 <printk>

void f1(int a, int b) {
  int c = 0;
  c = a + b;
  f2(c,20);
  while (c > 0)
    3f54:	e2544001 	subs	r4, r4, #1
    3f58:	1afffffa 	bne	3f48 <f1+0x1c>
    3f5c:	e8bd8010 	pop	{r4, pc}
    3f60:	0000034c 	.word	0x0000034c

00003f64 <test_thread>:
}
struct timer_list timer;
spinlock_t mylock;
static struct task_struct *test_task;
int test_thread(void* a)
{
    3f64:	e92d4008 	push	{r3, lr}
    3f68:	e1a0200d 	mov	r2, sp
    3f6c:	e3c23d7f 	bic	r3, r2, #8128	; 0x1fc0
	unsigned long flags;
	printk(KERN_EMERG "\r\n softlockup simulate, in_interrupt %u in_softirq %u, cpu id %d\n", in_interrupt(), in_softirq(), smp_processor_id());
    3f70:	e3a01cff 	mov	r1, #65280	; 0xff00
    3f74:	e3c3303f 	bic	r3, r3, #63	; 0x3f
    3f78:	e340101f 	movt	r1, #31
    3f7c:	e3000000 	movw	r0, #0
    3f80:	e3400000 	movt	r0, #0
    3f84:	e5932004 	ldr	r2, [r3, #4]
    3f88:	e5933014 	ldr	r3, [r3, #20]
    3f8c:	e0021001 	and	r1, r2, r1
    3f90:	e2022cff 	and	r2, r2, #65280	; 0xff00
    3f94:	ebfffffe 	bl	0 <printk>
	
	/*local_irq_disable();
	while (1){}*/
	f1(10, 20);
    3f98:	e3a0000a 	mov	r0, #10
    3f9c:	e3a01014 	mov	r1, #20
    3fa0:	ebfffffe 	bl	3f2c <f1>
	return 0;
}
    3fa4:	e3a00000 	mov	r0, #0
    3fa8:	e8bd8008 	pop	{r3, pc}

从上面的汇编代码可以看到每个函数的入栈信息如下。假设函数f3里面的栈顶指针为 sp_f3

完整的异常log如下: 

从异常log我们可以知道f3的栈顶指针为 sp : ee227f40

f2的返回地址为ee227f40 + 4指向的地址里面的内容

同理一级一级往上推

 

 

另外也可以用命令mds直接查看 

举报

相关推荐

0 条评论