diff options
-rwxr-xr-x | src/include/usr/errl/backtrace.H | 60 | ||||
-rw-r--r-- | src/include/usr/errl/errlentry.H | 4 | ||||
-rwxr-xr-x | src/usr/errl/backtrace.C | 69 | ||||
-rw-r--r-- | src/usr/errl/errlentry.C | 39 | ||||
-rw-r--r-- | src/usr/errl/makefile | 2 |
5 files changed, 165 insertions, 9 deletions
diff --git a/src/include/usr/errl/backtrace.H b/src/include/usr/errl/backtrace.H new file mode 100755 index 000000000..5db0081d3 --- /dev/null +++ b/src/include/usr/errl/backtrace.H @@ -0,0 +1,60 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/include/usr/errl/backtrace.H $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +#ifndef __BACKTRACE_H +#define __BACKTRACE_H +/** + * @file backtrace.H + * + * @brief Backtrace support for errorlog classes. + * This header provides the interfaces for errorlog, or any other user + * code to gather backtraces for the current location in the code. + * + */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <stdint.h> +#include <errl/errltypes.H> +#include <vector> + + +namespace ERRORLOG +{ + +/** +* @brief This function will be called during errorlog creation and will +* add an FFDC section that contains the addresses needed for +* decoding the backtrace at a later time. The later time would be +* when error log details are printed. +* +* @param[out] i_addrVector - Vector of addresses collected. +* +* @return None. +*/ +void collectBacktrace ( std::vector<uint64_t> & o_addrVector ); + + +} // End namespace + +#endif //__BACKTRACE_H diff --git a/src/include/usr/errl/errlentry.H b/src/include/usr/errl/errlentry.H index b3e856996..330a8a813 100644 --- a/src/include/usr/errl/errlentry.H +++ b/src/include/usr/errl/errlentry.H @@ -466,6 +466,7 @@ private: ErrlUH iv_User; // user header object ErrlSrc iv_Src; // primary SRC section std::vector<ErrlUD*> iv_SectionVector; // list of user defined sections + std::vector<uint64_t> iv_btAddrs; // list of addresses for the backtrace // TODO need to interpret term state and terminate accordingly. // TODO termstate is presently not being flattend into PEL @@ -555,9 +556,6 @@ inline void ErrlEntry::setSrcType(const srcType_t i_srcType) return; } - - - } // End namespace #endif //ERRLENTRY_H diff --git a/src/usr/errl/backtrace.C b/src/usr/errl/backtrace.C new file mode 100755 index 000000000..93c4c4fed --- /dev/null +++ b/src/usr/errl/backtrace.C @@ -0,0 +1,69 @@ +// IBM_PROLOG_BEGIN_TAG +// This is an automatically generated prolog. +// +// $Source: src/usr/errl/backtrace.C $ +// +// IBM CONFIDENTIAL +// +// COPYRIGHT International Business Machines Corp. 2011 +// +// p1 +// +// Object Code Only (OCO) source materials +// Licensed Internal Code Source Materials +// IBM HostBoot Licensed Internal Code +// +// The source code for this program is not published or other- +// wise divested of its trade secrets, irrespective of what has +// been deposited with the U.S. Copyright Office. +// +// Origin: 30 +// +// IBM_PROLOG_END +/** + * @file backtrace.C + * + * @brief Provide backtrace support to the errorlog classes. + */ + +/*****************************************************************************/ +// I n c l u d e s +/*****************************************************************************/ +#include <stdio.h> +#include <stdlib.h> +#include <trace/interface.H> +#include <errl/backtrace.H> +#include <vector> + +#include <kernel/console.H> + +namespace ERRORLOG +{ + +// ------------------------------------------------------------------ +// collectBacktrace +// ------------------------------------------------------------------ +void collectBacktrace ( std::vector<uint64_t> & o_addrVector ) +{ + o_addrVector.clear(); + + uint64_t* frame = static_cast<uint64_t*>(framePointer()); + bool first = true; + while (frame != NULL) + { + if ((0 != *frame) && (!first)) + { + TRACDCOMP( g_trac_back, + "Addr: %016llx", + frame[2] ); + o_addrVector.push_back( frame[2] ); + } + + frame = reinterpret_cast<uint64_t*>(*frame); + first = false; + } +} // End collectBacktrace + + +} // End ERRORLOG namespace + diff --git a/src/usr/errl/errlentry.C b/src/usr/errl/errlentry.C index 553bdab8f..5c7c39a83 100644 --- a/src/usr/errl/errlentry.C +++ b/src/usr/errl/errlentry.C @@ -37,6 +37,7 @@ #include <errl/errlmanager.H> #include <trace/interface.H> #include <arch/ppc.H> +#include <errl/backtrace.H> namespace ERRORLOG @@ -60,8 +61,36 @@ ErrlEntry::ErrlEntry(const errlSeverity_t i_sev, iv_Src( SRC_ERR_INFO, i_modId, i_reasonCode, i_user1, i_user2 ), iv_termState(TERM_STATE_UNKNOWN) { + // Collect the Backtrace + std::vector<uint64_t> bt; + collectBacktrace( bt ); + // Add Backtrace to user data section + ErrlUD * ffdcPtr = NULL; + for( uint32_t i = 0; i < bt.size(); i++ ) + { + if( 0 == i ) + { + ffdcPtr = addFFDC( ERRL_COMP_ID, + &bt[i], + sizeof(bt[i]), + 0, 0 ); + // Make sure we got a pointer to the user details + if( NULL == ffdcPtr ) + { + TRACFCOMP( g_trac_errl, + ERR_MRK"NULL FFDC pointer!" ); + break; + } + } + else + { + appendToFFDC( ffdcPtr, + &bt[i], + sizeof(bt[i]) ); + } + } } @@ -145,7 +174,7 @@ bool ErrlEntry::collectTrace(const char i_name[], const uint64_t i_max) do { // By passing nil arguments 2 and 3, obtain the size of the buffer. - // Besides getting buffer size, it validates i_name. + // Besides getting buffer size, it validates i_name. uint64_t l_cbFull = TRACE::Trace::getTheInstance().getBuffer( i_name, NULL, 0 ); @@ -168,11 +197,11 @@ bool ErrlEntry::collectTrace(const char i_name[], const uint64_t i_max) l_cbBuffer = i_max; } - // allocate the buffer - l_pBuffer = new char[ l_cbBuffer ]; + // allocate the buffer + l_pBuffer = new char[ l_cbBuffer ]; // Get the data into the buffer. - l_cbOutput = + l_cbOutput = TRACE::Trace::getTheInstance().getBuffer( i_name, l_pBuffer, l_cbBuffer ); @@ -181,7 +210,7 @@ bool ErrlEntry::collectTrace(const char i_name[], const uint64_t i_max) { // Problem. TRACFCOMP( g_trac_errl, - "ErrlEntry::collectTrace(): getBuffer(%s,%ld) rets zero.", + "ErrlEntry::collectTrace(): getBuffer(%s,%ld) rets zero.", i_name, l_cbBuffer ); break; diff --git a/src/usr/errl/makefile b/src/usr/errl/makefile index 1a219ccb3..8020e07a9 100644 --- a/src/usr/errl/makefile +++ b/src/usr/errl/makefile @@ -24,7 +24,7 @@ ROOTPATH = ../../.. MODULE = errl OBJS = errlentry.o errlmanager.o errlsctn.o errlsctnhdr.o errlprvt.o errluh.o \ - errlud.o errlsrc.o errluserdetails.o + errlud.o errlsrc.o errluserdetails.o backtrace.o SUBDIRS = test.d parser.d |