From cf3d24d5e0d78e4e8fe1c155a7c556164ae42a51 Mon Sep 17 00:00:00 2001 From: Patrick Williams Date: Fri, 20 Sep 2013 12:39:54 -0500 Subject: Runtime trace interfaces. Change-Id: Ie261eba4bd790150d520bb0261f56c8329cb6a80 RTC: 79420 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6400 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert Reviewed-by: Daniel M. Crowell Reviewed-by: A. Patrick Williams III --- src/usr/trace/interface.C | 5 +- src/usr/trace/runtime/rt_service.C | 119 +++++++++++++++++++++++++++++++++++-- src/usr/trace/service.C | 1 + src/usr/trace/service.H | 2 + 4 files changed, 120 insertions(+), 7 deletions(-) (limited to 'src/usr/trace') diff --git a/src/usr/trace/interface.C b/src/usr/trace/interface.C index 5ca18db37..947ae4eb9 100644 --- a/src/usr/trace/interface.C +++ b/src/usr/trace/interface.C @@ -84,13 +84,14 @@ namespace TRACE } void trace_adal_write_bin(ComponentDesc * io_td, - const trace_hash_val i_hash, + const traceCodeInfo* i_info, const uint32_t i_line, const void * i_ptr, const uint32_t i_size, const uint32_t i_type) { - Singleton::instance().writeBinEntry(io_td, i_hash, i_line, + Singleton::instance().writeBinEntry(io_td, i_info->hash, + i_info->format, i_line, i_ptr, i_size, i_type); } diff --git a/src/usr/trace/runtime/rt_service.C b/src/usr/trace/runtime/rt_service.C index 2bb697d3e..e7eda7280 100644 --- a/src/usr/trace/runtime/rt_service.C +++ b/src/usr/trace/runtime/rt_service.C @@ -25,10 +25,15 @@ #include #include #include +#include +#include +#include #include namespace TRACE { + // Value was chosen empirically from trace lengths during the IPL. + static const size_t DEFAULT_TRACE_LENGTH = 128; Service::Service() { @@ -55,14 +60,34 @@ namespace TRACE } } - char output[KILOBYTE]; - vsprintf(output, i_fmt, i_args); // TODO: RTC 79420 : - // Potential buffer overrun. - g_hostInterfaces->puts(output); + size_t compName_len = strnlen(i_td->iv_compName, + sizeof(i_td->iv_compName)); + + char output[DEFAULT_TRACE_LENGTH]; + memcpy(output, i_td->iv_compName, compName_len); + output[compName_len] = ':'; + size_t length = vsnprintf(&output[compName_len+1], + DEFAULT_TRACE_LENGTH-(compName_len+1), + i_fmt, i_args); + + if (unlikely((compName_len + 1 + length + 1) > DEFAULT_TRACE_LENGTH)) + { + char* long_output = new char[compName_len + 1 + length + 1]; + memcpy(long_output, i_td->iv_compName, compName_len); + long_output[compName_len] = ':'; + vsprintf(&long_output[compName_len+1], i_fmt, i_args); + g_hostInterfaces->puts(long_output); + delete[] long_output; + } + else + { + g_hostInterfaces->puts(output); + } } void Service::writeBinEntry(ComponentDesc* i_td, trace_hash_val i_hash, + const char * i_fmt, uint32_t i_ine, const void* i_ptr, uint32_t i_size, @@ -76,7 +101,91 @@ namespace TRACE } } - // TODO: RTC 79420 + size_t compName_len = strnlen(i_td->iv_compName, + sizeof(i_td->iv_compName)); + + // Output header. + char output[DEFAULT_TRACE_LENGTH]; + memcpy(output, i_td->iv_compName, compName_len); + output[compName_len] = ':'; + size_t length = vsnprintf(&output[compName_len+1], + DEFAULT_TRACE_LENGTH-(compName_len+1), + i_fmt, NULL); + + if(unlikely((compName_len + 1 + length + 1) > DEFAULT_TRACE_LENGTH)) + { + char* long_output = new char[compName_len + length + 1]; + memcpy(long_output, i_td->iv_compName, compName_len); + long_output[compName_len] = ':'; + vsprintf(&long_output[compName_len+1], i_fmt, NULL); + g_hostInterfaces->puts(long_output); + delete[] long_output; + } + else + { + g_hostInterfaces->puts(output); + } + + // Output binary data. + // Format is: + // ~[0x0000] 01234567 01234567 01234567 01234567 *012345689abcdef* + static size_t BINARY_FORMAT_LENGTH = + 68 + sizeof(ComponentDesc::iv_compName) + 1; + + size_t pos = 0; + while (pos < i_size) + { + char bin_output[BINARY_FORMAT_LENGTH]; + memcpy(bin_output, i_td->iv_compName, compName_len); + size_t output_pos = compName_len + + sprintf(&bin_output[compName_len], + ":~[0x%04hx]", (int) pos); + + for (int i = 0; i < 16; ++i) + { + if ((i % 4) == 0) + { + bin_output[output_pos++] = ' '; + } + if ((pos + i) < i_size) + { + output_pos += + sprintf(&bin_output[output_pos], "%02x", + ((const char*)i_ptr)[pos+i]); + } + else + { + bin_output[output_pos++] = ' '; + bin_output[output_pos++] = ' '; + } + } + + for (int i = 0; i < 4; i++) + { + bin_output[output_pos++] = ' '; + } + bin_output[output_pos++] = '*'; + + for (int i = 0; i < 16; ++i) + { + char ch = ' '; + if ((pos + i) < i_size) + { + ch = ((const char*) i_ptr)[pos+i]; + if (!isprint(ch)) + { + ch = '.'; + } + } + bin_output[output_pos++] = ch; + } + bin_output[output_pos++] = '*'; + bin_output[output_pos++] = '\0'; + + g_hostInterfaces->puts(bin_output); + + pos += 16; + } } diff --git a/src/usr/trace/service.C b/src/usr/trace/service.C index ad9105499..05938d920 100644 --- a/src/usr/trace/service.C +++ b/src/usr/trace/service.C @@ -208,6 +208,7 @@ namespace TRACE void Service::writeBinEntry(ComponentDesc* i_td, trace_hash_val i_hash, + const char * i_fmt, uint32_t i_line, const void* i_ptr, uint32_t i_size, diff --git a/src/usr/trace/service.H b/src/usr/trace/service.H index 61e9bc494..e1d4f1aba 100644 --- a/src/usr/trace/service.H +++ b/src/usr/trace/service.H @@ -107,6 +107,7 @@ namespace TRACE * @param[in] i_td - Component Descriptor to write to. * * @param[in] i_hash - Hash value. + * @param[in] i_fmt - Printf-style format string. * @param[in] i_line - Line number. * @param[in] i_ptr - Data to write. * @param[in] i_size - Bytes to write. @@ -114,6 +115,7 @@ namespace TRACE */ void writeBinEntry(ComponentDesc* i_td, trace_hash_val i_hash, + const char * i_fmt, uint32_t i_line, const void* i_ptr, uint32_t i_size, -- cgit v1.2.1