📄 db_eros.cxx
字号:
if (sn0->profCount > sn1->profCount) return -1; if (sn0->address == sn1->address) return 0; return 1;}enum HowSorted { Unknown, ByAddr, ByCount};static HowSorted FunSort = Unknown;static HowSorted LineSort = Unknown;voidddb_SortLinesByAddr(){ if (LineSort != ByAddr) { qsort(LineSym::table, LineSym::count, sizeof(LineSym), (qsortfn)ddb_CompareLinesByAddr); LineSort = ByAddr; }}voidddb_SortFunsByAddr(){ if (FunSort != ByAddr) { qsort(FuncSym::table, FuncSym::count, sizeof(FuncSym), (qsortfn)ddb_CompareFunsByAddr); FunSort = ByAddr; }}voidddb_SortFunsByCount(){ if (FunSort != ByCount) { qsort(FuncSym::table, FuncSym::count, sizeof(FuncSym), (qsortfn)ddb_CompareFunsByCount); FunSort = ByCount; }}voiddb_prof_clear_cmd(db_expr_t, int, db_expr_t, char*){ uint32_t kernelCodeLength = (uint32_t) etext; uint32_t tableSizeInWords = (kernelCodeLength >> 4); for (uint32_t i = 0; i < tableSizeInWords; i++) KernelProfileTable[i] = 0;}static uint64_tprep_prof(){ uint64_t totCount = 0ll; /* One profile word for every 16 bytes: */ const int topsz = 10; FuncSym *top[topsz]; for (int i = 0; i < topsz; i++) top[i] = 0; uint32_t kernelCodeLength = (uint32_t) etext; uint32_t tableSizeInWords = (kernelCodeLength >> 4); for (uint32_t i = 0; i < tableSizeInWords; i++) totCount += KernelProfileTable[i]; ddb_SortFunsByAddr(); /* Symbol table is sorted by address. We take advantage of that * here for efficiency: */ uint32_t limit = (uint32_t) etext; for (uint32_t i = 0; i < FuncSym::count; i++) { if (FuncSym::table[i].address >= limit) continue; FuncSym::table[i].profCount = 0; uint32_t address = FuncSym::table[i].address; address += 0xf; address &= ~0xfu; while (address < FuncSym::table[i+1].address) { FuncSym::table[i].profCount += KernelProfileTable[address >> 4]; address += 16; } } ddb_SortFunsByCount(); return totCount;}static voidshow_prof(uint64_t tot, uint32_t limit){ uint32_t printCount = 0; for (uint32_t i = 0; i < FuncSym::count; i++) { if (FuncSym::table[i].profCount == 0) continue; printCount++; db_printf("%02d: %-10u 0x%08x %s\n", i, FuncSym::table[i].profCount, FuncSym::table[i].address, FuncSym::table[i].name); if (printCount >= limit) break; } db_printf("Done. Total ticks: 0x%08x%08x\n", (uint32_t) (tot >> 32), (uint32_t) tot);}voiddb_prof_top_cmd(db_expr_t, int, db_expr_t, char*){ uint64_t totCount = prep_prof(); show_prof(totCount, 20);}voiddb_prof_all_cmd(db_expr_t, int, db_expr_t, char*){ uint64_t totCount = prep_prof(); show_prof(totCount, UINT32_MAX);}#endifvoiddb_show_irq_cmd(db_expr_t, int, db_expr_t, char*){ db_printf("Show IRQ temporarily disabled... surgery in progress\n");#if 0 db_printf("IRQ disable depth is %d\n", IRQ::DISABLE_DEPTH()); for (uint32_t i = 0; i < NUM_HW_INTERRUPT; i++) { IntAction *ia = IRQ::ddb_getaction(i); if (ia && ia->IsValid()) { db_printf("IRQ %d: \"%s\" (%s)\n", ia->GetIrq(), ia->DriverName(), ia->IsWired() ? "wired" : "not wired"); } }#endif}voiddb_kstat_hist_depend_cmd(db_expr_t, int, db_expr_t, char*){ int t; uint32_t bucket; t = db_read_token(); if (t != tNUMBER) Depend_ddb_dump_hist(); bucket = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } Depend_ddb_dump_bucket(bucket);}voiddb_kstat_hist_objhash_cmd(db_expr_t, int, db_expr_t, char*){ int t; uint32_t bucket; t = db_read_token(); if (t != tNUMBER) ObjectHeader::ddb_dump_hash_hist(); bucket = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } ObjectHeader::ddb_dump_bucket(bucket);}voiddb_show_sources(db_expr_t, int, db_expr_t, char*){ ObjectCache::ddb_DumpSources();}voiddb_check_nodes_cmd(db_expr_t, int, db_expr_t, char*){ if (Check::Nodes()) db_printf("nodes are okay\n"); else db_printf("nodes are crocked\n"); }voiddb_check_pages_cmd(db_expr_t, int, db_expr_t, char*){ if (Check::Pages()) db_printf("pages are okay\n"); else db_printf("pages are crocked\n"); }voiddb_check_ctxt_cmd(db_expr_t, int, db_expr_t, char*){ if (Check::Contexts("ddb")) db_printf("contexts are okay\n"); else db_printf("contexts are crocked\n");}voiddb_show_key_cmd(db_expr_t addr, int have_addr, db_expr_t, char*){ if (have_addr == 0) db_error("requires address\n"); db_eros_print_key(*((Key *) addr)); db_eros_print_key_details(*((Key *) addr));}voiddb_show_node_cmd(db_expr_t addr, int have_addr, db_expr_t, char*){ if (have_addr == 0) db_error("requires address\n"); db_eros_print_node(((Node *) addr));}voiddb_show_obhdr_cmd(db_expr_t addr, int have_addr, db_expr_t, char*){ if (have_addr == 0) db_error("requires address\n"); ((ObjectHeader *) addr)->ddb_dump();}voiddb_show_pins_cmd(db_expr_t, int, db_expr_t, char*){ ObjectCache::ddb_dump_pinned_objects();}voiddb_show_pmem_cmd(db_expr_t, int, db_expr_t, char*){ PhysMem::ddb_dump();}voiddb_show_pte_cmd(db_expr_t addr, int have_addr, db_expr_t, char*){ if (have_addr == 0) db_error("requires address\n"); ((PTE *) addr)->ddb_dump();}voiddb_show_pages_cmd(db_expr_t, int, db_expr_t, char*){ ObjectCache::ddb_dump_pages();}voiddb_show_nodes_cmd(db_expr_t, int, db_expr_t, char*){ ObjectCache::ddb_dump_nodes();}voiddb_user_continue_cmd(db_expr_t, int, db_expr_t, char*){ extern bool continue_user_bpt; continue_user_bpt = true;}voiddb_node_cmd(db_expr_t, int, db_expr_t, char*){ int t; OID oid; t = db_read_token(); if (t != tNUMBER) db_error("expects OID\n"); oid = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } Node *pNode = ObjectHeader::LookupNode(oid); if (pNode == 0) db_error("not in core\n"); db_eros_print_node(pNode);}voiddb_show_counters_cmd(db_expr_t, int, db_expr_t, char*){ int t; OID oid; t = db_read_token(); if (t != tNUMBER) db_error("expects OID\n"); oid = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } Node *pNode = ObjectHeader::LookupNode(oid); if (pNode == 0) db_error("not in core\n"); db_printf("Node 0x%08x%08x ac=0x%08x cc=0x%08x\n", (uint32_t) (pNode->ob.oid >> 32), (uint32_t) (pNode->ob.oid), pNode->ob.allocCount, pNode->callCount);#ifndef NDEBUG if (pNode->Validate() == false) db_error("...Is not valid\n");#endif bool isProcess = (pNode->obType == ObType::NtProcessRoot || pNode->obType == ObType::NtRegAnnex) && pNode->context; if (isProcess) { db_printf(" count = 0x%016X\n", pNode->context->stats.evtCounter0); } else { Key& k = pNode->slot[10]; uint32_t hi = k.nk.value[1]; uint32_t lo = k.nk.value[2]; db_printf(" count = 0x%08x%08x\n", hi, lo); }}voiddb_page_cmd(db_expr_t, int, db_expr_t, char*){ int t; OID oid; t = db_read_token(); if (t != tNUMBER) db_error("expects OID\n"); oid = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } ObjectHeader *pObj = ObjectHeader::Lookup(ObType::PtDataPage, oid); if (pObj == 0) db_error("not in core\n"); kva_t kva = ObjectCache::ObHdrToPage(pObj); db_printf("Page (hdr=0x%08x, data=0x%08x) 0x%08x%08x ac=0x%08x ot=%d\n", pObj, kva, (uint32_t) (pObj->ob.oid >> 32), (uint32_t) (pObj->ob.oid), pObj->ob.allocCount, pObj->obType);}voiddb_pframe_cmd(db_expr_t, int, db_expr_t, char*){ int t; uint32_t frame; t = db_read_token(); if (t != tNUMBER) db_error("expects OID\n"); frame = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } ObjectHeader *pObj = ObjectCache::GetCorePageFrame(frame); if (pObj == 0) db_error("not in core\n"); kva_t kva = ObjectCache::ObHdrToPage(pObj); db_printf("Frame (hdr=0x%08x, data=0x%08x) 0x%08x%08x ac=0x%08x ot=%d\n", pObj, kva, (uint32_t) (pObj->ob.oid >> 32), (uint32_t) (pObj->ob.oid), pObj->ob.allocCount, pObj->obType);}voidpte_print(uint32_t addr, char *note, PTE *pte){ db_printf("0x%08x %s ", addr, note); pte->ddb_dump();}voiddb_show_mappings_cmd(db_expr_t addr, int have_addr, db_expr_t, char*){ PTE *space; uint32_t base, len, top; int t; t = db_read_token(); if (t != tNUMBER) db_error("expects space base nPage\n"); space = KPAtoP(PTE *, db_tok_number); t = db_read_token(); if (t != tNUMBER) db_error("expects space base nPage\n"); base = db_tok_number; t = db_read_token(); if (t != tNUMBER) db_error("expects space base nPage\n"); len = db_tok_number; t = db_read_token(); if (db_read_token() != tEOL) { db_error("?\n"); /*NOTREACHED*/ } if ((uint32_t)space & EROS_PAGE_MASK) db_error("base must be a page address\n"); top = base + (len * EROS_PAGE_SIZE); while (base < top) { uint32_t hi = (base >> 22) & 0x3ffu; uint32_t lo = (base >> 12) & 0x3ffu; PTE* pde = space + hi; pte_print(base, "PDE ", pde); if (PTE_ISNOT(*pde, PTE_V)) db_printf("0x%08x PTE <invalid>\n", base); else { PTE *pte = (PTE *) pde->PageFrame(); pte += lo; pte_print(base, "PTE ", pte); uint32_t frm = pte->PageFrame(); ObjectHeader *pHdr = ObjectCache::PhysPageToObHdr(frm); if (pHdr == 0) db_printf("*** NOT A VALID USER FRAME!\n"); else if (pHdr->obType != ObType::PtDataPage) db_printf("*** FRAME IS INVALID TYPE!\n"); } base += EROS_PAGE_SIZE; }}voiddb_print_segwalk(const SegWalk *wi){#define BOOLC(x) ((x) ? 'y' : 'n') db_printf("wi: vaddr 0x%08x segBlss %d segObj 0x%08x\n"#ifdef KT_Wrapper "segObjIsWrapper: %c offset: 0x%08x%08x\n"#else "segObjIsRed: %c offset: 0x%08x%08x\n"#endif "redSpanBlss %d redSegOffset 0x%08x%08x\n" "writeAccess: %c kprOK: %c canCall: %c\n" "canWrite: %c segFault %d traverseCount %d\n", wi->vaddr, wi->segBlss, wi->segObj,#ifdef KT_Wrapper BOOLC(wi->segObjIsWrapper),#else BOOLC(wi->segObjIsRed),#endif (uint32_t) (wi->offset >> 32), (uint32_t) (wi->offset), wi->redSpanBlss, (uint32_t) (wi->redSegOffset >> 32), (uint32_t) (wi->redSegOffset), BOOLC(wi->writeAccess), BOOLC(wi->invokeKeeperOK), BOOLC(wi->canCall), BOOLC(wi->canWrite), wi->faultCode, wi->traverseCount);#undef BOOLC} voiddb_show_walkinfo_cmd(db_expr_t addr, int have_addr, db_expr_t /* count */, char * /* modif */){ if (have_addr == 0) db_error("requires address\n"); db_print_segwalk((const SegWalk *) addr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -