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 "CrashReason.h"
14 
15 #include <cassert>
16 #include <string>
17 
18 #include "lldb/lldb-defines.h"
19 #include "lldb/lldb-types.h"
20 
21 class ProcessMessage
22 {
23 public:
24 
25     /// The type of signal this message can correspond to.
26     enum Kind
27     {
28         eInvalidMessage,
29         eAttachMessage,
30         eExitMessage,
31         eLimboMessage,
32         eSignalMessage,
33         eSignalDeliveredMessage,
34         eTraceMessage,
35         eBreakpointMessage,
36         eWatchpointMessage,
37         eCrashMessage,
38         eNewThreadMessage,
39         eExecMessage
40     };
41 
42     ProcessMessage()
43         : m_tid(LLDB_INVALID_PROCESS_ID),
44           m_kind(eInvalidMessage),
45           m_crash_reason(CrashReason::eInvalidCrashReason),
46           m_status(0),
47           m_addr(0) { }
48 
49     Kind GetKind() const { return m_kind; }
50 
51     lldb::tid_t GetTID() const { return m_tid; }
52 
53     /// Indicates that the process @p pid has successfully attached.
54     static ProcessMessage Attach(lldb::pid_t pid) {
55         return ProcessMessage(pid, eAttachMessage);
56     }
57 
58     /// Indicates that the thread @p tid is about to exit with status @p status.
59     static ProcessMessage Limbo(lldb::tid_t tid, int status) {
60         return ProcessMessage(tid, eLimboMessage, status);
61     }
62 
63     /// Indicates that the thread @p tid had the signal @p signum delivered.
64     static ProcessMessage Signal(lldb::tid_t tid, int signum) {
65         return ProcessMessage(tid, eSignalMessage, signum);
66     }
67 
68     /// Indicates that a signal @p signum generated by the debugging process was
69     /// delivered to the thread @p tid.
70     static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
71         return ProcessMessage(tid, eSignalDeliveredMessage, signum);
72     }
73 
74     /// Indicates that the thread @p tid encountered a trace point.
75     static ProcessMessage Trace(lldb::tid_t tid) {
76         return ProcessMessage(tid, eTraceMessage);
77     }
78 
79     /// Indicates that the thread @p tid encountered a break point.
80     static ProcessMessage Break(lldb::tid_t tid) {
81         return ProcessMessage(tid, eBreakpointMessage);
82     }
83 
84     static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
85         return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
86     }
87 
88     /// Indicates that the thread @p tid crashed.
89     static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
90                                 int signo, lldb::addr_t fault_addr) {
91         ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
92         message.m_crash_reason = reason;
93         return message;
94     }
95 
96     /// Indicates that the thread @p child_tid was spawned.
97     static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
98         return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
99     }
100 
101     /// Indicates that the thread @p tid is about to exit with status @p status.
102     static ProcessMessage Exit(lldb::tid_t tid, int status) {
103         return ProcessMessage(tid, eExitMessage, status);
104     }
105 
106     /// Indicates that the thread @p pid has exec'd.
107     static ProcessMessage Exec(lldb::tid_t tid) {
108         return ProcessMessage(tid, eExecMessage);
109     }
110 
111     int GetExitStatus() const {
112         assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
113         return m_status;
114     }
115 
116     int GetSignal() const {
117         assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
118                GetKind() == eSignalDeliveredMessage);
119         return m_status;
120     }
121 
122     int GetStopStatus() const {
123         assert(GetKind() == eSignalMessage);
124         return m_status;
125     }
126 
127     CrashReason GetCrashReason() const {
128         assert(GetKind() == eCrashMessage);
129         return m_crash_reason;
130     }
131 
132     lldb::addr_t GetFaultAddress() const {
133         assert(GetKind() == eCrashMessage);
134         return m_addr;
135     }
136 
137     lldb::addr_t GetHWAddress() const {
138         assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
139         return m_addr;
140     }
141 
142     lldb::tid_t GetChildTID() const {
143         assert(GetKind() == eNewThreadMessage);
144         return m_child_tid;
145     }
146 
147     const char *
148     PrintCrashReason() const;
149 
150     const char *
151     PrintKind() const;
152 
153     static const char *
154     PrintKind(Kind);
155 
156 private:
157     ProcessMessage(lldb::tid_t tid, Kind kind,
158                    int status = 0, lldb::addr_t addr = 0)
159         : m_tid(tid),
160           m_kind(kind),
161           m_crash_reason(CrashReason::eInvalidCrashReason),
162           m_status(status),
163           m_addr(addr),
164           m_child_tid(0) { }
165 
166     ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
167         : m_tid(tid),
168           m_kind(kind),
169           m_crash_reason(CrashReason::eInvalidCrashReason),
170           m_status(0),
171           m_addr(0),
172           m_child_tid(child_tid) { }
173 
174     lldb::tid_t m_tid;
175     Kind        m_kind         : 8;
176     CrashReason m_crash_reason;
177     int m_status;
178     lldb::addr_t m_addr;
179     lldb::tid_t m_child_tid;
180 };
181 
182 #endif // #ifndef liblldb_ProcessMessage_H_
183