📄 db_eros.cxx
字号:
/* * Copyright (C) 1998, 1999, 2001, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <arch-kerninc/db_machdep.hxx>#include <ddb/db_output.hxx>#include <ddb/db_lex.hxx>#include <ddb/db_command.hxx>#include <kerninc/Machine.hxx>#include <kerninc/Check.hxx>#include <kerninc/Invocation.hxx>#include <kerninc/Process.hxx>#include <kerninc/SegWalk.hxx>#include <kerninc/Thread.hxx>#include <kerninc/CpuReserve.hxx>#include <kerninc/util.h>#include <kerninc/KernStream.hxx>#include <kerninc/SymNames.hxx>#include <kerninc/IRQ.hxx>#include <kerninc/IoRequest.hxx>#include <kerninc/BlockDev.hxx>#include <kerninc/SysTimer.hxx>#include <kerninc/ObjectCache.hxx>#include <kerninc/Depend.hxx>#include <kerninc/ObjectSource.hxx>#include <kerninc/PhysMem.hxx>#include <eros/SysTraceKey.h>#include <eros/Reserve.h>#include <eros/Invoke.h>#include <ddb/db_sym.hxx>#include <ddb/db_output.hxx>#include <arch-kerninc/PTE.hxx>voiddb_eros_print_key(Key& key){ uint32_t *pWKey = (uint32_t *) &key; if ( key.IsPreparedObjectKey() ) { ObjectHeader * pObj = key.GetObjectPtr(); uint32_t oidlo = (uint32_t) pObj->ob.oid; uint32_t oidhi = (uint32_t) (pObj->ob.oid >> 32); if (key.IsType(KT_Resume)) db_printf("rsum 0x%08x 0x%08x 0x%08x%08x (obj=0x%08x ctxt=0x%08x)\n", pWKey[0], ((Node *)pObj)->callCount, oidhi, oidlo, pObj, key.gk.pContext); else if (key.IsType(KT_Start)) db_printf("strt 0x%08x 0x%08x 0x%08x%08x (obj=0x%08x ctxt=0x%08x)\n", pWKey[0], ((Node *)pObj)->callCount, oidhi, oidlo, pObj, key.gk.pContext); else if (key.IsObjectKey()) db_printf("pobj 0x%08x 0x%08x 0x%08x%08x (obj=0x%08x)\n", pWKey[0], pObj->ob.allocCount, oidhi, oidlo, pObj); else db_printf("pkt 0x%08x 0x%08x 0x%08x 0x%08x\n", pWKey[0], pWKey[1], pWKey[2], pWKey[3]); } else if (key.IsObjectKey()) { db_printf("uobj 0x%08x cnt=%u 0x%016X\n", pWKey[0], key.unprep.count, key.unprep.oid); } else if (key.IsVoidKey()) { db_printf("void\n"); } else db_printf("ukt type=%d 0x%08x 0x%08x 0x%08x 0x%08x\n", key.GetType(), pWKey[0], pWKey[1], pWKey[2], pWKey[3]);}#define __EROS_PRIMARY_KEYDEF(name) #name,static const char *keyNames[] = {#include <eros/StdKeyType.h>};voiddb_eros_print_key_details(Key& key){ uint32_t *pWKey = (uint32_t *) &key; db_printf("Key (0x%08x) (KT_%s) keydata=0x%x flags=", pWKey, keyNames[key.GetType()], key.keyData); if (key.IsPrepared() || key.IsHazard()) { db_printf("("); if (key.IsRdHazard()) db_printf("rdhz"); if (key.IsWrHazard()) { if (key.IsRdHazard()) db_printf(", "); db_printf("wrhz"); } if (key.IsPrepared()) { if (key.IsHazard()) db_printf(", "); db_printf("prepared"); } db_printf(")"); } db_printf("\n"); if (key.IsObjectKey()) { OID oid; ObCount count; if (key.IsUnprepared()) { oid = key.unprep.oid; count = key.unprep.count; } else if (key.IsType(KT_Resume)) { oid = key.gk.pContext->procRoot->ob.oid; count = key.gk.pContext->procRoot->callCount; } else if (key.IsType(KT_Start)) { oid = key.gk.pContext->procRoot->ob.oid; count = key.gk.pContext->procRoot->ob.allocCount; } else { oid = key.GetKeyOid(); count = key.GetAllocCount(); } db_printf("oid=0x%08x%08x, count=%d", (unsigned long)(oid >> 32), (unsigned long)(oid), count); if (key.IsSegModeType()) { if (key.IsReadOnly()) db_printf(" ro"); if (key.IsWeak()) db_printf(" wk"); if (key.IsNoCall()) db_printf(" nc"); db_printf(" blss=%d", key.GetBlss()); } db_printf("\n"); } else if (key.IsType(KT_Range) || key.IsType(KT_PrimeRange) || key.IsType(KT_PhysRange)) { OID start = key.rk.oid; OID end = key.rk.oid + inv.key->rk.count; db_printf("oid=[0x%08x%08x, 0x%08x%08x)\n", (unsigned long)(start >> 32), (unsigned long)(start), (unsigned long)(end >> 32), (unsigned long)(end)); } else if (key.IsType(KT_Number)) { db_printf("0x%08x%08x%08x\n", key.nk.value[2], key.nk.value[1], key.nk.value[0]); } else if (key.IsVoidKey()) { } else { db_printf("0x%08x 0x%08x 0x%08x\n", key.nk.value[0], key.nk.value[1], key.nk.value[2]); }}voiddb_eros_print_node(Node *pNode){ db_printf("Node (0x%08x) 0x%08x%08x ac=0x%08x cc=0x%08x ot=%d\n", pNode, (uint32_t) (pNode->ob.oid >> 32), (uint32_t) (pNode->ob.oid), pNode->ob.allocCount, pNode->callCount, pNode->obType);#if !defined(NDEBUG) && 0 if (pNode->Validate() == false) db_error("...Is not valid\n");#endif bool wasPrepared = ((pNode->obType == ObType::NtProcessRoot || pNode->obType == ObType::NtKeyRegs) && pNode->context); bool isRoot = (pNode->obType == ObType::NtProcessRoot && pNode->context); if (isRoot) { for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) { if (pNode->slot[i].IsRdHazard()) ((Process *) pNode->context)->FlushProcessSlot(i); } } bool isKeyRegs = (pNode->obType == ObType::NtKeyRegs && pNode->context); if (isKeyRegs) { for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) { if (pNode->slot[i].IsRdHazard()) ((Process *) pNode->context)->WriteBackKeySlot(i); } } for (uint32_t i = 0; i < EROS_NODE_SIZE; i++) { Key& key = (*pNode)[i]; db_printf(" [%02d] (0x%08x) ", i, &key); db_eros_print_key(key); } if (wasPrepared) pNode->context->Prepare();}voiddb_eros_print_string(uint8_t *data, uint32_t len){ if ( len > 20) len = 20; for (uint32_t i = 0; i < len; i++) { uint8_t c = data[i]; if (KernStream::IsPrint(c) || c == '\n') db_printf("%c", c); else db_printf("\\x%02x", c); }}voiddb_eros_print_number_as_string(Key& k){ unsigned ndx; uint8_t theName[12]; for (ndx = 0; ndx < 12; ndx++) theName[ndx] = k.nk.value[ndx / 4] >> (8 * (ndx % 4)); db_eros_print_string(theName, 12);}voiddb_eros_print_context(Process *cc){ if (cc == 0) db_printf("invokee=0x%08x\n", cc); else { db_printf("ctxt=0x%08x (%s)", cc, cc->Name()); db_printf(" (%s) ", ((cc->runState == RS_Running) ? "Running" : ((cc->runState == RS_Waiting) ? "Waiting" : "Avail"))); if (cc->isUserContext) { uint32_t oidhi = (uint32_t) (cc->procRoot->ob.oid >> 32); uint32_t oidlo = (uint32_t) cc->procRoot->ob.oid; db_printf("domain root=0x%08x", cc->procRoot); db_printf(" oid=0x%08x%08x\n", oidhi, oidlo); } db_printf(" Fault Code=0x%08x Fault Info = 0x%08x procFlags=0x%02x\n" " haz=0x%x rsrv=0x%08x", cc->faultCode, cc->faultInfo, cc->processFlags, cc->hazards, cc->cpuReserve);#ifdef OPTION_SMALL_SPACES db_printf(" smallPTE=0x%08x bias=0x%08x lim=0x%08x\n", cc->smallPTE, cc->bias, cc->limit);#else db_printf("\n");#endif if (cc->procRoot->slot[ProcSymSpace].IsType(KT_Number)) { db_printf("Procname: "); db_eros_print_number_as_string(cc->procRoot->slot[ProcSymSpace]); db_printf("\n"); } cc->DumpFixRegs(); }}voiddb_show_savearea_cmd(db_expr_t addr, int have_addr, db_expr_t /* count */, char * /* modif */){ extern void DumpFixRegs(const fixregs_t *fx); if (have_addr == 0) db_error("requires address\n"); DumpFixRegs((const fixregs_t *) addr);}voiddb_show_sizes_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ db_printf("sizeof(ObjectHeader) = 0x%x (%d)\n", sizeof(ObjectHeader), sizeof(ObjectHeader)); db_printf("sizeof(Node) = 0x%x (%d)\n", sizeof(Node), sizeof(Node)); db_printf("sizeof(Process) = 0x%x (%d)\n", sizeof(Process), sizeof(Process));}extern "C" { extern uint32_t InterruptStackTop; extern uint32_t InterruptStackBottom;}voiddb_eros_print_context_keyring(Process *cc){ Key *kr = (Key*) &cc->kr; Key *k = (Key *) kr->gk.next; while (k != kr) { if ( ( (uint32_t) k >= (uint32_t) &InterruptStackBottom ) && ( (uint32_t) k < (uint32_t) &InterruptStackTop ) ) db_printf("*** next key is on kernel stack:\n"); db_printf("(0x%08x): ", k); db_eros_print_key(*k); k = (Key *) k->gk.next; }}voiddb_eros_print_context_keyregs(Process *cc){ if (cc == 0) { db_printf("invokee=0x%08x\n", cc); return; } for (unsigned int i = 0; i < EROS_NODE_SIZE; i++) { db_printf("[%02d] (0x%08x)", i, &cc->keyReg[i]); db_eros_print_key(cc->keyReg[i]); }}voiddb_eros_print_thread(Thread *t){ uint32_t ndx = t - Thread::ThreadTable; db_printf("thread 0x%08x:\n", t); OID oid = 0; char isGoodOid = '?'; if ( t->IsUser() ) { if (t->context) { oid = ((Process *) (t->context))->procRoot->ob.oid; isGoodOid = 'u'; } else if (t->processKey.IsObjectKey()) { oid = t->processKey.GetKeyOid(); isGoodOid = 'u'; } } else isGoodOid = 'k'; if (t->IsUser()) db_printf("[%4d] ", ndx); else db_printf("[kern] ", ndx); db_printf("0x%08x %c %s ctxt=0x%08x dr=%c0x%08x%08x\n" " q=0x%08x lnkd? %c wake=0x%08x%08x shouldwake? %c\n" " reserve=0x%08x curPrio %d shouldYield? %c canYield? %c\n", t, t->IsUser() ? 'u' : 'k', Thread::stateNames[t->state], t->context, isGoodOid, (uint32_t) (oid>>32), (uint32_t) oid, t->lastq, t->prev ? 'y' : 'n', (uint32_t) (t->wakeTime >> 32), (uint32_t) t->wakeTime, t->wakeTime <= SysTimer::Now() ? 'y' : 'n', t->cpuReserve, t->cpuReserve->curPrio, t->ShouldYield() ? 'y' : 'n', t->CAN_PREEMPT() ? 'y' : 'n');}#ifdef DBG_WILD_PTRunsigned dbg_wild_ptr = true;voiddb_eros_dbg_wild_n_cmd(db_expr_t, int, db_expr_t, char*){ dbg_wild_ptr = false;}voiddb_eros_dbg_wild_y_cmd(db_expr_t, int, db_expr_t, char*){ dbg_wild_ptr = true;}#endif#ifndef NDEBUGunsigned dbg_inttrap = false;voiddb_eros_dbg_inttrap_n_cmd(db_expr_t, int, db_expr_t, char*){ dbg_inttrap = false;}voiddb_eros_dbg_inttrap_y_cmd(db_expr_t, int, db_expr_t, char*){ dbg_inttrap = true;}#endifbool ddb_thread_uqueue_debug = false;voiddb_eros_mesg_uqueue_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_thread_uqueue_debug) { ddb_thread_uqueue_debug = false; db_printf("ddb will NOT stop on user thread queueing\n"); } else { ddb_thread_uqueue_debug = true; db_printf("ddb will stop on user thread queueing\n"); }}bool ddb_segwalk_debug = false;voiddb_eros_mesg_segwalk_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_segwalk_debug) { ddb_segwalk_debug = false; db_printf("ddb will NOT stop in segment traversal\n"); } else { ddb_segwalk_debug = true; db_printf("ddb will stop in segment traversal\n"); }}bool ddb_uyield_debug = false;voiddb_eros_mesg_uyield_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_uyield_debug) { ddb_uyield_debug = false; db_printf("ddb will NOT stop on user thread yield\n"); } else { ddb_uyield_debug = true; db_printf("ddb will stop on user thread yield\n"); }}voiddb_eros_mesg_gate_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_inv_flags & DDB_INV_gate) { ddb_inv_flags &= ~DDB_INV_gate; db_printf("ddb will NOT stop on gate key invocations\n"); } else { ddb_inv_flags |= DDB_INV_gate; db_printf("ddb will stop on gate key invocations\n"); }}voiddb_eros_mesg_return_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_inv_flags & DDB_INV_return) { ddb_inv_flags &= ~DDB_INV_return; db_printf("ddb will NOT stop on return invocations\n"); } else { ddb_inv_flags |= DDB_INV_return; db_printf("ddb will stop on return invocations\n"); }}voiddb_eros_mesg_allinv_cmd(db_expr_t /* addr */, int /* have_addr */, db_expr_t /* count */, char * /* modif */){ if (ddb_inv_flags & DDB_INV_all) { ddb_inv_flags &= ~DDB_INV_all; db_printf("ddb will NOT stop on all invocations\n"); } else { ddb_inv_flags |= DDB_INV_all; db_printf("ddb will stop on all invocations\n"); }}voiddb_eros_mesg_procinv_cmd(db_expr_t addr, int have_addr, db_expr_t /* count */, char * /* modif */){ Process *cc = have_addr ? (Process *) addr : (Process*) Thread::CurContext(); if (cc->processFlags & PF_DDBINV) { cc->processFlags &= ~PF_DDBINV; db_printf("Invocation traps for context 0x%08x (OID 0x%08x%08x) disabled\n", cc, (uint32_t) (cc->procRoot->ob.oid >> 32), (uint32_t) (cc->procRoot->ob.oid)); } else { cc->processFlags |= PF_DDBINV; db_printf("Invocation traps for context 0x%08x (OID 0x%08x%08x) enabled\n", cc, (uint32_t) (cc->procRoot->ob.oid >> 32), (uint32_t) (cc->procRoot->ob.oid)); /* Once set, this is forever: */ ddb_inv_flags |= DDB_INV_pflag; }}voiddb_eros_mesg_proctrap_cmd(db_expr_t addr, int have_addr, db_expr_t /* count */, char * /* modif */){ Process *cc = have_addr ? (Process *) addr : (Process*) Thread::CurContext();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -