diff --git a/src/bin/debug/strace/TypeHandler.cpp b/src/bin/debug/strace/TypeHandler.cpp index f9ded7b176..0fb1100428 100644 --- a/src/bin/debug/strace/TypeHandler.cpp +++ b/src/bin/debug/strace/TypeHandler.cpp @@ -91,6 +91,39 @@ TypeHandlerFactory::Create() return new TypeHandlerImpl(); } +// status_t +class StatusTypeHandler : public TypeHandler { +public: + StatusTypeHandler() {} + + string GetParameterValue(Context &context, Parameter *, const void *address) + { + return RenderValue(context, get_value(address)); + } + + string GetReturnValue(Context &context, uint64 value) + { + return RenderValue(context, value); + } + +private: + string RenderValue(Context &context, uint64 value) const + { + string rendered = context.FormatUnsigned(value); + if (value <= UINT32_MAX && (status_t)value <= 0) { + rendered += " "; + rendered += strerror(value); + } + return rendered; + } +}; + +TypeHandler * +create_status_t_type_handler() +{ + return new StatusTypeHandler; +} + // read_string static string diff --git a/src/bin/debug/strace/TypeHandler.h b/src/bin/debug/strace/TypeHandler.h index 854bbb9ccf..ca11583dd4 100644 --- a/src/bin/debug/strace/TypeHandler.h +++ b/src/bin/debug/strace/TypeHandler.h @@ -97,6 +97,7 @@ struct TypeHandlerFactory { extern TypeHandler *create_pointer_type_handler(); extern TypeHandler *create_string_type_handler(); +extern TypeHandler *create_status_t_type_handler(); // specialization for "const char*" template<> diff --git a/src/bin/debug/strace/strace.cpp b/src/bin/debug/strace/strace.cpp index 8613c90293..011dd12ce9 100644 --- a/src/bin/debug/strace/strace.cpp +++ b/src/bin/debug/strace/strace.cpp @@ -265,10 +265,21 @@ patch_syscalls() // instead of having this done here manually we should either add the // patching step to gensyscalls also manually or add metadata to // kernel/syscalls.h and have it parsed automatically + extern void patch_fcntl(); extern void patch_ioctl(); extern void patch_area(); + for (size_t i = 0; i < sSyscallVector.size(); i++) { + Syscall *syscall = sSyscallVector[i]; + const string returnTypeName = syscall->ReturnType()->TypeName(); + // patch return type handlers + if (returnTypeName == "status_t" || returnTypeName == "ssize_t" + || returnTypeName == "int") { + syscall->ReturnType()->SetHandler(create_status_t_type_handler()); + } + } + patch_fcntl(); patch_ioctl(); patch_area(); @@ -455,21 +466,12 @@ print_syscall(FILE *outputFile, Syscall* syscall, debug_post_syscall &message, syscall->Name().c_str() + 6); } } + Type *returnType = syscall->ReturnType(); TypeHandler *handler = returnType->Handler(); ::string value = handler->GetReturnValue(ctx, message.return_value); - if (value.length() > 0) { + if (value.length() > 0) print_to_string(&string, &length, " = %s", value.c_str()); - - // if the return type is status_t or ssize_t, print human-readable - // error codes - if (returnType->TypeName() == "status_t" - || ((returnType->TypeName() == "ssize_t" - || returnType->TypeName() == "int") - && message.return_value < 0)) { - print_to_string(&string, &length, " %s", strerror(message.return_value)); - } - } } // print arguments