int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { func_info * func_ptr = 0; char format[150]; char formatEIP[150]; struct Eipdebuginfo info; strcpy(format,"ebp %08x eip %08x args %08x %08x %08x %08x %08x\n"); strcpy(formatEIP, "\t%s:%d: %.*s+%d\n"); cprintf("Stack backtrace:\n"); func_ptr = (func_info*)read_ebp(); while(func_ptr != NULL){ cprintf(format,func_ptr,func_ptr->eip,func_ptr->args[0],func_ptr->args[1] , func_ptr->args[2], func_ptr->args[3],func_ptr->args[4]); debuginfo_eip((uintptr_t)func_ptr->eip,&info); cprintf(formatEIP, info.eip_file, info.eip_line, info.eip_fn_namelen, (char*)info.eip_fn_name,(uintptr_t)func_ptr->eip - info.eip_fn_addr); func_ptr = (func_info*) func_ptr->prevfunc_ebp; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { struct Eipdebuginfo info; unsigned int *ebp=(unsigned int *)read_ebp(); unsigned int *esp=(unsigned int *)read_esp(); unsigned int *eip=0; unsigned int arg[5]; int i=0; while(ebp) { for(i=0;i<5;i++) arg[i]=*(ebp+i+2); eip=ebp+1; debuginfo_eip(*eip,&info); cprintf(" ebp %08x eip %08x args ",(unsigned int)ebp,*eip ); for(i=0;i<5;++i) cprintf("%08x ", arg[i]); cprintf("\n"); cprintf("\t\t%s:%u:%.*s+%u\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, *eip-info.eip_fn_addr); esp=ebp+2; ebp=(unsigned int *)*ebp; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { unsigned ebp = read_ebp(); while (ebp) { struct Eipdebuginfo info; unsigned eip = *((unsigned *)ebp + 1); debuginfo_eip(eip, &info); cprintf("ebp %08x eip %08x args %08x %08x %08x %08x %08x %s:%d: %.*s+%d\n", ebp, eip, *((unsigned *)ebp + 2), *((unsigned *)ebp + 3), *((unsigned *)ebp + 4), *((unsigned *)ebp + 5), *((unsigned *)ebp + 6), info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, (char*)eip - (char*)info.eip_fn_addr); ebp = *(unsigned*)ebp; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t ebp, eip; int i; cprintf("Stack backtrace:\n"); ebp = read_ebp(); while (ebp) { eip = ((uint32_t *) ebp)[1]; cprintf(" ebp %08x eip %08x ", ebp, eip); cprintf("args "); for (i = 1; i <= 5; i++) { cprintf("%08x ", ((uint32_t *) ebp)[1 + i]); } cprintf("\n"); struct Eipdebuginfo info; if (!debuginfo_eip(eip, &info)) cprintf("\t%s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, eip - info.eip_fn_addr); ebp = ((uint32_t *) ebp)[0]; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. cprintf("Stack backtrace:\n"); uint32_t ebp = read_ebp(); uint32_t eip; // = read_eip(); struct Eipdebuginfo info; int idxStr; while (ebp != 0) { // print registers cprintf(" ebp %x", ebp); eip = *(uint32_t*)(ebp + 4); cprintf(" eip %x", eip); cprintf(" args %08x", *(uint32_t*)(ebp + 8)); cprintf(" %08x", *(uint32_t*)(ebp + 12)); cprintf(" %08x", *(uint32_t*)(ebp + 16)); cprintf(" %08x", *(uint32_t*)(ebp + 20)); cprintf(" %08x\n", *(uint32_t*)(ebp + 24)); ebp = *(uint32_t*)ebp; // print line numbers debuginfo_eip((uintptr_t)eip, &info); cprintf(" %s", info.eip_file); cprintf(":%d: ", info.eip_line); for (idxStr = 0; idxStr < info.eip_fn_namelen; idxStr++) cprintf("%c", info.eip_fn_name[idxStr]); cprintf("+%d\n", eip - info.eip_fn_addr); } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t eip=read_eip(); uint32_t ebp=read_ebp(); uint32_t esp=ebp; int i; struct Eipdebuginfo info; cprintf("Stack backtrace:\n"); // in Entry.S it sets ebp to 0 at first,so if ebp==0 then we know that there is no more stack. while(ebp!=0) { cprintf("ebp %08x eip %08x args ",ebp,eip); // pop the saved ebp to current ebp. ebp=*(uint32_t *)esp; esp+=4; // pop the saved eip to current eip. eip=*(uint32_t *)esp; esp+=4; for(i=0;i<=4;i++){ cprintf("%08x ",*(uint32_t *)esp); esp+=4; } cprintf("\n"); cprintf(" "); debuginfo_eip(eip,&info); cprintf("%s:%d: ",info.eip_file, info.eip_line); cprintf("%.*s",info.eip_fn_namelen, info.eip_fn_name); cprintf("+%d", eip-info.eip_fn_addr); cprintf("\n"); esp=ebp; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t *addr = 0; char format[FORMAT_LENGTH] = {0}; char formatName[FORMAT_LENGTH] = { 0 }; struct Eipdebuginfo info; strcpy(format, " ebp %08x eip %08x args %08x %08x %08x %08x %08x"); strcpy(formatName, " %s:%d: %.*s+%d\n"); addr = (uint32_t *)read_ebp(); cprintf("Stack backtrace\n"); for (; NULL != addr;) { cprintf(format, EBP(addr), EIP(addr), ARG(addr, 0), ARG(addr, 1), ARG(addr, 2), ARG(addr, 3), ARG(addr, 4)); debuginfo_eip(EIP(addr), &info); cprintf(formatName, info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, EIP(addr)-info.eip_fn_addr); addr = (uint32_t*)*addr; } return 0; }
static int ksc_backtrace(int argc ,char **argv ,struct Trapframe *tf) { // Your code here. unsigned int *ptr=(unsigned int *)__get_frame_pointer(); int ebp=0,eip=1,args=2; int count=0; struct Eipdebuginfo info; cprintf("Stack backtrace:\n"); while(count<=8) { if(debuginfo_eip((uintptr_t)ptr[eip] ,&info)) panic("oh~no!\n"); // exit while ebp backtrace to 0x0, it's our magic ebp value to the end; if(!ptr[ebp]) panic("backtrace to end!\n"); cprintf("%s:%u: %s+%x\n" ,info.eip_file ,info.eip_line, info.eip_fn_name ,info.eip_fn_namelen); cprintf("ebp %08x eip %x args %08x %08x %08x %08x %08x\n", ptr ,ptr[eip] ,ptr[args+0], ptr[args+1] , ptr[args+2] ,ptr[args+3] ,ptr[args+4]); ptr=(unsigned int*)ptr[ebp]; count++; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t ebp,eip; struct Eipdebuginfo info; int i=0; ebp=read_ebp(); while(ebp != 0) { eip = *((uint32_t *)(ebp+4)); // change ip to addr // debuginfo_eip(uintptr_t addr, struct Eipdebuginfo *info) debuginfo_eip((uintptr_t)eip,&info); cprintf("ebp %0x eip %0x ",ebp,eip); cprintf("args "); for(i=0;i<=4;i++) cprintf("%0x ",*(uint32_t *)(ebp+8+4*i)); cprintf("\n"); cprintf(" eipfile: %s eipfunc: %s ",info.eip_file,info.eip_fn_name); cprintf("\n"); ebp=*((uint32_t *)ebp); } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t *ebp = (uint32_t*)read_ebp(); struct Eipdebuginfo info; cprintf ("Stack backtrace:\n"); while (ebp != 0x0){ cprintf (" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, ebp[1], ebp[2], ebp[3], ebp[4], ebp[5], ebp[6]); debuginfo_eip(ebp[1],&info); cprintf ("%s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen,info.eip_fn_name, ebp[1]-info.eip_fn_addr); ebp = (uint32_t*) ebp[0]; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t* ebp = (uint32_t*) read_ebp(); cprintf("Stack backtrace:\n"); while (ebp != 0) { cprintf(" ebp %08x eip %08x", ebp, *(ebp+1)); cprintf(" args %08x %08x %08x %08x %08x\n", *(ebp+2), *(ebp+3), *(ebp+4), *(ebp+5), *(ebp+6)); struct Eipdebuginfo info; debuginfo_eip(*(ebp+1), &info); cprintf(" %s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, *(ebp + 1) - info.eip_fn_addr); ebp = (uint32_t*) *ebp; } return 0; }
// Release the lock. void spin_unlock(struct spinlock *lk) { #ifdef DEBUG_SPINLOCK if (!holding(lk)) { int i; uint32_t pcs[10]; // Nab the acquiring EIP chain before it gets released memmove(pcs, lk->pcs, sizeof pcs); #ifdef bug_017 if(lk->cpu == 0) { cprintf("Total lock_cnt:%d\n",lock_cnt); panic("here\n"); } #endif cprintf("CPU %d cannot release %s: held by CPU %d\nAcquired at:", cpunum(), lk->name, lk->cpu->cpu_id); for (i = 0; i < 10 && pcs[i]; i++) { struct Eipdebuginfo info; if (debuginfo_eip(pcs[i], &info) >= 0) cprintf(" %08x %s:%d: %.*s+%x\n", pcs[i], info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, pcs[i] - info.eip_fn_addr); else cprintf(" %08x\n", pcs[i]); } panic("spin_unlock"); } lk->pcs[0] = 0; lk->cpu = 0; #endif // The xchg serializes, so that reads before release are // not reordered after it. The 1996 PentiumPro manual (Volume 3, // 7.2) says reads can be carried out speculatively and in // any order, which implies we need to serialize here. // But the 2007 Intel 64 Architecture Memory Ordering White // Paper says that Intel 64 and IA-32 will not move a load // after a store. So lock->locked = 0 would work here. // The xchg being asm volatile ensures gcc emits it after // the above assignments (and after the critical section). xchg(&lk->locked, 0); }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. struct Eipdebuginfo info; int i = 1; uint32_t* ebp = (uint32_t*) read_ebp(); uint32_t eip = *(ebp + 1); // return address cprintf("Stack backtrace:\n"); for (; ebp != 0; ebp = (uint32_t*)(*(ebp)), eip = *(ebp + 1)) { cprintf(" ebp %08x eip %08x args", ebp, eip); for (i = 1; i <= 5; ++i) cprintf(" %08x", *(ebp + 1 + i)); cprintf("\n"); debuginfo_eip((uintptr_t)(*(ebp + 1)), &info); cprintf(" %s:%d: %.*s+%u\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, (unsigned int)(*(ebp + 1) - info.eip_fn_addr)); } return 0; }
// @yzy int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { uint32_t tmp_ebp = read_r11(), tmp_eip; int debuginfo_ret, i; struct Eipdebuginfo info; cprintf("Stack backtrace:\n"); // in arm, r11 points to ret addr, and old r11 is just below ret addr while (tmp_ebp != 0x0) { // ret addr stays just above ebp tmp_eip = *((uint32_t*)tmp_ebp); cprintf(" ebp %08x", tmp_ebp); cprintf(" eip %08x", tmp_eip); // loop 5 variables above ret addr // because of sl register, not possible yet //for (i = 0; i < 5; i++) { // cprintf(" %08x", *((uint32_t*)tmp_ebp + 2 + i)); //} //cprintf("\n"); // find the debuginfo of the instruction which ret addr indicates // and check whether the debug info is valid if (debuginfo_eip(tmp_eip, &info) == 0) { cprintf(" %s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, (int)tmp_eip - (int)info.eip_fn_addr); } else { cprintf(" debuginfo not available\n"); } // update tmp_ebp tmp_ebp = *((uint32_t*)tmp_ebp - 1); } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. int * ebp = (int *) read_ebp(); uint32_t eip; uint32_t arg[5]; struct Eipdebuginfo info; while (ebp != 0){ eip = ebp[1]; arg[0] = ebp[2]; arg[1] = ebp[3]; arg[2] = ebp[4]; arg[3] = ebp[5]; arg[4] = ebp[6]; cprintf("ebp %08x eip %08x args %08x %08x %08x %08x %08x\n",ebp,eip,arg[0],arg[1],arg[2],arg[3],arg[4]); debuginfo_eip(eip, &info); cprintf("%s:%d: %.*s+%d\n",info.eip_file, info.eip_line, info.eip_fn_namelen ,info.eip_fn_name, eip-info.eip_fn_addr); ebp= (int *) ebp[0]; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. // 寄存器ebp 的值是当前栈帧的最高地址,而且这个最高地址对应的内存单元里面存放的值恰好是调用者栈帧的最高地址 // 寄存器eip 存放的是cpu 执行下一条指令的地址 uint32_t *ebp = (uint32_t *)read_ebp(); struct Eipdebuginfo info; cprintf("Stack backtrace:\n"); while (ebp) { cprintf("ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, ebp[1], ebp[2], ebp[3], ebp[4], ebp[5], ebp[6]); uint32_t eip = ebp[1]; debuginfo_eip(eip, &info); cprintf("%s:%d : %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, (eip - info.eip_fn_addr)); ebp = (uint32_t *)(*ebp); } return 0; }
int csa_backtrace(int argc, char **argv, struct Trapframe *tf) { uint32_t* ebp = (uint32_t*) read_ebp(); cprintf("Stack backtrace:\n"); while (ebp) { uint32_t eip = ebp[1]; cprintf("ebp %x eip %x args", ebp, eip); int i; for (i = 2; i <= 6; ++i) cprintf(" %08.x", ebp[i]); cprintf("\n"); struct Eipdebuginfo info; debuginfo_eip(eip, &info); cprintf("\t%s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, eip-info.eip_fn_addr); // kern/monitor.c:143: monitor+106 ebp = (uint32_t*) *ebp; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { uint32_t ebp, eip, *p; struct Eipdebuginfo info; ebp = read_ebp(); while (ebp != 0) { p = (uint32_t *) ebp; eip = p[1]; cprintf("ebp %x eip %x args %08x %08x %08x %08x %08x\n", ebp, eip, p[2], p[3], p[4], p[5], p[6]); if (debuginfo_eip(eip, &info) == 0) { int fn_offset = eip - info.eip_fn_addr; cprintf("%s:%d: %.*s+%d\n", info.eip_file, info.eip_line, info.eip_fn_namelen, info.eip_fn_name, fn_offset); } ebp = p[0]; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t * ebp; ebp = (uint32_t *)read_ebp(); cprintf("Stack backtrace:\n"); while(ebp != 0){ cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, (uint32_t *)ebp[1], ebp[2], ebp[3], ebp[4] , ebp[5], ebp[6]); struct Eipdebuginfo dinfo; debuginfo_eip((uintptr_t)(uint32_t *)ebp[1], &dinfo); char tmpname[30]; strcpy(tmpname, dinfo.eip_fn_name); tmpname[dinfo.eip_fn_namelen] = '\0'; cprintf(" %s:%d: %s+%u\n", dinfo.eip_file, dinfo.eip_line, tmpname, (uint32_t)ebp[1] - dinfo.eip_fn_addr); ebp = (uint32_t *)ebp[0]; } return 0; }
int mon_backtrace(int argc, char **argv, struct Trapframe *tf) { // Your code here. uint32_t *ebp; uint32_t eip; uint32_t arg0, arg1, arg2, arg3, arg4; ebp = (uint32_t *)read_ebp(); eip = ebp[1]; arg0 = ebp[2]; arg1 = ebp[3]; arg2 = ebp[4]; arg3 = ebp[5]; arg4 = ebp[6]; cprintf("Stack backtrace:\n"); while(ebp != 0) { char fn[100]; cprintf(" ebp %08x eip %08x args %08x %08x %08x %08x %08x\n", ebp, eip, arg0, arg1, arg2, arg3, arg4); struct Eipdebuginfo info; debuginfo_eip(eip, &info); snprintf(fn, info.eip_fn_namelen+1, "%s", info.eip_fn_name); cprintf(" %s:%u: %s+%u\n", info.eip_file, info.eip_line, fn, eip - info.eip_fn_addr); ebp = (uint32_t *)ebp[0]; eip = ebp[1]; arg0 = ebp[2]; arg1 = ebp[3]; arg2 = ebp[4]; arg3 = ebp[5]; arg4 = ebp[6]; } return 0; }