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