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 
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 
78     Kind GetKind() const { return m_kind; }
79 
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.
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.
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.
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.
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.
104     static ProcessMessage Break(lldb::tid_t tid) {
105         return ProcessMessage(tid, eBreakpointMessage);
106     }
107 
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.
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 tid was spawned.
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     int GetExitStatus() const {
126         assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
127         return m_status;
128     }
129 
130     int GetSignal() const {
131         assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
132                GetKind() == eSignalDeliveredMessage);
133         return m_status;
134     }
135 
136     int GetStopStatus() const {
137         assert(GetKind() == eSignalMessage);
138         return m_status;
139     }
140 
141     CrashReason GetCrashReason() const {
142         assert(GetKind() == eCrashMessage);
143         return m_crash_reason;
144     }
145 
146     lldb::addr_t GetFaultAddress() const {
147         assert(GetKind() == eCrashMessage);
148         return m_addr;
149     }
150 
151     lldb::addr_t GetHWAddress() const {
152         assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
153         return m_addr;
154     }
155 
156     lldb::tid_t GetChildTID() const {
157         assert(GetKind() == eNewThreadMessage);
158         return m_child_tid;
159     }
160 
161     static const char *
162     GetCrashReasonString(CrashReason reason);
163 
164     const char *
165     PrintCrashReason() const;
166 
167     static const char *
168     PrintCrashReason(CrashReason reason);
169 
170     const char *
171     PrintKind() const;
172 
173     static const char *
174     PrintKind(Kind);
175 
176 private:
177     ProcessMessage(lldb::tid_t tid, Kind kind,
178                    int status = 0, lldb::addr_t addr = 0)
179         : m_tid(tid),
180           m_kind(kind),
181           m_crash_reason(eInvalidCrashReason),
182           m_status(status),
183           m_addr(addr),
184           m_child_tid(0) { }
185 
186     ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
187         : m_tid(tid),
188           m_kind(kind),
189           m_crash_reason(eInvalidCrashReason),
190           m_status(0),
191           m_addr(0),
192           m_child_tid(child_tid) { }
193 
194     lldb::tid_t m_tid;
195     Kind        m_kind         : 8;
196     CrashReason m_crash_reason : 8;
197     int m_status;
198     lldb::addr_t m_addr;
199     lldb::tid_t m_child_tid;
200 };
201 
202 #endif // #ifndef liblldb_ProcessMessage_H_
203