Переглянути джерело

[update]

rtthread_MCoreDump
huangyulong 5 місяці тому
джерело
коміт
b9a36bc5e1

+ 12
- 4
Middlewares/MCoreDump/addr2line/addr2line.c Переглянути файл

2
 #include <rtthread.h>
2
 #include <rtthread.h>
3
 #include "addr2line.h"
3
 #include "addr2line.h"
4
 
4
 
5
-#define PROJECT_NAME "project"
5
+#define PROJECT_NAME "project.out"
6
 #define addr2line_print rt_kprintf
6
 #define addr2line_print rt_kprintf
7
 
7
 
8
 // 错误类型打印
8
 // 错误类型打印
513
     }
513
     }
514
 }
514
 }
515
 
515
 
516
+// 只会找符合要求的lr,不能找pc值。所以要指定pc
516
 void addr2line_cmd_with_pc_print(uint32_t *thread_pc, uint32_t *addr, int size)
517
 void addr2line_cmd_with_pc_print(uint32_t *thread_pc, uint32_t *addr, int size)
517
 {
518
 {
518
     addr2line_print("addr2line -e " PROJECT_NAME " -a -f ");
519
     addr2line_print("addr2line -e " PROJECT_NAME " -a -f ");
532
 
533
 
533
         if (pc % 2 == 0) // thumb 指令pc寄存器值一定是偶数
534
         if (pc % 2 == 0) // thumb 指令pc寄存器值一定是偶数
534
             continue;
535
             continue;
535
-        
536
 
536
 
537
         pc = lr - 1; // lr寄存器值保存的是pc+1
537
         pc = lr - 1; // lr寄存器值保存的是pc+1
538
 
538
 
539
         if ((uint32_t)thread_pc == pc) // 忽略:已经指定打印过了
539
         if ((uint32_t)thread_pc == pc) // 忽略:已经指定打印过了
540
             continue;
540
             continue;
541
 
541
 
542
-        if (true == disassembly_ins_is_bl_blx(pc - sizeof(size_t))) // pc 的上一条指令是跳转指令
542
+        if (true == disassembly_ins_is_bl_blx(pc - sizeof(size_t))) // pc 的上一条指令是跳转指
543
+        {
544
+//          if (i + 1 < size && pc != addr[i + 1] && true == is_in_text(addr[i + 1])) // 最后一次调用的情况:LR、PC还在CPU寄存器里面挨着的
545
+//          {
546
+//              addr2line_print("%08x ", addr[i + 1]);
547
+//              i++;
548
+//          }
549
+
543
             addr2line_print("%08x ", pc);
550
             addr2line_print("%08x ", pc);
551
+        }
544
     }
552
     }
545
 
553
 
546
-    addr2line_print("\n\n");
554
+    addr2line_print("\n");
547
 }
555
 }
548
 
556
 
549
 void addr2line_cmd_print(uint32_t *addr, int size)
557
 void addr2line_cmd_print(uint32_t *addr, int size)

+ 21
- 1
Middlewares/MCoreDump/arch/armv7m/armv7m.c Переглянути файл

206
 void print_registers_armv7m(core_regset_type *reg, fp_regset_type *fp_reg, char *thread)
206
 void print_registers_armv7m(core_regset_type *reg, fp_regset_type *fp_reg, char *thread)
207
 {
207
 {
208
     mcd_print("Registers@%s\n", thread);
208
     mcd_print("Registers@%s\n", thread);
209
+    mcd_print("R13(SP): 0x%08x\n", reg->sp);
210
+#if 0
209
     mcd_print("R0: 0x%08x\n", reg->r0);
211
     mcd_print("R0: 0x%08x\n", reg->r0);
210
     mcd_print("R1: 0x%08x\n", reg->r1);
212
     mcd_print("R1: 0x%08x\n", reg->r1);
211
     mcd_print("R2: 0x%08x\n", reg->r2);
213
     mcd_print("R2: 0x%08x\n", reg->r2);
223
     mcd_print("R14(LR): 0x%08x\n", reg->lr);
225
     mcd_print("R14(LR): 0x%08x\n", reg->lr);
224
     mcd_print("R15(PC): 0x%08x\n", reg->pc);
226
     mcd_print("R15(PC): 0x%08x\n", reg->pc);
225
     mcd_print("xPSR: 0x%08x\n", reg->xpsr);
227
     mcd_print("xPSR: 0x%08x\n", reg->xpsr);
228
+#else // 按压栈顺序打印
229
+    mcd_print("xPSR: 0x%08x\n", reg->xpsr);
230
+    mcd_print("R15(PC): 0x%08x\n", reg->pc);
231
+    mcd_print("R14(LR): 0x%08x\n", reg->lr);
232
+    mcd_print("R12: 0x%08x\n", reg->r12);
233
+    mcd_print("R3: 0x%08x\n", reg->r3);
234
+    mcd_print("R2: 0x%08x\n", reg->r2);
235
+    mcd_print("R1: 0x%08x\n", reg->r1);
236
+    mcd_print("R0: 0x%08x\n", reg->r0);
237
+    mcd_print("R11: 0x%08x\n", reg->r11);
238
+    mcd_print("R10: 0x%08x\n", reg->r10);
239
+    mcd_print("R9: 0x%08x\n", reg->r9);
240
+    mcd_print("R8: 0x%08x\n", reg->r8);
241
+    mcd_print("R7: 0x%08x\n", reg->r7);
242
+    mcd_print("R6: 0x%08x\n", reg->r6);
243
+    mcd_print("R5: 0x%08x\n", reg->r5);
244
+    mcd_print("R4: 0x%08x\n", reg->r4);
245
+#endif
226
 }
246
 }
227
 
247
 
228
 /**
248
 /**
401
 #else
421
 #else
402
     uint32_t *stack_ptr = context;
422
     uint32_t *stack_ptr = context;
403
     stack_ptr += 1; /* 跳过:exc_return */
423
     stack_ptr += 1; /* 跳过:exc_return */
404
-//  stack_ptr += 1; // 如开启fpuflag
424
+    //  stack_ptr += 1; // 如开启fpuflag
405
 #endif
425
 #endif
406
 
426
 
407
     /*
427
     /*

+ 31
- 5
Middlewares/MCoreDump/rtthread_port.c Переглянути файл

14
 #include "addr2line/addr2line.h"
14
 #include "addr2line/addr2line.h"
15
 
15
 
16
 #define PRINT_COREDUMP_INFO_STRING 1 // 打印字符串格式的coredump信息
16
 #define PRINT_COREDUMP_INFO_STRING 1 // 打印字符串格式的coredump信息
17
+#define STACK_CORE_REG_SIZE (17 * 4) // 16个自动+手动压栈寄存器 + exe_return
18
+#define STACK_FPU_REG_SIZE (17 * 4) // 17个自动压栈的浮点寄存器
17
 
19
 
18
 /*
20
 /*
19
  * RT-Thread OS abstraction layer implementation for MCoreDump
21
  * RT-Thread OS abstraction layer implementation for MCoreDump
161
                 {
163
                 {
162
                     *addr = get_cur_core_regset_address()->sp;  // 异常中填充
164
                     *addr = get_cur_core_regset_address()->sp;  // 异常中填充
163
                     *memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - (rt_uint32_t)thread->sp;
165
                     *memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - (rt_uint32_t)thread->sp;
164
-
166
+                    *addr -= STACK_CORE_REG_SIZE; // 异常中断里面已经压栈了但还没更新tcb里面的sp指针
167
+                    *memlen += STACK_CORE_REG_SIZE * 2; // 前后括大两倍:实际可能更多局部变量在死机前还没来得及向下增长sp
168
+#if MCD_FPU_SUPPORT
169
+                    /* Read FPU flag first - indicates if FPU context was saved */
170
+                    uint32_t fpu_flag = *(uint32_t *)thread->sp;
171
+                    *addr -= 1;
172
+                    *memlen += 1;
173
+
174
+                    if (fpu_flag)
175
+                    {
176
+                        *addr -= STACK_FPU_REG_SIZE; // 异常中断里面已经压栈了但还没更新tcb里面的sp指针
177
+                        *memlen += STACK_FPU_REG_SIZE;
178
+                    }
179
+#endif
165
                     if (*memlen > thread->stack_size)
180
                     if (*memlen > thread->stack_size)
166
                     {
181
                     {
167
                         mcd_println("The stack may overflow!!!");
182
                         mcd_println("The stack may overflow!!!");
209
             {
224
             {
210
                 addr = (rt_uint32_t)get_cur_core_regset_address()->sp;      // 异常中填充
225
                 addr = (rt_uint32_t)get_cur_core_regset_address()->sp;      // 异常中填充
211
                 memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - (rt_uint32_t)thread->sp;
226
                 memlen = (rt_uint32_t)thread->stack_addr + thread->stack_size - (rt_uint32_t)thread->sp;
212
-
227
+                addr -= STACK_CORE_REG_SIZE; // 异常中断里面已经压栈了但还没更新tcb里面的sp指针
228
+                memlen += STACK_CORE_REG_SIZE * 2; // 前后括大两倍:实际可能更多局部变量在死机前还没来得及向下增长sp
229
+#if MCD_FPU_SUPPORT
230
+                /* Read FPU flag first - indicates if FPU context was saved */
231
+                uint32_t fpu_flag = *(uint32_t *)thread->sp;
232
+                addr -= 1;
233
+                memlen += 1;
234
+
235
+                if (fpu_flag)
236
+                {
237
+                    addr -= STACK_FPU_REG_SIZE; // 异常中断里面已经压栈了但还没更新tcb里面的sp指针
238
+                    memlen += STACK_FPU_REG_SIZE;
239
+                }
240
+#endif
213
                 if (memlen > thread->stack_size)
241
                 if (memlen > thread->stack_size)
214
                 {
242
                 {
215
                     mcd_println("The stack may overflow!!!");
243
                     mcd_println("The stack may overflow!!!");
217
                 }
245
                 }
218
 
246
 
219
                 print_registers((void *)get_cur_core_regset_address(), get_cur_fp_regset_address(), thread->name);
247
                 print_registers((void *)get_cur_core_regset_address(), get_cur_fp_regset_address(), thread->name);
220
-#define STACK_FRAME_SIZE (17 * 4) // 17个寄存器
221
-                rt_uint32_t addr2 = (rt_uint32_t)thread->sp - STACK_FRAME_SIZE;
222
-                addr2line_cmd_with_pc_print((rt_uint32_t *)get_cur_core_regset_address()->pc, (uint32_t *)addr2, memlen + STACK_FRAME_SIZE);
248
+                addr2line_cmd_with_pc_print((rt_uint32_t *)get_cur_core_regset_address()->pc, (uint32_t *)addr, memlen);
223
             }
249
             }
224
             else
250
             else
225
             {
251
             {

Завантаження…
Відмінити
Зберегти