20 #include "pedigree/kernel/debugger/Debugger.h" 21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/Service.h" 23 #include "pedigree/kernel/ServiceFeatures.h" 24 #include "pedigree/kernel/ServiceManager.h" 25 #include "pedigree/kernel/debugger/DebuggerCommand.h" 26 #include "pedigree/kernel/debugger/DebuggerIO.h" 27 #include "pedigree/kernel/debugger/LocalIO.h" 28 #include "pedigree/kernel/debugger/SerialIO.h" 29 #include "pedigree/kernel/debugger/commands/AllocationCommand.h" 30 #include "pedigree/kernel/debugger/commands/Backtracer.h" 31 #include "pedigree/kernel/debugger/commands/BreakpointCommand.h" 32 #include "pedigree/kernel/debugger/commands/CpuInfoCommand.h" 33 #include "pedigree/kernel/debugger/commands/DevicesCommand.h" 34 #include "pedigree/kernel/debugger/commands/DisassembleCommand.h" 35 #include "pedigree/kernel/debugger/commands/DumpCommand.h" 36 #include "pedigree/kernel/debugger/commands/HelpCommand.h" 37 #include "pedigree/kernel/debugger/commands/IoCommand.h" 38 #include "pedigree/kernel/debugger/commands/LocksCommand.h" 39 #include "pedigree/kernel/debugger/commands/LogViewer.h" 40 #include "pedigree/kernel/debugger/commands/LookupCommand.h" 41 #include "pedigree/kernel/debugger/commands/MappingCommand.h" 42 #include "pedigree/kernel/debugger/commands/MemoryInspector.h" 43 #include "pedigree/kernel/debugger/commands/PanicCommand.h" 44 #include "pedigree/kernel/debugger/commands/QuitCommand.h" 45 #include "pedigree/kernel/debugger/commands/SlamCommand.h" 46 #include "pedigree/kernel/debugger/commands/StepCommand.h" 47 #include "pedigree/kernel/debugger/commands/SyscallTracerCommand.h" 48 #include "pedigree/kernel/debugger/commands/ThreadsCommand.h" 49 #include "pedigree/kernel/debugger/commands/TraceCommand.h" 50 #include "pedigree/kernel/graphics/GraphicsService.h" 51 #include "pedigree/kernel/machine/Display.h" 52 #include "pedigree/kernel/machine/Keyboard.h" 53 #include "pedigree/kernel/machine/Machine.h" 54 #include "pedigree/kernel/processor/InterruptManager.h" 55 #include "pedigree/kernel/processor/Processor.h" 56 #include "pedigree/kernel/processor/ProcessorInformation.h" 57 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 58 #include "pedigree/kernel/processor/state.h" 59 #include "pedigree/kernel/utilities/String.h" 60 #include "pedigree/kernel/utilities/utility.h" 69 static int getCommandMatchingPrefix(
72 for (
size_t i = start; i < nCmds; i++)
75 pCommands[i]->getString(), prefix, StringLength(prefix)))
89 size_t n = StringLength(pCommand->
getString());
90 MemoryCopy(pStr, pStr + n + 1, StringLength(pStr) - n);
103 Debugger::~Debugger()
110 if (!InterruptManager::instance().registerInterruptHandlerDebugger( 113 ERROR_NOLOCK(
"Debugger: breakpoint interrupt registration failed!");
116 ERROR_NOLOCK(
"Debugger: debug interrupt registration failed!");
123 #ifdef MULTIPROCESSOR 124 Machine::instance().stopAllOtherProcessors();
128 entry << Log::Notice <<
" << Flushing log content >>";
130 #if defined(VALGRIND) || defined(HAS_SANITIZERS) 133 static String graphicsService(
"graphics");
137 ByteSet(¶ms, 0,
sizeof(params));
138 params.wantTextMode =
false;
143 bool bSuccess =
false;
148 bSuccess = pService->
serve(
154 if (bSuccess && params.providerFound)
157 if (params.providerResult.pDisplay)
170 bool debugState = Machine::instance().
getKeyboard()->getDebugState();
175 #ifndef DONT_LOG_TO_SERIAL 176 static SerialIO serialIO(Machine::instance().getSerial(0));
177 serialIO.initialise();
184 if (Machine::instance()
188 Machine::instance().getVga(0), Machine::instance().getKeyboard());
189 #ifdef DONT_LOG_TO_SERIAL 190 pInterfaces[0] = &localIO;
193 pInterfaces[0] = &localIO;
194 pInterfaces[1] = &serialIO;
198 #ifndef DONT_LOG_TO_SERIAL 201 pInterfaces[0] = &serialIO;
209 ERROR_NOLOCK(
"This machine/CPU combination doesn't support any output " 210 "methods for the debugger!");
215 int nChosenInterface = -1;
243 size_t nCommands = 21;
245 size_t nCommands = 20;
265 &g_AllocationCommand,
281 for (
int i = 0; i < nInterfaces; i++)
283 pInterfaces[i]->disableCli();
285 "Press any key to enter the debugger...", 0, 0,
286 DebuggerIO::LightBlue, DebuggerIO::Black);
290 str, 2, 0, DebuggerIO::LightBlue, DebuggerIO::Black);
294 for (
int i = 0; i < nInterfaces; i++)
296 char c = pInterfaces[i]->getCharNonBlock();
297 if ((c >= 32 && static_cast<unsigned char>(c) <= 127) ||
298 c ==
'\n' || c == 0x08 || c ==
'\r' || c == 0x09)
300 pIo = pInterfaces[i];
301 nChosenInterface = i;
308 pIo = pInterfaces[n];
309 nChosenInterface = n;
311 pIo->readDimensions();
314 for (
int i = 0; i < nInterfaces; i++)
315 if (pIo != pInterfaces[i])
317 "Locked by another device.", 1, 0, DebuggerIO::LightRed,
321 pIo->setCliLowerLimit(1);
325 pIo->
writeCli(description, DebuggerIO::Yellow, DebuggerIO::Black);
328 description +=
"Kernel heap ends at ";
330 reinterpret_cast<uintptr_t>(
334 pIo->
writeCli(description, DebuggerIO::Yellow, DebuggerIO::Black);
337 bool bKeepGoing =
false;
345 bKeepGoing = trace.
execute(command, output, state, pIo);
349 trace.setInterface(nChosenInterface);
352 ' ', 0, 0, pIo->
getWidth() - 1, DebuggerIO::White,
355 ' ', pIo->getHeight() - 1, 0, pIo->
getWidth() - 1,
356 DebuggerIO::White, DebuggerIO::Green);
359 "Pedigree debugger", 0, 0, DebuggerIO::White, DebuggerIO::Green);
361 bool matchedCommand =
false;
368 if (pIo->
readCli(command, pAutoComplete))
375 matchedCommand =
false;
376 for (
size_t i = 0; i < nCommands; i++)
385 const_cast<char *>(static_cast<const char *>(command)),
388 str2 =
static_cast<const char *
>(pCommands[i]->
getString());
391 matchedCommand =
true;
401 (i = getCommandMatchingPrefix(
402 const_cast<char *>(static_cast<const char *>(command)),
403 pCommands, nCommands, i + 1)) != -1)
406 pAutoComplete = pCommands[i];
407 str +=
static_cast<const char *
>(pCommands[i]->
getString());
413 ' ', pIo->getHeight() - 1, 0, pIo->
getWidth() - 1,
414 DebuggerIO::White, DebuggerIO::Green);
416 str2, pIo->getHeight() - 1, 0, DebuggerIO::Yellow,
419 str, pIo->getHeight() - 1, str2.length(), DebuggerIO::White,
424 bool bValidCommand =
false;
425 for (
size_t i = 0; i < nCommands; i++)
428 const_cast<char *>(static_cast<const char *>(command)),
431 bKeepGoing = pCommands[i]->
execute(command, output, state, pIo);
432 pIo->
writeCli(output, DebuggerIO::LightGrey, DebuggerIO::Black);
433 bValidCommand =
true;
440 "Unrecognised command.\n", DebuggerIO::LightGrey,
445 }
while (bKeepGoing);
446 if (Machine::instance().getNumVga())
447 pInterfaces[0]->destroy();
448 #ifndef DONT_LOG_TO_SERIAL 459 if (interruptNumber ==
464 if (state.getRegister(0) == ASSERT_FAILED_SENTINEL)
468 const char *pDescription =
469 reinterpret_cast<const char *
>(state.getRegister(1));
470 description += pDescription;
474 description +=
"Breakpoint exception.";
476 start(state, description);
483 description =
"Debug/trap exception";
484 start(state, description);
virtual Keyboard * getKeyboard()=0
virtual size_t getWidth()=0
virtual void enableCli()=0
virtual void interrupt(size_t interruptNumber, InterruptState &state)
virtual void writeCli(const char *str, Colour foreColour, Colour backColour)
virtual bool readCli(HugeStaticString &str, DebuggerCommand *pAutoComplete)
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static ProcessorInformation & information()
virtual bool provides(Type service)
static void setSingleStep(bool bEnable, InterruptState &state)
virtual void setDebugState(bool enableDebugState)=0
void start(InterruptState &state, LargeStaticString &description)
virtual void setCliUpperLimit(size_t nlines)=0
void setPointers(Thread **ppThread, InterruptState *pState)
static Debugger m_Instance
virtual void drawString(const char *str, size_t row, size_t col, Colour foreColour, Colour backColour)=0
static EXPORTED_PUBLIC Log & instance()
Service * getService(const String &serviceName)
virtual const NormalStaticString getString()=0
virtual bool serve(ServiceFeatures::Type type, void *pData, size_t dataLen)=0
bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)
virtual void autocomplete(const HugeStaticString &input, HugeStaticString &output)=0
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
virtual bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)=0
virtual size_t getBreakpointInterruptNumber() PURE=0
virtual void drawHorizontalLine(char c, size_t row, size_t colStart, size_t colEnd, Colour foreColour, Colour backColour)=0
static InterruptManager & instance()
ServiceFeatures * enumerateOperations(const String &serviceName)
virtual bool setScreenMode(ScreenMode sm)