2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de
3 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de
4 * Distributed under the terms of the MIT License.
6 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
10 #include "debug_builtin_commands.h"
19 #include "debug_commands.h"
24 cmd_reboot(int argc
, char **argv
)
26 arch_cpu_shutdown(true);
28 // I'll be really suprised if this line ever runs! ;-)
33 cmd_shutdown(int argc
, char **argv
)
35 arch_cpu_shutdown(false);
41 cmd_help(int argc
, char **argv
)
43 debugger_command
*command
, *specified
= NULL
;
44 const char *start
= NULL
;
45 int32 startLength
= 0;
49 specified
= find_debugger_command(argv
[1], false, ambiguous
);
50 if (specified
== NULL
) {
52 startLength
= strlen(start
);
56 if (specified
!= NULL
) {
57 // only print out the help of the specified command (and all of its aliases)
58 kprintf("debugger command for \"%s\" and aliases:\n", specified
->name
);
59 } else if (start
!= NULL
)
60 kprintf("debugger commands starting with \"%s\":\n", start
);
62 kprintf("debugger commands:\n");
64 for (command
= get_debugger_commands(); command
!= NULL
;
65 command
= command
->next
) {
66 if (specified
&& command
->func
!= specified
->func
)
68 if (start
!= NULL
&& strncmp(start
, command
->name
, startLength
))
71 kprintf(" %-20s\t\t%s\n", command
->name
, command
->description
? command
->description
: "-");
79 cmd_continue(int argc
, char **argv
)
86 cmd_expr(int argc
, char **argv
)
89 print_debugger_command_usage(argv
[0]);
94 if (evaluate_debug_expression(argv
[1], &result
, false)) {
95 kprintf("%" B_PRIu64
" (0x%" B_PRIx64
")\n", result
, result
);
96 set_debug_variable("_", result
);
104 cmd_error(int argc
, char **argv
)
107 print_debugger_command_usage(argv
[0]);
111 int32 error
= parse_expression(argv
[1]);
112 kprintf("error 0x%" B_PRIx32
": %s\n", error
, strerror(error
));
119 cmd_head(int argc
, char** argv
)
121 debugger_command_pipe_segment
* segment
122 = get_current_debugger_command_pipe_segment();
123 if (segment
== NULL
) {
124 kprintf_unfiltered("%s can only be run as part of a pipe!\n", argv
[0]);
125 return B_KDEBUG_ERROR
;
132 user_data
* userData
= (user_data
*)segment
->user_data
;
134 if (segment
->invocations
== 0) {
136 print_debugger_command_usage(argv
[0]);
137 return B_KDEBUG_ERROR
;
140 if (!evaluate_debug_expression(argv
[1], &userData
->max_lines
, false))
141 return B_KDEBUG_ERROR
;
145 if (++userData
->lines
<= userData
->max_lines
) {
155 cmd_tail(int argc
, char** argv
)
157 debugger_command_pipe_segment
* segment
158 = get_current_debugger_command_pipe_segment();
159 if (segment
== NULL
) {
160 kprintf_unfiltered("%s can only be run as part of a pipe!\n", argv
[0]);
161 return B_KDEBUG_ERROR
;
169 user_data
* userData
= (user_data
*)segment
->user_data
;
171 if (segment
->invocations
== 0) {
173 print_debugger_command_usage(argv
[0]);
174 return B_KDEBUG_ERROR
;
177 userData
->max_lines
= 10;
178 if (argc
> 2 && !evaluate_debug_expression(argv
[1],
179 &userData
->max_lines
, false)) {
180 return B_KDEBUG_ERROR
;
183 userData
->line_count
= 1;
184 userData
->restarted
= false;
185 } else if (!userData
->restarted
) {
186 if (argv
[argc
- 1] == NULL
) {
187 userData
->restarted
= true;
188 userData
->line_count
-= userData
->max_lines
;
189 return B_KDEBUG_RESTART_PIPE
;
192 ++userData
->line_count
;
194 if (argv
[argc
- 1] == NULL
)
197 if (--userData
->line_count
< 0) {
198 kputs(argv
[argc
- 1]);
208 cmd_grep(int argc
, char** argv
)
210 bool caseSensitive
= true;
211 bool inverseMatch
= false;
214 for (; argi
< argc
; argi
++) {
215 const char* arg
= argv
[argi
];
219 for (int32 i
= 1; arg
[i
] != '\0'; i
++) {
221 caseSensitive
= false;
222 } else if (arg
[i
] == 'v') {
225 print_debugger_command_usage(argv
[0]);
226 return B_KDEBUG_ERROR
;
231 if (argc
- argi
!= 2) {
232 print_debugger_command_usage(argv
[0]);
233 return B_KDEBUG_ERROR
;
236 const char* pattern
= argv
[argi
++];
237 const char* line
= argv
[argi
++];
241 match
= strstr(line
, pattern
) != NULL
;
244 int32 lineLen
= strlen(line
);
245 int32 patternLen
= strlen(pattern
);
246 for (int32 i
= 0; i
<= lineLen
- patternLen
; i
++) {
247 // This is rather slow, but should be OK for our purposes.
248 if (strncasecmp(line
+ i
, pattern
, patternLen
) == 0) {
255 if (match
!= inverseMatch
) {
265 cmd_wc(int argc
, char** argv
)
267 debugger_command_pipe_segment
* segment
268 = get_current_debugger_command_pipe_segment();
269 if (segment
== NULL
) {
270 kprintf_unfiltered("%s can only be run as part of a pipe!\n", argv
[0]);
271 return B_KDEBUG_ERROR
;
279 user_data
* userData
= (user_data
*)segment
->user_data
;
281 if (segment
->invocations
== 0) {
283 print_debugger_command_usage(argv
[0]);
284 return B_KDEBUG_ERROR
;
292 const char* line
= argv
[1];
294 // last run -- print results
295 kprintf("%10" B_PRIu64
" %10" B_PRIu64
" %10" B_PRIu64
"\n",
296 userData
->lines
, userData
->words
, userData
->chars
);
304 // count words and chars in this line
306 for (; *line
!= '\0'; line
++) {
308 if ((isspace(*line
) != 0) == inWord
) {
320 cmd_faults(int argc
, char** argv
)
323 print_debugger_command_usage(argv
[0]);
324 return B_KDEBUG_ERROR
;
328 gInvokeCommandDirectly
= parse_expression(argv
[1]) == 0;
330 kprintf("Fault handling is %s%s.\n", argc
== 2 ? "now " : "",
331 gInvokeCommandDirectly
? "off" : "on");
340 debug_builtin_commands_init()
342 add_debugger_command_etc("help", &cmd_help
, "List all debugger commands",
344 "Lists all debugger commands or those starting with \"name\".\n", 0);
345 add_debugger_command_etc("reboot", &cmd_reboot
, "Reboot the system",
347 "Reboots the system.\n", 0);
348 add_debugger_command_etc("shutdown", &cmd_shutdown
, "Shut down the system",
350 "Shuts down the system.\n", 0);
351 add_debugger_command_etc("gdb", &cmd_gdb
, "Connect to remote gdb",
353 "Connects to a remote gdb connected to the serial port.\n", 0);
354 add_debugger_command_etc("continue", &cmd_continue
, "Leave kernel debugger",
356 "Leaves kernel debugger.\n", 0);
357 add_debugger_command_alias("exit", "continue", "Same as \"continue\"");
358 add_debugger_command_alias("es", "continue", "Same as \"continue\"");
359 add_debugger_command_etc("expr", &cmd_expr
,
360 "Evaluates the given expression and prints the result",
362 "Evaluates the given expression and prints the result.\n",
363 B_KDEBUG_DONT_PARSE_ARGUMENTS
);
364 add_debugger_command_etc("error", &cmd_error
,
365 "Prints a human-readable description for an error code",
367 "Prints a human-readable description for the given numeric error\n"
369 " <error> - The numeric error code.\n", 0);
370 add_debugger_command_etc("faults", &cmd_faults
, "Toggles fault handling "
371 "for debugger commands",
373 "Toggles fault handling on (1) or off (0).\n", 0);
374 add_debugger_command_etc("head", &cmd_head
,
375 "Prints only the first lines of output from another command",
377 "Should be used in a command pipe. It prints only the first\n"
378 "<maxLines> lines of output from the previous command in the pipe and\n"
379 "silently discards the rest of the output.\n", 0);
380 add_debugger_command_etc("tail", &cmd_tail
,
381 "Prints only the last lines of output from another command",
383 "Should be used in a command pipe. It prints only the last\n"
384 "<maxLines> (default 10) lines of output from the previous command in\n"
385 "the pipe and silently discards the rest of the output.\n",
386 B_KDEBUG_PIPE_FINAL_RERUN
);
387 add_debugger_command_etc("grep", &cmd_grep
,
388 "Filters output from another command",
389 "[ -i ] [ -v ] <pattern>\n"
390 "Should be used in a command pipe. It filters all output from the\n"
391 "previous command in the pipe according to the given pattern.\n"
392 "When \"-v\" is specified, only those lines are printed that don't\n"
393 "match the given pattern, otherwise only those that do match. When\n"
394 "\"-i\" is specified, the pattern is matched case insensitive,\n"
395 "otherwise case sensitive.\n", 0);
396 add_debugger_command_etc("wc", &cmd_wc
,
397 "Counts the lines, words, and characters of another command's output",
399 "Should be used in a command pipe. It prints how many lines, words,\n"
400 "and characters the output of the previous command consists of.\n",
401 B_KDEBUG_PIPE_FINAL_RERUN
);