1 //===-- ProcessMessage.h ----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ProcessMessage_H_ 11 #define liblldb_ProcessMessage_H_ 12 13 #include <cassert> 14 15 #include "lldb/lldb-defines.h" 16 #include "lldb/lldb-types.h" 17 18 class ProcessMessage 19 { 20 public: 21 22 /// The type of signal this message can correspond to. 23 enum Kind 24 { 25 eInvalidMessage, 26 eAttachMessage, 27 eExitMessage, 28 eLimboMessage, 29 eSignalMessage, 30 eSignalDeliveredMessage, 31 eTraceMessage, 32 eBreakpointMessage, 33 eWatchpointMessage, 34 eCrashMessage, 35 eNewThreadMessage 36 }; 37 38 enum CrashReason 39 { 40 eInvalidCrashReason, 41 42 // SIGSEGV crash reasons. 43 eInvalidAddress, 44 ePrivilegedAddress, 45 46 // SIGILL crash reasons. 47 eIllegalOpcode, 48 eIllegalOperand, 49 eIllegalAddressingMode, 50 eIllegalTrap, 51 ePrivilegedOpcode, 52 ePrivilegedRegister, 53 eCoprocessorError, 54 eInternalStackError, 55 56 // SIGBUS crash reasons, 57 eIllegalAlignment, 58 eIllegalAddress, 59 eHardwareError, 60 61 // SIGFPE crash reasons, 62 eIntegerDivideByZero, 63 eIntegerOverflow, 64 eFloatDivideByZero, 65 eFloatOverflow, 66 eFloatUnderflow, 67 eFloatInexactResult, 68 eFloatInvalidOperation, 69 eFloatSubscriptRange 70 }; 71 72 ProcessMessage() 73 : m_tid(LLDB_INVALID_PROCESS_ID), 74 m_kind(eInvalidMessage), 75 m_crash_reason(eInvalidCrashReason), 76 m_status(0), 77 m_addr(0) { } 78 79 Kind GetKind() const { return m_kind; } 80 81 lldb::tid_t GetTID() const { return m_tid; } 82 83 /// Indicates that the process @p pid has successfully attached. 84 static ProcessMessage Attach(lldb::pid_t pid) { 85 return ProcessMessage(pid, eAttachMessage); 86 } 87 88 /// Indicates that the thread @p tid is about to exit with status @p status. 89 static ProcessMessage Limbo(lldb::tid_t tid, int status) { 90 return ProcessMessage(tid, eLimboMessage, status); 91 } 92 93 /// Indicates that the thread @p tid had the signal @p signum delivered. 94 static ProcessMessage Signal(lldb::tid_t tid, int signum) { 95 return ProcessMessage(tid, eSignalMessage, signum); 96 } 97 98 /// Indicates that a signal @p signum generated by the debugging process was 99 /// delivered to the thread @p tid. 100 static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) { 101 return ProcessMessage(tid, eSignalDeliveredMessage, signum); 102 } 103 104 /// Indicates that the thread @p tid encountered a trace point. 105 static ProcessMessage Trace(lldb::tid_t tid) { 106 return ProcessMessage(tid, eTraceMessage); 107 } 108 109 /// Indicates that the thread @p tid encountered a break point. 110 static ProcessMessage Break(lldb::tid_t tid) { 111 return ProcessMessage(tid, eBreakpointMessage); 112 } 113 114 static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) { 115 return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr); 116 } 117 118 /// Indicates that the thread @p tid crashed. 119 static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, 120 int signo, lldb::addr_t fault_addr) { 121 ProcessMessage message(pid, eCrashMessage, signo, fault_addr); 122 message.m_crash_reason = reason; 123 return message; 124 } 125 126 /// Indicates that the thread @p child_tid was spawned. 127 static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) { 128 return ProcessMessage(parent_tid, eNewThreadMessage, child_tid); 129 } 130 131 /// Indicates that the thread @p tid is about to exit with status @p status. 132 static ProcessMessage Exit(lldb::tid_t tid, int status) { 133 return ProcessMessage(tid, eExitMessage, status); 134 } 135 136 int GetExitStatus() const { 137 assert(GetKind() == eExitMessage || GetKind() == eLimboMessage); 138 return m_status; 139 } 140 141 int GetSignal() const { 142 assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage || 143 GetKind() == eSignalDeliveredMessage); 144 return m_status; 145 } 146 147 int GetStopStatus() const { 148 assert(GetKind() == eSignalMessage); 149 return m_status; 150 } 151 152 CrashReason GetCrashReason() const { 153 assert(GetKind() == eCrashMessage); 154 return m_crash_reason; 155 } 156 157 lldb::addr_t GetFaultAddress() const { 158 assert(GetKind() == eCrashMessage); 159 return m_addr; 160 } 161 162 lldb::addr_t GetHWAddress() const { 163 assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage); 164 return m_addr; 165 } 166 167 lldb::tid_t GetChildTID() const { 168 assert(GetKind() == eNewThreadMessage); 169 return m_child_tid; 170 } 171 172 static const char * 173 GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr); 174 175 const char * 176 PrintCrashReason() const; 177 178 static const char * 179 PrintCrashReason(CrashReason reason); 180 181 const char * 182 PrintKind() const; 183 184 static const char * 185 PrintKind(Kind); 186 187 private: 188 ProcessMessage(lldb::tid_t tid, Kind kind, 189 int status = 0, lldb::addr_t addr = 0) 190 : m_tid(tid), 191 m_kind(kind), 192 m_crash_reason(eInvalidCrashReason), 193 m_status(status), 194 m_addr(addr), 195 m_child_tid(0) { } 196 197 ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid) 198 : m_tid(tid), 199 m_kind(kind), 200 m_crash_reason(eInvalidCrashReason), 201 m_status(0), 202 m_addr(0), 203 m_child_tid(child_tid) { } 204 205 lldb::tid_t m_tid; 206 Kind m_kind : 8; 207 CrashReason m_crash_reason : 8; 208 int m_status; 209 lldb::addr_t m_addr; 210 lldb::tid_t m_child_tid; 211 }; 212 213 #endif // #ifndef liblldb_ProcessMessage_H_ 214