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