cmdtab.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*++
  2. Copyright (c) 2013 Minoca Corp. All Rights Reserved
  3. Module Name:
  4. cmdtab.c
  5. Abstract:
  6. This module defines the command table for the debugger.
  7. Author:
  8. Evan Green 11-Dec-2013
  9. Environment:
  10. Debug
  11. --*/
  12. //
  13. // ------------------------------------------------------------------- Includes
  14. //
  15. #include "dbgrtl.h"
  16. #include <minoca/debug/spproto.h>
  17. #include <minoca/lib/im.h>
  18. #include <minoca/debug/dbgext.h>
  19. #include "dbgapi.h"
  20. #include "symbols.h"
  21. #include "dbgrprof.h"
  22. #include "dbgrcomm.h"
  23. #include "extsp.h"
  24. #include <assert.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. //
  29. // ---------------------------------------------------------------- Definitions
  30. //
  31. #define DBG_DISPATCH_EXCEPTION_DESCRIPTION "Runs a debugger extension command."
  32. #define DBG_SWITCH_PROCESSOR_DESCRIPTION \
  33. "Switch to another processor (kernel mode) or thread (user mode)."
  34. #define DBGR_QUIT_DESCRIPTION "Exits the local debugger."
  35. #define DBGR_GET_SET_REGISTERS_DESCRIPTION "Get and set registers."
  36. #define DBGR_GET_SPECIAL_REGISTERS_DESCRIPTION "Get and set special registers."
  37. #define DBGR_GO_DESCRIPTION "Continue execution (go)."
  38. #define DBGR_RETURN_TO_CALLER_DESCRIPTION \
  39. "Continue to calling function (go up)."
  40. #define DBGR_STEP_INTO_DESCRIPTION "Step in."
  41. #define DBGR_STEP_OVER_DESCRIPTION "Step over."
  42. #define DBGR_SET_SOURCE_STEPPING_DESCRIPTION \
  43. "Enable or disable source line level stepping."
  44. #define DBGR_SOURCE_LINE_PRINTING_DESCRIPTION \
  45. "Enable or disable printing of file and line numbers with each address."
  46. #define DBGR_SOURCE_AT_ADDRESS_DESCRIPTION \
  47. "Display the source file and line number for the given address."
  48. #define DBGR_DISASSEMBLE_DESCRIPTION \
  49. "Disassemble instructions at the current or specified address."
  50. #define DBGR_PRINT_CALL_STACK_DESCRIPTION "Print the current call stack."
  51. #define DBGR_PRINT_CALL_STACK_NUMBERED_DESCRIPTION \
  52. "Print the current call stack with frame numbers."
  53. #define DBGR_SEARCH_SYMBOLS_DESCRIPTION "Search for a symbol by name."
  54. #define DBGR_DUMP_TYPE_DESCRIPTION "Dump information about a type."
  55. #define DBGR_DUMP_LIST_DESCRIPTION "Dump a doubly-linked list."
  56. #define DBGR_EVALUATE_DESCRIPTION "Evaluate a numeric or symbolic expression."
  57. #define DBGR_PRINT_LOCALS_DESCRIPTION "Dump local variables."
  58. #define DBGR_DUMP_BYTES_DESCRIPTION "Dump bytes (8-bit) from memory."
  59. #define DBGR_DUMP_CHARACTERS_DESCRIPTION "Dump characters (8-bit) from memory."
  60. #define DBGR_DUMP_WORDS_DESCRIPTION "Dump words (16-bit) from memory."
  61. #define DBGR_DUMP_DWORDS_DESCRIPTION "Dump double words (32-bit) from memory."
  62. #define DBGR_DUMP_QWORDS_DESCRIPTION "Dump quad words (64-bit) from memory."
  63. #define DBGR_EDIT_BYTES_DESCRIPTION "Edit bytes (8-bit) in memory."
  64. #define DBGR_EDIT_WORDS_DESCRIPTION "Edit words (16-bit) in memory."
  65. #define DBGR_EDIT_DWORDS_DESCRIPTION "Edit double-words (32-bit) in memory."
  66. #define DBGR_EDIT_QWORDS_DESCRIPTION "Edit quad-words (64-bit) in memory."
  67. #define DBGR_SET_FRAME_DESCRIPTION "Set the current call stack frame."
  68. #define DBGR_LIST_BREAKPOINTS_DESCRIPTION "List all breakpoints."
  69. #define DBGR_ENABLE_BREAKPOINT_DESCRIPTION "Enable a breakpoint by number."
  70. #define DBGR_DISABLE_BREAKPOINT_DESCRIPTION "Disable a breakpoint by number."
  71. #define DBGR_CREATE_BREAK_POINT_DESCRIPTION "Create a breakpoint."
  72. #define DBGR_DELETE_BREAK_POINT_DESCRIPTION \
  73. "Clear (delete) a breakpoint by number."
  74. #define DBGR_SET_SYMBOL_PATH_DESCRIPTION "Get or set the symbol search path."
  75. #define DBGR_APPEND_SYMBOL_PATH_DESCRIPTION \
  76. "Append a path to the symbol search path."
  77. #define DBGR_SET_SOURCE_PATH_DESCRIPTION "Get or set the source search path."
  78. #define DBGR_APPEND_SOURCE_PATH_DESCRIPTION \
  79. "Append a path to the source search path."
  80. #define DBGR_RELOAD_SYMBOLS_DESCRIPTION \
  81. "Reload all symbols from the symbol search path."
  82. #define DBGR_LOAD_EXTENSION_DESCRIPTION "Load a debugger extension."
  83. #define DBGR_UNLOAD_EXTENSION_DESCRIPTION \
  84. "Unload a debugger extension (use * to unload all)."
  85. #define DBGR_PRINT_PROCESSOR_BLOCK_DESCRIPTION \
  86. "Dump the current processor block (kernel mode)."
  87. #define DBGR_DUMP_POINTER_SYMBOLS_DESCRIPTION \
  88. "Dump any addresses found for memory at the given location."
  89. #define DBGR_PROFILE_DESCRIPTION \
  90. "Profiler commands."
  91. #define DBGR_REBOOT_DESCRIPTION "Forcefully reboot the target machine."
  92. #define DBGR_HELP_DESCRIPTION "Show this help text."
  93. #define DBGR_SERVER_DESCRIPTION \
  94. "Start a remote server so that others can connect to this session."
  95. //
  96. // ------------------------------------------------------ Data Type Definitions
  97. //
  98. //
  99. // ----------------------------------------------- Internal Function Prototypes
  100. //
  101. INT
  102. DbgrHelpCommand (
  103. PDEBUGGER_CONTEXT Context,
  104. PSTR *Arguments,
  105. ULONG ArgumentCount
  106. );
  107. //
  108. // -------------------------------------------------------------------- Globals
  109. //
  110. //
  111. // Define the command table, which is terminated with an entry of NULLs. The
  112. // first entry is always the extension command entry, and the second entry must
  113. // be the switch processor command.
  114. //
  115. DEBUGGER_COMMAND_ENTRY DbgrCommandTable[] = {
  116. {"!", DbgDispatchExtension, DBG_DISPATCH_EXCEPTION_DESCRIPTION},
  117. {"~", DbgrSwitchProcessor, DBG_SWITCH_PROCESSOR_DESCRIPTION},
  118. {"q", DbgrQuit, DBGR_QUIT_DESCRIPTION},
  119. {"r", DbgrGetSetRegisters, DBGR_GET_SET_REGISTERS_DESCRIPTION},
  120. {"rs", DbgrGetSetSpecialRegisters, DBGR_GET_SPECIAL_REGISTERS_DESCRIPTION},
  121. {"g", DbgrGo, DBGR_GO_DESCRIPTION},
  122. {"gu", DbgrReturnToCaller, DBGR_RETURN_TO_CALLER_DESCRIPTION},
  123. {"t", DbgrStep, DBGR_STEP_INTO_DESCRIPTION},
  124. {"p", DbgrStep, DBGR_STEP_OVER_DESCRIPTION},
  125. {"ss", DbgrSetSourceStepping, DBGR_SET_SOURCE_STEPPING_DESCRIPTION},
  126. {"sl", DbgrSetSourceLinePrinting, DBGR_SOURCE_LINE_PRINTING_DESCRIPTION},
  127. {"so", DbgrShowSourceAtAddressCommand, DBGR_SOURCE_AT_ADDRESS_DESCRIPTION},
  128. {"u", DbgrDisassemble, DBGR_DISASSEMBLE_DESCRIPTION},
  129. {"k", DbgrPrintCallStack, DBGR_PRINT_CALL_STACK_DESCRIPTION},
  130. {"kn", DbgrPrintCallStack, DBGR_PRINT_CALL_STACK_NUMBERED_DESCRIPTION},
  131. {"x", DbgrSearchSymbols, DBGR_SEARCH_SYMBOLS_DESCRIPTION},
  132. {"dt", DbgrDumpTypeCommand, DBGR_DUMP_TYPE_DESCRIPTION},
  133. {"dl", DbgrDumpList, DBGR_DUMP_LIST_DESCRIPTION},
  134. {"?", DbgrEvaluate, DBGR_EVALUATE_DESCRIPTION},
  135. {"dv", DbgrPrintLocals, DBGR_PRINT_LOCALS_DESCRIPTION},
  136. {"db", DbgrDumpMemory, DBGR_DUMP_BYTES_DESCRIPTION},
  137. {"dc", DbgrDumpMemory, DBGR_DUMP_CHARACTERS_DESCRIPTION},
  138. {"dw", DbgrDumpMemory, DBGR_DUMP_WORDS_DESCRIPTION},
  139. {"dd", DbgrDumpMemory, DBGR_DUMP_DWORDS_DESCRIPTION},
  140. {"dq", DbgrDumpMemory, DBGR_DUMP_QWORDS_DESCRIPTION},
  141. {"eb", DbgrEditMemory, DBGR_EDIT_BYTES_DESCRIPTION},
  142. {"ew", DbgrEditMemory, DBGR_EDIT_WORDS_DESCRIPTION},
  143. {"ed", DbgrEditMemory, DBGR_EDIT_DWORDS_DESCRIPTION},
  144. {"eq", DbgrEditMemory, DBGR_EDIT_QWORDS_DESCRIPTION},
  145. {"frame", DbgrSetFrame, DBGR_SET_FRAME_DESCRIPTION},
  146. {"bl", DbgrListBreakPoints, DBGR_LIST_BREAKPOINTS_DESCRIPTION},
  147. {"be", DbgrEnableBreakPoint, DBGR_ENABLE_BREAKPOINT_DESCRIPTION},
  148. {"bd", DbgrEnableBreakPoint, DBGR_DISABLE_BREAKPOINT_DESCRIPTION},
  149. {"bp", DbgrCreateBreakPoint, DBGR_CREATE_BREAK_POINT_DESCRIPTION},
  150. {"bc", DbgrDeleteBreakPoint, DBGR_DELETE_BREAK_POINT_DESCRIPTION},
  151. {"sympath", DbgrSetSymbolPathCommand, DBGR_SET_SYMBOL_PATH_DESCRIPTION},
  152. {"sympath+", DbgrSetSymbolPathCommand, DBGR_APPEND_SYMBOL_PATH_DESCRIPTION},
  153. {"srcpath", DbgrSetSourcePathCommand, DBGR_SET_SOURCE_PATH_DESCRIPTION},
  154. {"srcpath+", DbgrSetSourcePathCommand, DBGR_APPEND_SOURCE_PATH_DESCRIPTION},
  155. {"reload", DbgrReloadSymbols, DBGR_RELOAD_SYMBOLS_DESCRIPTION},
  156. {"load", DbgrLoadExtension, DBGR_LOAD_EXTENSION_DESCRIPTION},
  157. {"unload", DbgrLoadExtension, DBGR_UNLOAD_EXTENSION_DESCRIPTION},
  158. {"proc", DbgrPrintProcessorBlock, DBGR_PRINT_PROCESSOR_BLOCK_DESCRIPTION},
  159. {"dps", DbgrDumpPointerSymbols, DBGR_DUMP_POINTER_SYMBOLS_DESCRIPTION},
  160. {"profile", DbgrProfileCommand, DBGR_PROFILE_DESCRIPTION},
  161. {"reboot", DbgrRebootCommand, DBGR_REBOOT_DESCRIPTION},
  162. {"help", DbgrHelpCommand, DBGR_HELP_DESCRIPTION},
  163. {"server", DbgrServerCommand, DBGR_SERVER_DESCRIPTION},
  164. {NULL, NULL, NULL}
  165. };
  166. //
  167. // ------------------------------------------------------------------ Functions
  168. //
  169. PDEBUGGER_COMMAND_ENTRY
  170. DbgrLookupCommand (
  171. PSTR Command
  172. )
  173. /*++
  174. Routine Description:
  175. This routine attempts to find a debugger command entry.
  176. Arguments:
  177. Command - Supplies a pointer to the null-terminated string containing the
  178. name of the command that was invoked. This command is split on the
  179. period character, and the first segment is looked up.
  180. Return Value:
  181. Returns a pointer to the command entry on success.
  182. NULL if there no such command, or on failure.
  183. --*/
  184. {
  185. PSTR CommandCopy;
  186. ULONG CommandIndex;
  187. PDEBUGGER_COMMAND_ENTRY Entry;
  188. PSTR Period;
  189. CommandCopy = NULL;
  190. Period = strchr(Command, '.');
  191. if (Period != NULL) {
  192. CommandCopy = strdup(Command);
  193. if (CommandCopy == NULL) {
  194. return NULL;
  195. }
  196. Period = strchr(CommandCopy, '.');
  197. *Period = '\0';
  198. Command = CommandCopy;
  199. }
  200. //
  201. // The extension command is special as it's not delimited by a period.
  202. //
  203. if (*Command == '!') {
  204. Entry = &(DbgrCommandTable[0]);
  205. goto LookupCommandEnd;
  206. //
  207. // The switch processor command is also special as its format is ~N, where
  208. // N is a number argument.
  209. //
  210. } else if (*Command == '~') {
  211. Entry = &(DbgrCommandTable[1]);
  212. goto LookupCommandEnd;
  213. }
  214. //
  215. // Loop looking for a command that matches. Case is not important.
  216. //
  217. CommandIndex = 0;
  218. while (DbgrCommandTable[CommandIndex].Command != NULL) {
  219. Entry = &(DbgrCommandTable[CommandIndex]);
  220. if (strcasecmp(Command, Entry->Command) == 0) {
  221. goto LookupCommandEnd;
  222. }
  223. CommandIndex += 1;
  224. }
  225. Entry = NULL;
  226. LookupCommandEnd:
  227. if (CommandCopy != NULL) {
  228. free(CommandCopy);
  229. }
  230. return Entry;
  231. }
  232. //
  233. // --------------------------------------------------------- Internal Functions
  234. //
  235. INT
  236. DbgrHelpCommand (
  237. PDEBUGGER_CONTEXT Context,
  238. PSTR *Arguments,
  239. ULONG ArgumentCount
  240. )
  241. /*++
  242. Routine Description:
  243. This routine prints a description of all available commands.
  244. Arguments:
  245. Context - Supplies a pointer to the application context.
  246. Arguments - Supplies an array of strings containing the arguments. The
  247. first argument is the command itself.
  248. ArgumentCount - Supplies the count of arguments. This is always at least
  249. one.
  250. Return Value:
  251. 0 on success.
  252. Returns an error code on failure.
  253. --*/
  254. {
  255. ULONG CommandIndex;
  256. PDEBUGGER_COMMAND_ENTRY Entry;
  257. CommandIndex = 0;
  258. while (DbgrCommandTable[CommandIndex].Command != NULL) {
  259. Entry = &(DbgrCommandTable[CommandIndex]);
  260. DbgOut("%s -- %s\n", Entry->Command, Entry->HelpText);
  261. CommandIndex += 1;
  262. }
  263. return 0;
  264. }