00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00035 #include "OW_Platform.hpp"
00036 #include "OW_PlatformSignal.hpp"
00037 #include "OW_UserUtils.hpp"
00038 #include <ostream>
00039
00040 namespace OW_NAMESPACE
00041 {
00042 namespace Platform
00043 {
00044 namespace Signal
00045 {
00046 SignalInformation::SignalInformation() :
00047 signalAction(0),
00048 signalNumber(0),
00049 errorNumber(0),
00050 signalCode(0),
00051 originatingPID(0),
00052 originatingUID(0),
00053 faultAddress(0),
00054 fileDescriptor(0),
00055 band(0)
00056 {
00057 #if defined(OW_HAVE_SIGVAL_TYPE_SIGVAL_INT)
00058 timerValue.sigval_int = 0;
00059 #elif defined(OW_HAVE_SIGVAL_TYPE_SIVAL_INT)
00060 timerValue.sival_int = 0;
00061 #else
00062 timerValue = 0;
00063 #endif
00064 }
00065
00066 void extractSignalInformation(const siginfo_t& source, SignalInformation& dest)
00067 {
00068
00069 dest = SignalInformation();
00070
00071 #ifndef OW_WIN32
00072
00073
00074
00075 dest.signalNumber = source.si_signo;
00076 dest.errorNumber = source.si_errno;
00077 dest.signalCode = source.si_code;
00078
00079 switch(source.si_code)
00080 {
00081 case SI_USER:
00082 dest.originatingPID = source.si_pid;
00083 dest.originatingUID = source.si_uid;
00084 break;
00085 case SI_TIMER:
00086 dest.timerValue = source.si_value;
00087 break;
00088 case SI_ASYNCIO:
00089 #if defined(OW_HAVE_SIGINFO_T_SI_FD)
00090 dest.fileDescriptor = source.si_fd;
00091 #endif
00092 dest.band = source.si_band;
00093 break;
00094 default:
00095
00096 break;
00097 }
00098 switch(source.si_signo)
00099 {
00100 case SIGILL:
00101 case SIGFPE:
00102 case SIGTRAP:
00103 case SIGBUS:
00104 case SIGSEGV:
00105 dest.faultAddress = source.si_addr;
00106 break;
00107 #if defined(SIGPOLL)
00108 case SIGPOLL:
00109 #if defined(OW_HAVE_SIGINFO_T_SI_FD)
00110 dest.fileDescriptor = source.si_fd;
00111 #endif
00112 dest.band = source.si_band;
00113 break;
00114 #endif
00115 default:
00116
00117 break;
00118 }
00119 #endif
00120 }
00121
00122 namespace
00123 {
00124
00125
00126
00127 template<class T>
00128 void flattenToPipe(const T& t, UnnamedPipeRef& destPipe)
00129 {
00130 destPipe->write(&t, sizeof(t));
00131 }
00132
00133
00134
00135
00136 template <class T>
00137 bool unflattenFromPipe(T& dest, UnnamedPipeRef& sourcePipe)
00138 {
00139 return sourcePipe->read(&dest, sizeof(dest));
00140 }
00141 }
00142
00143 bool flattenSignalInformation(const SignalInformation& source, UnnamedPipeRef& destPipe)
00144 {
00145 if( !destPipe )
00146 {
00147 return false;
00148 }
00149
00150 flattenToPipe(source.signalAction, destPipe);
00151 flattenToPipe(source.signalNumber, destPipe);
00152 flattenToPipe(source.errorNumber, destPipe);
00153 flattenToPipe(source.signalCode, destPipe);
00154 flattenToPipe(source.originatingPID, destPipe);
00155 flattenToPipe(source.originatingUID, destPipe);
00156 flattenToPipe(source.timerValue, destPipe);
00157 flattenToPipe(source.faultAddress, destPipe);
00158 flattenToPipe(source.fileDescriptor, destPipe);
00159 flattenToPipe(source.band, destPipe);
00160 return true;
00161 }
00162
00163 bool unflattenSignalInformation(SignalInformation& dest, UnnamedPipeRef& sourcePipe)
00164 {
00165 if( !sourcePipe )
00166 {
00167 return false;
00168 }
00169 bool success = true;
00170 dest = SignalInformation();
00171
00172 success = success && unflattenFromPipe(dest.signalAction, sourcePipe);
00173 success = success && unflattenFromPipe(dest.signalNumber, sourcePipe);
00174 success = success && unflattenFromPipe(dest.errorNumber, sourcePipe);
00175 success = success && unflattenFromPipe(dest.signalCode, sourcePipe);
00176 success = success && unflattenFromPipe(dest.originatingPID, sourcePipe);
00177 success = success && unflattenFromPipe(dest.originatingUID, sourcePipe);
00178 success = success && unflattenFromPipe(dest.timerValue, sourcePipe);
00179 success = success && unflattenFromPipe(dest.faultAddress, sourcePipe);
00180 success = success && unflattenFromPipe(dest.fileDescriptor, sourcePipe);
00181 success = success && unflattenFromPipe(dest.band, sourcePipe);
00182
00183 return success;
00184 }
00185
00186 std::ostream& operator<<(std::ostream& o, const SignalInformation& sig)
00187 {
00188 const char* sigtext = NULL;
00189 #if defined(OW_HAVE_STRSIGNAL)
00190 sigtext = strsignal(sig.signalNumber);
00191 #endif
00192
00193 if( !sigtext )
00194 {
00195 sigtext = "UNKNOWN";
00196 }
00197 o << " Signal: " << sigtext << " (" << sig.signalNumber << ")" << std::endl;
00198 if( sig.errorNumber )
00199 {
00200 o << " Error: " << strerror(sig.errorNumber) << std::endl;
00201 }
00202
00203 const char* signal_type = "Unknown-origin signal";
00204
00205 enum signal_specifications
00206 {
00207 SIGNAL_ANY,
00208 SIGNAL_SPECIFIC
00209 };
00210
00211 struct signal_code_text
00212 {
00213 signal_specifications signal_spec;
00214 int signal_number;
00215 int signal_code;
00216 const char* signal_type_text;
00217 };
00218
00219 #ifndef OW_WIN32
00220
00221
00222
00223
00224 const signal_code_text signal_text[] =
00225 {
00226 #if defined(SI_USER)
00227 { SIGNAL_ANY, 0, SI_USER, "User-originated (kill, sigsend, or raise) signal" },
00228 #endif
00229 #if defined(SI_KERNEL)
00230 { SIGNAL_ANY, 0, SI_KERNEL, "Kernel-originated signal" },
00231 #endif
00232 #if defined(SI_QUEUE)
00233 { SIGNAL_ANY, 0, SI_QUEUE, "sigqueue queued signal" },
00234 #endif
00235 #if defined(SI_TIMER)
00236 { SIGNAL_ANY, 0, SI_TIMER, "Timer expiration signal"},
00237 #endif
00238 #if defined(SI_ASYNCIO)
00239 { SIGNAL_ANY, 0, SI_ASYNCIO, "Asynchronous I/O signal"},
00240 #endif
00241 #if defined(SI_MESGQ)
00242 { SIGNAL_ANY, 0, SI_MESGQ, "Empty message queue signal"},
00243 #endif
00244 #if defined(SIGILL) && defined(ILL_ILLOPC)
00245 { SIGNAL_SPECIFIC, SIGILL, ILL_ILLOPC, "Illegal instruction: Illegal opcode"},
00246 #endif
00247 #if defined(SIGILL) && defined(ILL_ILLOPN)
00248 { SIGNAL_SPECIFIC, SIGILL, ILL_ILLOPN, "Illegal instruction: Illegal operand"},
00249 #endif
00250 #if defined(SIGILL) && defined(ILL_ILLADR)
00251 { SIGNAL_SPECIFIC, SIGILL, ILL_ILLADR, "Illegal instruction: Illegal addressing mode"},
00252 #endif
00253 #if defined(SIGILL) && defined(ILL_ILLTRP)
00254 { SIGNAL_SPECIFIC, SIGILL, ILL_ILLTRP, "Illegal instruction: Illegal trap"},
00255 #endif
00256 #if defined(SIGILL) && defined(ILL_PRVOPC)
00257 { SIGNAL_SPECIFIC, SIGILL, ILL_PRVOPC, "Illegal instruction: Privileged opcode"},
00258 #endif
00259 #if defined(SIGILL) && defined(ILL_PRVREG)
00260 { SIGNAL_SPECIFIC, SIGILL, ILL_PRVREG, "Illegal instruction: Privileged register"},
00261 #endif
00262 #if defined(SIGILL) && defined(ILL_COPROC)
00263 { SIGNAL_SPECIFIC, SIGILL, ILL_COPROC, "Illegal instruction: Coprocessor error"},
00264 #endif
00265 #if defined(SIGILL) && defined(ILL_BADSTK)
00266 { SIGNAL_SPECIFIC, SIGILL, ILL_BADSTK, "Illegal instruction: Internal stack error"},
00267 #endif
00268 };
00269
00270 for( const signal_code_text* test_signal = signal_text;
00271 test_signal != (signal_text + sizeof(signal_text) / sizeof(*signal_text));
00272 ++test_signal )
00273 {
00274 if( test_signal->signal_spec == SIGNAL_ANY )
00275 {
00276 if( sig.signalCode == test_signal->signal_code )
00277 {
00278 signal_type = test_signal->signal_type_text;
00279 break;
00280 }
00281 }
00282 else
00283 {
00284 if(
00285 (sig.signalNumber == test_signal->signal_number) &&
00286 (sig.signalCode == test_signal->signal_code) )
00287 {
00288 signal_type = test_signal->signal_type_text;
00289 break;
00290 }
00291 }
00292 }
00293 #else
00294 signal_type = "UNKNOWN";
00295 #endif
00296
00297 o << " Signal Type: " << signal_type << " (" << sig.signalCode << ")" << std::endl;
00298
00299
00300
00301 o << " Fault address: " << sig.faultAddress << std::endl;
00302 o << " File Descriptor: " << sig.fileDescriptor << std::endl;
00303 o << " Band: " << sig.band << std::endl;
00304 o << " Origination PID: " << sig.originatingPID << std::endl;
00305 o << " Originating UID: " << sig.originatingUID;
00306 bool success = false;
00307 String username = UserUtils::getUserName(sig.originatingUID, success);
00308 if( success )
00309 {
00310 o << " (" << username << ")";
00311 }
00312 o << std::endl;
00313
00314 const char* action;
00315 switch( sig.signalAction )
00316 {
00317 case ::OW_NAMESPACE::Platform::SHUTDOWN:
00318 action = "shutdown";
00319 break;
00320 case ::OW_NAMESPACE::Platform::REINIT:
00321 action = "restart";
00322 break;
00323 default:
00324 action = "unknown";
00325 break;
00326 }
00327 o << " CIMOM Action: " << action << std::endl;
00328 return o;
00329 }
00330
00331 }
00332 }
00333 }