* Implemented colorized output.
* Implemented finding programs in the PATH. * Added human readable error codes for status_t and ssize_t return values. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11448 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -62,6 +62,13 @@ static const char *kUsage =
|
|||||||
" ID."
|
" ID."
|
||||||
;
|
;
|
||||||
|
|
||||||
|
// terminal color escape sequences
|
||||||
|
// (http://www.dee.ufcg.edu.br/~rrbrandt/tools/ansi.html)
|
||||||
|
static const char *kTerminalTextNormal = "\33[0m";
|
||||||
|
static const char *kTerminalTextRed = "\33[31m";
|
||||||
|
static const char *kTerminalTextMagenta = "\33[35m";
|
||||||
|
|
||||||
|
|
||||||
// command line args
|
// command line args
|
||||||
static int sArgc;
|
static int sArgc;
|
||||||
static const char *const *sArgv;
|
static const char *const *sArgv;
|
||||||
@@ -108,15 +115,74 @@ get_id(const char *str, int32 &id)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find_program
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
find_program(const char *programName, string &resolvedPath)
|
||||||
|
{
|
||||||
|
// If the program name is absolute, then there's nothing to do.
|
||||||
|
// If the program name consists of more than one path element, then we
|
||||||
|
// consider it a relative path and don't search in PATH either.
|
||||||
|
if (*programName == '/' || strchr(programName, '/')) {
|
||||||
|
resolvedPath = programName;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the PATH environment variable
|
||||||
|
const char *paths = getenv("PATH");
|
||||||
|
if (!paths)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
// iterate through the paths
|
||||||
|
do {
|
||||||
|
const char *pathEnd = strchr(paths, ':');
|
||||||
|
int pathLen = (pathEnd ? pathEnd - paths : strlen(paths));
|
||||||
|
|
||||||
|
// We skip empty paths.
|
||||||
|
if (pathLen > 0) {
|
||||||
|
// get the program path
|
||||||
|
string path(paths, pathLen);
|
||||||
|
path += "/";
|
||||||
|
path += programName;
|
||||||
|
|
||||||
|
// stat() the path to be sure, there is a file
|
||||||
|
struct stat st;
|
||||||
|
if (stat(path.c_str(), &st) == 0 && S_ISREG(st.st_mode)) {
|
||||||
|
resolvedPath = path;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paths = (pathEnd ? pathEnd + 1 : NULL);
|
||||||
|
} while (paths);
|
||||||
|
|
||||||
|
// not found in PATH
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
// load_program
|
// load_program
|
||||||
thread_id
|
thread_id
|
||||||
load_program(const char *const *args, int32 argCount)
|
load_program(const char *const *args, int32 argCount)
|
||||||
{
|
{
|
||||||
// TODO: We need to find the program in the PATH, if no absolute or relative
|
// clone the argument vector so that we can change it
|
||||||
// path has been given (i.e. only a name).
|
const char **mutableArgs = new const char*[argCount];
|
||||||
return load_image(argCount, (const char**)args, (const char**)environ);
|
for (int i = 0; i < argCount; i++)
|
||||||
}
|
mutableArgs[i] = args[i];
|
||||||
|
|
||||||
|
// resolve the program path
|
||||||
|
string programPath;
|
||||||
|
status_t error = find_program(args[0], programPath);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
mutableArgs[0] = programPath.c_str();
|
||||||
|
|
||||||
|
// load the program
|
||||||
|
error = load_image(argCount, mutableArgs, (const char**)environ);
|
||||||
|
|
||||||
|
delete[] mutableArgs;
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// set_team_debugging_flags
|
// set_team_debugging_flags
|
||||||
static
|
static
|
||||||
@@ -258,12 +324,16 @@ print_syscall(debug_post_syscall &message, MemoryReader &memoryReader,
|
|||||||
bool printArguments, bool getContents, bool printReturnValue,
|
bool printArguments, bool getContents, bool printReturnValue,
|
||||||
bool colorize)
|
bool colorize)
|
||||||
{
|
{
|
||||||
// TODO: colorize support
|
|
||||||
int32 syscallNumber = message.syscall;
|
int32 syscallNumber = message.syscall;
|
||||||
Syscall *syscall = sSyscallVector[syscallNumber];
|
Syscall *syscall = sSyscallVector[syscallNumber];
|
||||||
|
|
||||||
// print syscall name
|
// print syscall name
|
||||||
printf("[%6ld] %s(", message.thread, syscall->Name().c_str());
|
if (colorize) {
|
||||||
|
printf("[%6ld] %s%s%s(", message.thread, kTerminalTextRed,
|
||||||
|
syscall->Name().c_str(), kTerminalTextNormal);
|
||||||
|
} else {
|
||||||
|
printf("[%6ld] %s(", message.thread, syscall->Name().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
// print arguments
|
// print arguments
|
||||||
if (printArguments) {
|
if (printArguments) {
|
||||||
@@ -284,15 +354,29 @@ print_syscall(debug_post_syscall &message, MemoryReader &memoryReader,
|
|||||||
|
|
||||||
// print return value
|
// print return value
|
||||||
if (printReturnValue) {
|
if (printReturnValue) {
|
||||||
TypeHandler *handler = syscall->ReturnType()->Handler();
|
Type *returnType = syscall->ReturnType();
|
||||||
|
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());
|
printf(" = %s", value.c_str());
|
||||||
// TODO: If the return value is a status_t, print the error code.
|
|
||||||
|
// if the return type is status_t or ssize_t, print human-readable
|
||||||
|
// error codes
|
||||||
|
if (returnType->TypeName() == "status_t"
|
||||||
|
|| returnType->TypeName() == "ssize_t"
|
||||||
|
&& message.return_value < 0) {
|
||||||
|
printf(" %s", strerror(message.return_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf(" (%lld us)\n", message.end_time - message.start_time);
|
if (colorize) {
|
||||||
|
printf(" %s(%lld us)%s\n", kTerminalTextMagenta,
|
||||||
|
message.end_time - message.start_time, kTerminalTextNormal);
|
||||||
|
} else {
|
||||||
|
printf(" (%lld us)\n", message.end_time - message.start_time);
|
||||||
|
}
|
||||||
|
|
||||||
//for (int32 i = 0; i < 16; i++) {
|
//for (int32 i = 0; i < 16; i++) {
|
||||||
// if (i % 4 == 0) {
|
// if (i % 4 == 0) {
|
||||||
@@ -360,6 +444,9 @@ main(int argc, const char *const *argv)
|
|||||||
// initialize our syscalls vector and map
|
// initialize our syscalls vector and map
|
||||||
init_syscalls();
|
init_syscalls();
|
||||||
|
|
||||||
|
// don't colorize the output, if we don't have a terminal
|
||||||
|
colorize = colorize && isatty(STDOUT_FILENO);
|
||||||
|
|
||||||
// get thread/team to be debugged
|
// get thread/team to be debugged
|
||||||
thread_id thread = -1;
|
thread_id thread = -1;
|
||||||
team_id team = -1;
|
team_id team = -1;
|
||||||
|
|||||||
Reference in New Issue
Block a user