1 //===-- LLDBUtils.cpp -------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
16 bool RunLLDBCommands(llvm::StringRef prefix
,
17 const llvm::ArrayRef
<std::string
> &commands
,
18 llvm::raw_ostream
&strm
, bool parse_command_directives
) {
22 bool did_print_prefix
= false;
24 lldb::SBCommandInterpreter interp
= g_dap
.debugger
.GetCommandInterpreter();
25 for (llvm::StringRef command
: commands
) {
26 lldb::SBCommandReturnObject result
;
27 bool quiet_on_success
= false;
28 bool check_error
= false;
30 while (parse_command_directives
) {
31 if (command
.starts_with("?")) {
32 command
= command
.drop_front();
33 quiet_on_success
= true;
34 } else if (command
.starts_with("!")) {
35 command
= command
.drop_front();
43 // Prevent simultaneous calls to HandleCommand, e.g. EventThreadFunction
44 // may asynchronously call RunExitCommands when we are already calling
45 // RunTerminateCommands.
46 static std::mutex handle_command_mutex
;
47 std::lock_guard
<std::mutex
> locker(handle_command_mutex
);
48 interp
.HandleCommand(command
.str().c_str(), result
);
51 const bool got_error
= !result
.Succeeded();
52 // The if statement below is assuming we always print out `!` prefixed
53 // lines. The only time we don't print is when we have `quiet_on_success ==
54 // true` and we don't have an error.
55 if (quiet_on_success
? got_error
: true) {
56 if (!did_print_prefix
&& !prefix
.empty()) {
57 strm
<< prefix
<< "\n";
58 did_print_prefix
= true;
60 strm
<< "(lldb) " << command
<< "\n";
61 auto output_len
= result
.GetOutputSize();
63 const char *output
= result
.GetOutput();
66 auto error_len
= result
.GetErrorSize();
68 const char *error
= result
.GetError();
72 if (check_error
&& got_error
)
73 return false; // Stop running commands.
78 std::string
RunLLDBCommands(llvm::StringRef prefix
,
79 const llvm::ArrayRef
<std::string
> &commands
,
80 bool &required_command_failed
,
81 bool parse_command_directives
) {
82 required_command_failed
= false;
84 llvm::raw_string_ostream
strm(s
);
85 required_command_failed
=
86 !RunLLDBCommands(prefix
, commands
, strm
, parse_command_directives
);
92 RunLLDBCommandsVerbatim(llvm::StringRef prefix
,
93 const llvm::ArrayRef
<std::string
> &commands
) {
94 bool required_command_failed
= false;
95 return RunLLDBCommands(prefix
, commands
, required_command_failed
,
96 /*parse_command_directives=*/false);
99 bool ThreadHasStopReason(lldb::SBThread
&thread
) {
100 switch (thread
.GetStopReason()) {
101 case lldb::eStopReasonTrace
:
102 case lldb::eStopReasonPlanComplete
:
103 case lldb::eStopReasonBreakpoint
:
104 case lldb::eStopReasonWatchpoint
:
105 case lldb::eStopReasonInstrumentation
:
106 case lldb::eStopReasonSignal
:
107 case lldb::eStopReasonException
:
108 case lldb::eStopReasonExec
:
109 case lldb::eStopReasonProcessorTrace
:
110 case lldb::eStopReasonFork
:
111 case lldb::eStopReasonVFork
:
112 case lldb::eStopReasonVForkDone
:
114 case lldb::eStopReasonThreadExiting
:
115 case lldb::eStopReasonInvalid
:
116 case lldb::eStopReasonNone
:
122 static uint32_t constexpr THREAD_INDEX_SHIFT
= 19;
124 uint32_t GetLLDBThreadIndexID(uint64_t dap_frame_id
) {
125 return dap_frame_id
>> THREAD_INDEX_SHIFT
;
128 uint32_t GetLLDBFrameID(uint64_t dap_frame_id
) {
129 return dap_frame_id
& ((1u << THREAD_INDEX_SHIFT
) - 1);
132 int64_t MakeDAPFrameID(lldb::SBFrame
&frame
) {
133 return ((int64_t)frame
.GetThread().GetIndexID() << THREAD_INDEX_SHIFT
) |
137 } // namespace lldb_dap