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