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