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