Added two output options: -o redirects output to the specified file,

-S will dump over the serial line (kernel debug output).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11948 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-03-22 02:20:41 +00:00
parent 3f484ea41a
commit 5680579795
+75 -16
View File
@@ -7,6 +7,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <errno.h>
#include <map> #include <map>
#include <string> #include <string>
@@ -63,6 +64,8 @@ static const char *kUsage =
" -T - Trace all threads of the supplied or loaded executable's\n" " -T - Trace all threads of the supplied or loaded executable's\n"
" team. If an ID is supplied, it is interpreted as a team\n" " team. If an ID is supplied, it is interpreted as a team\n"
" ID.\n" " ID.\n"
" -o <file> - directs output into the specified file.\n"
" -S - prints output to serial debug line.\n"
; ;
// terminal color escape sequences // terminal color escape sequences
@@ -298,22 +301,40 @@ init_syscalls()
} }
} }
// print_to_string
static
void
print_to_string(char **_buffer, int32 *_length, const char *format, ...)
{
va_list list;
va_start(list, format);
ssize_t length = vsnprintf(*_buffer, *_length, format, list);
va_end(list);
*_buffer += length;
*_length -= length;
}
// print_syscall // print_syscall
static static
void void
print_syscall(debug_post_syscall &message, MemoryReader &memoryReader, print_syscall(FILE *outputFile, debug_post_syscall &message,
bool printArguments, bool getContents, bool printReturnValue, MemoryReader &memoryReader, bool printArguments, bool getContents,
bool colorize) bool printReturnValue, bool colorize)
{ {
char buffer[4096], *string = buffer;
int32 length = (int32)sizeof(buffer);
int32 syscallNumber = message.syscall; int32 syscallNumber = message.syscall;
Syscall *syscall = sSyscallVector[syscallNumber]; Syscall *syscall = sSyscallVector[syscallNumber];
// print syscall name // print syscall name
if (colorize) { if (colorize) {
printf("[%6ld] %s%s%s(", message.origin.thread, kTerminalTextRed, print_to_string(&string, &length, "[%6ld] %s%s%s(",
syscall->Name().c_str(), kTerminalTextNormal); message.origin.thread, kTerminalTextRed, syscall->Name().c_str(),
kTerminalTextNormal);
} else { } else {
printf("[%6ld] %s(", message.origin.thread, syscall->Name().c_str()); print_to_string(&string, &length, "[%6ld] %s(",
message.origin.thread, syscall->Name().c_str());
} }
// print arguments // print arguments
@@ -323,40 +344,42 @@ print_syscall(debug_post_syscall &message, MemoryReader &memoryReader,
// get the value // get the value
Parameter *parameter = syscall->ParameterAt(i); Parameter *parameter = syscall->ParameterAt(i);
TypeHandler *handler = parameter->Handler(); TypeHandler *handler = parameter->Handler();
string value = handler->GetParameterValue( ::string value = handler->GetParameterValue(
(char*)message.args + parameter->Offset(), getContents, (char*)message.args + parameter->Offset(), getContents,
memoryReader); memoryReader);
printf((i > 0 ? ", %s" : "%s"), value.c_str()); print_to_string(&string, &length, (i > 0 ? ", %s" : "%s"),
value.c_str());
} }
} }
printf(")"); print_to_string(&string, &length, ")");
// print return value // print return value
if (printReturnValue) { if (printReturnValue) {
Type *returnType = syscall->ReturnType(); Type *returnType = syscall->ReturnType();
TypeHandler *handler = returnType->Handler(); TypeHandler *handler = returnType->Handler();
string value = handler->GetReturnValue(message.return_value, ::string value = handler->GetReturnValue(message.return_value,
getContents, memoryReader); getContents, memoryReader);
if (value.length() > 0) { if (value.length() > 0) {
printf(" = %s", value.c_str()); print_to_string(&string, &length, " = %s", value.c_str());
// if the return type is status_t or ssize_t, print human-readable // if the return type is status_t or ssize_t, print human-readable
// error codes // error codes
if (returnType->TypeName() == "status_t" if (returnType->TypeName() == "status_t"
|| returnType->TypeName() == "ssize_t" || returnType->TypeName() == "ssize_t"
&& message.return_value < 0) { && message.return_value < 0) {
printf(" %s", strerror(message.return_value)); print_to_string(&string, &length, " %s", strerror(message.return_value));
} }
} }
} }
if (colorize) { if (colorize) {
printf(" %s(%lld us)%s\n", kTerminalTextMagenta, print_to_string(&string, &length, " %s(%lld us)%s\n", kTerminalTextMagenta,
message.end_time - message.start_time, kTerminalTextNormal); message.end_time - message.start_time, kTerminalTextNormal);
} else { } else {
printf(" (%lld us)\n", message.end_time - message.start_time); print_to_string(&string, &length, " (%lld us)\n",
message.end_time - message.start_time);
} }
//for (int32 i = 0; i < 16; i++) { //for (int32 i = 0; i < 16; i++) {
@@ -370,6 +393,11 @@ print_syscall(debug_post_syscall &message, MemoryReader &memoryReader,
//} //}
//printf("\n"); //printf("\n");
// output either to file or serial debug line
if (outputFile != NULL)
fwrite(buffer, sizeof(buffer) - length, 1, outputFile);
else
_kern_debug_output(buffer);
} }
@@ -390,11 +418,14 @@ main(int argc, const char *const *argv)
bool printReturnValues = true; bool printReturnValues = true;
bool traceChildThreads = false; bool traceChildThreads = false;
bool traceTeam = false; bool traceTeam = false;
bool serialOutput = false;
FILE *outputFile = stdout;
// parse arguments // parse arguments
for (int argi = 1; argi < argc; argi++) { for (int argi = 1; argi < argc; argi++) {
const char *arg = argv[argi]; const char *arg = argv[argi];
if (arg[0] == '-') { if (arg[0] == '-') {
// ToDo: improve option parsing so that ie. "-rsf" would also work
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
print_usage_and_exit(false); print_usage_and_exit(false);
} else if (strcmp(arg, "-a") == 0) { } else if (strcmp(arg, "-a") == 0) {
@@ -411,6 +442,28 @@ main(int argc, const char *const *argv)
traceChildThreads = true; traceChildThreads = true;
} else if (strcmp(arg, "-T") == 0) { } else if (strcmp(arg, "-T") == 0) {
traceTeam = true; traceTeam = true;
} else if (strcmp(arg, "-S") == 0) {
serialOutput = true;
outputFile = NULL;
} else if (strncmp(arg, "-o", 2) == 0) {
// read filename
const char *filename = NULL;
if (arg[2] == '=') {
// name follows
filename = arg + 3;
} else if (arg[2] == '\0'
&& argi + 1 < argc && argv[argi + 1][0] != '-') {
// next arg is name
filename = argv[++argi];
} else
print_usage_and_exit(true);
outputFile = fopen(filename, "w+");
if (outputFile == NULL) {
fprintf(stderr, "Could not open `%s': %s\n", filename,
strerror(errno));
exit(1);
}
} else { } else {
print_usage_and_exit(true); print_usage_and_exit(true);
} }
@@ -429,7 +482,10 @@ main(int argc, const char *const *argv)
init_syscalls(); init_syscalls();
// don't colorize the output, if we don't have a terminal // don't colorize the output, if we don't have a terminal
colorize = colorize && isatty(STDOUT_FILENO); if (outputFile == stdout)
colorize = colorize && isatty(STDOUT_FILENO);
else if (outputFile)
colorize = false;
// get thread/team to be debugged // get thread/team to be debugged
thread_id thread = -1; thread_id thread = -1;
@@ -512,7 +568,7 @@ main(int argc, const char *const *argv)
switch (code) { switch (code) {
case B_DEBUGGER_MESSAGE_POST_SYSCALL: case B_DEBUGGER_MESSAGE_POST_SYSCALL:
{ {
print_syscall(message.post_syscall, memoryReader, print_syscall(outputFile, message.post_syscall, memoryReader,
printArguments, !fastMode, printReturnValues, colorize); printArguments, !fastMode, printReturnValues, colorize);
break; break;
@@ -544,5 +600,8 @@ main(int argc, const char *const *argv)
continue_thread(message.origin.nub_port, message.origin.thread); continue_thread(message.origin.nub_port, message.origin.thread);
} }
if (outputFile != NULL && outputFile != stdout)
fclose(outputFile);
return 0; return 0;
} }