Debug.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //===-- Debug.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. #ifndef LLDB_HOST_DEBUG_H
  9. #define LLDB_HOST_DEBUG_H
  10. #include <vector>
  11. #include "lldb/lldb-private.h"
  12. namespace lldb_private {
  13. // Tells a thread what it needs to do when the process is resumed.
  14. struct ResumeAction {
  15. lldb::tid_t tid; // The thread ID that this action applies to,
  16. // LLDB_INVALID_THREAD_ID for the default thread
  17. // action
  18. lldb::StateType state; // Valid values are eStateStopped/eStateSuspended,
  19. // eStateRunning, and eStateStepping.
  20. int signal; // When resuming this thread, resume it with this signal if this
  21. // value is > 0
  22. };
  23. // A class that contains instructions for all threads for
  24. // NativeProcessProtocol::Resume(). Each thread can either run, stay suspended,
  25. // or step when the process is resumed. We optionally have the ability to also
  26. // send a signal to the thread when the action is run or step.
  27. class ResumeActionList {
  28. public:
  29. ResumeActionList() : m_actions(), m_signal_handled() {}
  30. ResumeActionList(lldb::StateType default_action, int signal)
  31. : m_actions(), m_signal_handled() {
  32. SetDefaultThreadActionIfNeeded(default_action, signal);
  33. }
  34. ResumeActionList(const ResumeAction *actions, size_t num_actions)
  35. : m_actions(), m_signal_handled() {
  36. if (actions && num_actions) {
  37. m_actions.assign(actions, actions + num_actions);
  38. m_signal_handled.assign(num_actions, false);
  39. }
  40. }
  41. ~ResumeActionList() = default;
  42. bool IsEmpty() const { return m_actions.empty(); }
  43. void Append(const ResumeAction &action) {
  44. m_actions.push_back(action);
  45. m_signal_handled.push_back(false);
  46. }
  47. void AppendAction(lldb::tid_t tid, lldb::StateType state, int signal = 0) {
  48. ResumeAction action = {tid, state, signal};
  49. Append(action);
  50. }
  51. void AppendResumeAll() {
  52. AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateRunning);
  53. }
  54. void AppendSuspendAll() {
  55. AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStopped);
  56. }
  57. void AppendStepAll() {
  58. AppendAction(LLDB_INVALID_THREAD_ID, lldb::eStateStepping);
  59. }
  60. const ResumeAction *GetActionForThread(lldb::tid_t tid,
  61. bool default_ok) const {
  62. const size_t num_actions = m_actions.size();
  63. for (size_t i = 0; i < num_actions; ++i) {
  64. if (m_actions[i].tid == tid)
  65. return &m_actions[i];
  66. }
  67. if (default_ok && tid != LLDB_INVALID_THREAD_ID)
  68. return GetActionForThread(LLDB_INVALID_THREAD_ID, false);
  69. return nullptr;
  70. }
  71. size_t NumActionsWithState(lldb::StateType state) const {
  72. size_t count = 0;
  73. const size_t num_actions = m_actions.size();
  74. for (size_t i = 0; i < num_actions; ++i) {
  75. if (m_actions[i].state == state)
  76. ++count;
  77. }
  78. return count;
  79. }
  80. bool SetDefaultThreadActionIfNeeded(lldb::StateType action, int signal) {
  81. if (GetActionForThread(LLDB_INVALID_THREAD_ID, true) == nullptr) {
  82. // There isn't a default action so we do need to set it.
  83. ResumeAction default_action = {LLDB_INVALID_THREAD_ID, action, signal};
  84. m_actions.push_back(default_action);
  85. m_signal_handled.push_back(false);
  86. return true; // Return true as we did add the default action
  87. }
  88. return false;
  89. }
  90. void SetSignalHandledForThread(lldb::tid_t tid) const {
  91. if (tid != LLDB_INVALID_THREAD_ID) {
  92. const size_t num_actions = m_actions.size();
  93. for (size_t i = 0; i < num_actions; ++i) {
  94. if (m_actions[i].tid == tid)
  95. m_signal_handled[i] = true;
  96. }
  97. }
  98. }
  99. const ResumeAction *GetFirst() const { return m_actions.data(); }
  100. size_t GetSize() const { return m_actions.size(); }
  101. void Clear() {
  102. m_actions.clear();
  103. m_signal_handled.clear();
  104. }
  105. protected:
  106. std::vector<ResumeAction> m_actions;
  107. mutable std::vector<bool> m_signal_handled;
  108. };
  109. struct ThreadStopInfo {
  110. lldb::StopReason reason;
  111. union {
  112. // eStopReasonSignal
  113. struct {
  114. uint32_t signo;
  115. } signal;
  116. // eStopReasonException
  117. struct {
  118. uint64_t type;
  119. uint32_t data_count;
  120. lldb::addr_t data[8];
  121. } exception;
  122. // eStopReasonFork / eStopReasonVFork
  123. struct {
  124. lldb::pid_t child_pid;
  125. lldb::tid_t child_tid;
  126. } fork;
  127. } details;
  128. };
  129. }
  130. #endif // LLDB_HOST_DEBUG_H