cmDebuggerThread.cxx 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmDebuggerThread.h"
  4. #include <cstdint>
  5. #include <utility>
  6. #include <cm3p/cppdap/optional.h>
  7. #include <cm3p/cppdap/types.h>
  8. #include "cmDebuggerStackFrame.h"
  9. #include "cmDebuggerVariables.h"
  10. #include "cmDebuggerVariablesHelper.h"
  11. #include "cmDebuggerVariablesManager.h"
  12. #include "cmListFileCache.h"
  13. #include "cmStringAlgorithms.h"
  14. namespace cmDebugger {
  15. cmDebuggerThread::cmDebuggerThread(int64_t id, std::string name)
  16. : Id(id)
  17. , Name(std::move(name))
  18. , VariablesManager(std::make_shared<cmDebuggerVariablesManager>())
  19. {
  20. }
  21. void cmDebuggerThread::PushStackFrame(cmMakefile* mf,
  22. std::string const& sourcePath,
  23. cmListFileFunction const& lff)
  24. {
  25. std::unique_lock<std::mutex> lock(Mutex);
  26. Frames.emplace_back(
  27. std::make_shared<cmDebuggerStackFrame>(mf, sourcePath, lff));
  28. FrameMap.insert({ Frames.back()->GetId(), Frames.back() });
  29. }
  30. void cmDebuggerThread::PopStackFrame()
  31. {
  32. std::unique_lock<std::mutex> lock(Mutex);
  33. FrameMap.erase(Frames.back()->GetId());
  34. FrameScopes.erase(Frames.back()->GetId());
  35. FrameVariables.erase(Frames.back()->GetId());
  36. Frames.pop_back();
  37. }
  38. std::shared_ptr<cmDebuggerStackFrame> cmDebuggerThread::GetTopStackFrame()
  39. {
  40. std::unique_lock<std::mutex> lock(Mutex);
  41. if (!Frames.empty()) {
  42. return Frames.back();
  43. }
  44. return {};
  45. }
  46. std::shared_ptr<cmDebuggerStackFrame> cmDebuggerThread::GetStackFrame(
  47. int64_t frameId)
  48. {
  49. std::unique_lock<std::mutex> lock(Mutex);
  50. auto it = FrameMap.find(frameId);
  51. if (it == FrameMap.end()) {
  52. return {};
  53. }
  54. return it->second;
  55. }
  56. dap::ScopesResponse cmDebuggerThread::GetScopesResponse(
  57. int64_t frameId, bool supportsVariableType)
  58. {
  59. std::unique_lock<std::mutex> lock(Mutex);
  60. auto it = FrameScopes.find(frameId);
  61. if (it != FrameScopes.end()) {
  62. dap::ScopesResponse response;
  63. response.scopes = it->second;
  64. return response;
  65. }
  66. auto it2 = FrameMap.find(frameId);
  67. if (it2 == FrameMap.end()) {
  68. return dap::ScopesResponse();
  69. }
  70. std::shared_ptr<cmDebuggerStackFrame> frame = it2->second;
  71. std::shared_ptr<cmDebuggerVariables> localVariables =
  72. cmDebuggerVariablesHelper::Create(VariablesManager, "Locals",
  73. supportsVariableType, frame);
  74. FrameVariables[frameId].emplace_back(localVariables);
  75. dap::Scope scope;
  76. scope.name = localVariables->GetName();
  77. scope.presentationHint = "locals";
  78. scope.variablesReference = localVariables->GetId();
  79. dap::Source source;
  80. source.name = frame->GetFileName();
  81. source.path = source.name;
  82. scope.source = source;
  83. FrameScopes[frameId].push_back(scope);
  84. dap::ScopesResponse response;
  85. response.scopes.push_back(scope);
  86. return response;
  87. }
  88. dap::VariablesResponse cmDebuggerThread::GetVariablesResponse(
  89. dap::VariablesRequest const& request)
  90. {
  91. std::unique_lock<std::mutex> lock(Mutex);
  92. dap::VariablesResponse response;
  93. response.variables = VariablesManager->HandleVariablesRequest(request);
  94. return response;
  95. }
  96. dap::StackTraceResponse GetStackTraceResponse(
  97. std::shared_ptr<cmDebuggerThread> const& thread,
  98. dap::optional<dap::StackFrameFormat> format)
  99. {
  100. dap::boolean showParameters = false;
  101. dap::boolean showParameterValues = false;
  102. dap::boolean showLine = false;
  103. if (format.has_value()) {
  104. auto formatValue = format.value();
  105. if (formatValue.parameters.has_value()) {
  106. showParameters = formatValue.parameters.value();
  107. }
  108. if (formatValue.parameterValues.has_value()) {
  109. showParameterValues = formatValue.parameterValues.value();
  110. }
  111. if (formatValue.line.has_value()) {
  112. showLine = formatValue.line.value();
  113. }
  114. }
  115. dap::StackTraceResponse response;
  116. std::unique_lock<std::mutex> lock(thread->Mutex);
  117. for (int i = static_cast<int>(thread->Frames.size()) - 1; i >= 0; --i) {
  118. dap::Source source;
  119. source.name = thread->Frames[i]->GetFileName();
  120. source.path = source.name;
  121. #ifdef __GNUC__
  122. # pragma GCC diagnostic push
  123. # pragma GCC diagnostic ignored "-Warray-bounds"
  124. #endif
  125. dap::StackFrame stackFrame;
  126. #ifdef __GNUC__
  127. # pragma GCC diagnostic pop
  128. #endif
  129. stackFrame.line = thread->Frames[i]->GetLine();
  130. stackFrame.column = 1;
  131. stackFrame.id = thread->Frames[i]->GetId();
  132. stackFrame.source = source;
  133. auto stackName = thread->Frames[i]->GetFunction().OriginalName();
  134. if (showParameters) {
  135. stackName.push_back('(');
  136. if (showParameterValues && !thread->Frames[i]->GetArguments().empty()) {
  137. for (auto const& arg : thread->Frames[i]->GetArguments()) {
  138. stackName = cmStrCat(stackName, arg.Value, ", ");
  139. }
  140. stackName.erase(stackName.end() - 2, stackName.end());
  141. }
  142. stackName.push_back(')');
  143. }
  144. if (showLine) {
  145. stackName =
  146. cmStrCat(stackName, " Line: ", static_cast<int64_t>(stackFrame.line));
  147. }
  148. stackFrame.name = stackName;
  149. response.stackFrames.push_back(stackFrame);
  150. }
  151. response.totalFrames = response.stackFrames.size();
  152. return response;
  153. }
  154. } // namespace cmDebugger