dump-process.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <linux/fs.h>
  2. #include <linux/mm.h>
  3. #include <linux/sched.h>
  4. #include <linux/string.h>
  5. #include <linux/uaccess.h>
  6. #include "ipanic.h"
  7. char NativeInfo[MAX_NATIVEINFO]; /* check that 32k is enought?? */
  8. unsigned long User_Stack[MAX_NATIVEHEAP]; /* 8K Heap */
  9. void _LOG(const char *fmt, ...)
  10. {
  11. char buf[256];
  12. int len = 0;
  13. va_list ap;
  14. va_start(ap, fmt);
  15. len = strlen(NativeInfo);
  16. if ((len + sizeof(buf)) < MAX_NATIVEINFO)
  17. vsnprintf(&NativeInfo[len], sizeof(buf), fmt, ap);
  18. va_end(ap);
  19. }
  20. void dump_registers(struct pt_regs *r)
  21. {
  22. if (r != NULL) {
  23. _LOG(" r0 %08x r1 %08x r2 %08x r3 %08x\n",
  24. r->ARM_r0, r->ARM_r1, r->ARM_r2, r->ARM_r3);
  25. _LOG(" r4 %08x r5 %08x r6 %08x r7 %08x\n",
  26. r->ARM_r4, r->ARM_r5, r->ARM_r6, r->ARM_r7);
  27. _LOG(" r8 %08x r9 %08x 10 %08x fp %08x\n",
  28. r->ARM_r8, r->ARM_r9, r->ARM_r10, r->ARM_fp);
  29. _LOG(" ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
  30. r->ARM_ip, r->ARM_sp, r->ARM_lr, r->ARM_pc, r->ARM_cpsr);
  31. }
  32. }
  33. int DumpNativeInfo(void)
  34. {
  35. struct task_struct *current_task;
  36. struct pt_regs *user_ret;
  37. struct vm_area_struct *vma;
  38. unsigned long userstack_start = 0;
  39. unsigned long userstack_end = 0, length = 0;
  40. int mapcount = 0;
  41. struct file *file;
  42. int flags;
  43. struct mm_struct *mm;
  44. int ret = 0, i = 0;
  45. current_task = get_current();
  46. user_ret = task_pt_regs(current_task);
  47. if (!user_mode(user_ret))
  48. return 0;
  49. dump_registers(user_ret);
  50. LOGI("pc/lr/sp 0x%08lx/0x%08lx/0x%08lx\n", user_ret->ARM_pc, user_ret->ARM_lr,
  51. user_ret->ARM_sp);
  52. _LOG("pc/lr/sp 0x%08lx/0x%08lx/0x%08lx\n", user_ret->ARM_pc, user_ret->ARM_lr,
  53. user_ret->ARM_sp);
  54. userstack_start = (unsigned long)user_ret->ARM_sp;
  55. if (current_task->mm == NULL)
  56. return 0;
  57. vma = current_task->mm->mmap;
  58. while (vma && (mapcount < current_task->mm->map_count)) {
  59. file = vma->vm_file;
  60. flags = vma->vm_flags;
  61. if (file) {
  62. _LOG("%08lx-%08lx %c%c%c%c %s\n", vma->vm_start, vma->vm_end,
  63. flags & VM_READ ? 'r' : '-',
  64. flags & VM_WRITE ? 'w' : '-',
  65. flags & VM_EXEC ? 'x' : '-',
  66. flags & VM_MAYSHARE ? 's' : 'p', file->f_path.dentry->d_iname);
  67. } else {
  68. const char *name = arch_vma_name(vma);
  69. mm = vma->vm_mm;
  70. if (!name) {
  71. if (mm) {
  72. if (vma->vm_start <= mm->start_brk &&
  73. vma->vm_end >= mm->brk) {
  74. name = "[heap]";
  75. } else if (vma->vm_start <= mm->start_stack &&
  76. vma->vm_end >= mm->start_stack) {
  77. name = "[stack]";
  78. }
  79. } else {
  80. name = "[vdso]";
  81. }
  82. }
  83. /* if (name) */
  84. {
  85. _LOG("%08lx-%08lx %c%c%c%c %s\n", vma->vm_start, vma->vm_end,
  86. flags & VM_READ ? 'r' : '-',
  87. flags & VM_WRITE ? 'w' : '-',
  88. flags & VM_EXEC ? 'x' : '-',
  89. flags & VM_MAYSHARE ? 's' : 'p', name);
  90. }
  91. }
  92. vma = vma->vm_next;
  93. mapcount++;
  94. }
  95. vma = current_task->mm->mmap;
  96. while (vma != NULL) {
  97. if (vma->vm_start <= userstack_start && vma->vm_end >= userstack_start) {
  98. userstack_end = vma->vm_end;
  99. break;
  100. }
  101. vma = vma->vm_next;
  102. if (vma == current_task->mm->mmap)
  103. break;
  104. }
  105. if (userstack_end == 0) {
  106. LOGE("Dump native stack failed:\n");
  107. return 0;
  108. }
  109. LOGI("Dump stack range (0x%08lx:0x%08lx)\n", userstack_start, userstack_end);
  110. _LOG("Dump stack range (0x%08lx:0x%08lx)\n", userstack_start, userstack_end);
  111. length =
  112. ((userstack_end - userstack_start) <
  113. (sizeof(User_Stack) - 1)) ? (userstack_end - userstack_start) : (sizeof(User_Stack) -
  114. 1);
  115. ret = copy_from_user((void *)(User_Stack), (const void __user *)(userstack_start), length);
  116. LOGI("copy_from_user ret(0x%08x),len:%lx\n", ret, length);
  117. i = 0;
  118. while ((i < (length / 4)) && (userstack_start < userstack_end)) {
  119. _LOG("0x%08x: 0x%08x\n", userstack_start, User_Stack[i]);
  120. userstack_start += 4;
  121. i++;
  122. }
  123. LOGD("end dump native stack:\n");
  124. _LOG("end dump native stack:\n");
  125. return 0;
  126. }
  127. void aee_dumpnative(void)
  128. {
  129. char *printk_buf = NativeInfo;
  130. int log_length = 0;
  131. memset(NativeInfo, 0, MAX_NATIVEINFO);
  132. DumpNativeInfo();
  133. log_length = strlen(NativeInfo);
  134. LOGD("\n DumpNativeInfo : %d\n", log_length);
  135. /* printk temporary buffer printk_buf[1024]. To avoid char loss, add 4 bytes here */
  136. while (log_length > 0) {
  137. LOGE("%s", printk_buf);
  138. printk_buf += 1020;
  139. log_length -= 1020;
  140. }
  141. }