[Lldb-commits] [PATCH] D154029: [lldb-vscode] Adding support for column break points.
This revision was automatically updated to reflect the committed changes. Closed by commit rGda59370b0977: [lldb-vscode] Adding support for column break points. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154029/new/ https://reviews.llvm.org/D154029 Files: lldb/tools/lldb-vscode/JSONUtils.cpp lldb/tools/lldb-vscode/JSONUtils.h lldb/tools/lldb-vscode/SourceBreakpoint.cpp Index: lldb/tools/lldb-vscode/SourceBreakpoint.cpp === --- lldb/tools/lldb-vscode/SourceBreakpoint.cpp +++ lldb/tools/lldb-vscode/SourceBreakpoint.cpp @@ -16,7 +16,9 @@ column(GetUnsigned(obj, "column", 0)) {} void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) { - bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line); + lldb::SBFileSpecList module_list; + bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line, + column, 0, module_list); // See comments in BreakpointBase::GetBreakpointLabel() for details of why // we add a label to our breakpoints. bp.AddName(GetBreakpointLabel()); Index: lldb/tools/lldb-vscode/JSONUtils.h === --- lldb/tools/lldb-vscode/JSONUtils.h +++ lldb/tools/lldb-vscode/JSONUtils.h @@ -232,13 +232,21 @@ /// provided by the setBreakpoints request are returned to the IDE as a /// fallback. /// +/// \param[in] request_column +/// An optional column to use when creating the resulting "Breakpoint" object. +/// It is used if the breakpoint has no valid locations. +/// It is useful to ensure the same column +/// provided by the setBreakpoints request are returned to the IDE as a +/// fallback. +/// /// \return /// A "Breakpoint" JSON object with that follows the formal JSON /// definition outlined by Microsoft. llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp, std::optional request_path = std::nullopt, - std::optional request_line = std::nullopt); + std::optional request_line = std::nullopt, + std::optional request_column = std::nullopt); /// Converts a LLDB module to a VS Code DAP module for use in "modules" events. /// Index: lldb/tools/lldb-vscode/JSONUtils.cpp === --- lldb/tools/lldb-vscode/JSONUtils.cpp +++ lldb/tools/lldb-vscode/JSONUtils.cpp @@ -308,7 +308,8 @@ // } llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp, std::optional request_path, - std::optional request_line) { + std::optional request_line, + std::optional request_column) { // Each breakpoint location is treated as a separate breakpoint for VS code. // They don't have the notion of a single breakpoint with multiple locations. llvm::json::Object object; @@ -345,11 +346,16 @@ const auto line = line_entry.GetLine(); if (line != UINT32_MAX) object.try_emplace("line", line); +const auto column = line_entry.GetColumn(); +if (column != 0) + object.try_emplace("column", column); object.try_emplace("source", CreateSource(line_entry)); } // We try to add request_line as a fallback if (request_line) object.try_emplace("line", *request_line); + if (request_column) +object.try_emplace("column", *request_column); return llvm::json::Value(std::move(object)); } Index: lldb/tools/lldb-vscode/SourceBreakpoint.cpp === --- lldb/tools/lldb-vscode/SourceBreakpoint.cpp +++ lldb/tools/lldb-vscode/SourceBreakpoint.cpp @@ -16,7 +16,9 @@ column(GetUnsigned(obj, "column", 0)) {} void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) { - bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line); + lldb::SBFileSpecList module_list; + bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line, + column, 0, module_list); // See comments in BreakpointBase::GetBreakpointLabel() for details of why // we add a label to our breakpoints. bp.AddName(GetBreakpointLabel()); Index: lldb/tools/lldb-vscode/JSONUtils.h === --- lldb/tools/lldb-vscode/JSONUtils.h +++ lldb/tools/lldb-vscode/JSONUtils.h @@ -232,13 +232,21 @@ /// provided by the setBreakpoints request are returned to the IDE as a /// fallback. /// +/// \param[in] request_column +/// An optional column to use when creating the resulting "Breakpoint" object. +/// It is used if the breakpoint has no valid locations
[Lldb-commits] [PATCH] D154030: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.
This revision was automatically updated to reflect the committed changes. Closed by commit rG16317f1ced77: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl… (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154030/new/ https://reviews.llvm.org/D154030 Files: lldb/tools/lldb-vscode/Options.td lldb/tools/lldb-vscode/README.md lldb/tools/lldb-vscode/VSCode.cpp lldb/tools/lldb-vscode/VSCode.h lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1065,50 +1065,63 @@ FillResponse(request, response); llvm::json::Object body; auto arguments = request.getObject("arguments"); + + // If we have a frame, try to set the context for variable completions. + lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments); + if (frame.IsValid()) { +frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread()); +frame.GetThread().SetSelectedFrame(frame.GetFrameID()); + } + std::string text = std::string(GetString(arguments, "text")); auto original_column = GetSigned(arguments, "column", text.size()); - auto actual_column = original_column - 1; + auto original_line = GetSigned(arguments, "line", 1); + auto offset = original_column - 1; + if (original_line > 1) { +llvm::StringRef text_ref{text}; +::llvm::SmallVector<::llvm::StringRef, 2> lines; +text_ref.split(lines, '\n'); +for (int i = 0; i < original_line - 1; i++) { + offset += lines[i].size(); +} + } llvm::json::Array targets; - // NOTE: the 'line' argument is not needed, as multiline expressions - // work well already - // TODO: support frameID. Currently - // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions - // is frame-unaware. - - if (!text.empty() && text[0] == '`') { -text = text.substr(1); -actual_column--; - } else { -char command[] = "expression -- "; + + if (g_vsc.DetectExpressionContext(frame, text) == + ExpressionContext::Variable) { +char command[] = "frame variable "; text = command + text; -actual_column += strlen(command); +offset += strlen(command); } lldb::SBStringList matches; lldb::SBStringList descriptions; - g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions( - text.c_str(), actual_column, 0, -1, matches, descriptions); - size_t count = std::min((uint32_t)100, matches.GetSize()); - targets.reserve(count); - for (size_t i = 0; i < count; i++) { -std::string match = matches.GetStringAtIndex(i); -std::string description = descriptions.GetStringAtIndex(i); - -llvm::json::Object item; - -llvm::StringRef match_ref = match; -for (llvm::StringRef commit_point : {".", "->"}) { - if (match_ref.contains(commit_point)) { -match_ref = match_ref.rsplit(commit_point).second; + + if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions( + text.c_str(), offset, 0, 100, matches, descriptions)) { +// The first element is the common substring after the cursor position for +// all the matches. The rest of the elements are the matches. +targets.reserve(matches.GetSize() - 1); +std::string common_pattern = matches.GetStringAtIndex(0); +for (size_t i = 1; i < matches.GetSize(); i++) { + std::string match = matches.GetStringAtIndex(i); + std::string description = descriptions.GetStringAtIndex(i); + + llvm::json::Object item; + llvm::StringRef match_ref = match; + for (llvm::StringRef commit_point : {".", "->"}) { +if (match_ref.contains(commit_point)) { + match_ref = match_ref.rsplit(commit_point).second; +} } -} -EmplaceSafeString(item, "text", match_ref); + EmplaceSafeString(item, "text", match_ref); -if (description.empty()) - EmplaceSafeString(item, "label", match); -else - EmplaceSafeString(item, "label", match + " -- " + description); + if (description.empty()) +EmplaceSafeString(item, "label", match); + else +EmplaceSafeString(item, "label", match + " -- " + description); -targets.emplace_back(std::move(item)); + targets.emplace_back(std::move(item)); +} } body.try_emplace("targets", std::move(targets)); @@ -1223,12 +1236,17 @@ llvm::json::Object body; auto arguments = request.getObject("arguments"); lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments); - const auto expression = GetString(arguments, "expression"); + std::string expression = GetString(arguments, "expression").str(); llvm::StringRef context = GetString(arguments, "context"); - if (!expression.empty() && expression[0] == '`') { -auto result = -RunLLDBCommands(llvm::StringRef(), {std:
[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.
dgoldman added inline comments. Comment at: lldb/tools/lldb-vscode/lldb-vscode.cpp:285 if (num_threads_with_reason == 0) { lldb::SBThread thread = process.GetThreadAtIndex(0); g_vsc.SendJSON(CreateThreadStopped(thread, stop_id)); Should we also set g_vsc.focus_tid here if it's invalid? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154989/new/ https://reviews.llvm.org/D154989 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D155248: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl expressions to allow users to more easily invoke lldb commands.
This revision was automatically updated to reflect the committed changes. Closed by commit rG3d1f89c2e37c: [lldb-vscode] Creating a new flag for adjusting the behavior of evaluation repl… (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D155248/new/ https://reviews.llvm.org/D155248 Files: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py lldb/test/API/tools/lldb-vscode/completions/TestVSCode_completions.py lldb/test/API/tools/lldb-vscode/console/TestVSCode_console.py lldb/test/API/tools/lldb-vscode/module/TestVSCode_module.py lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py lldb/tools/lldb-vscode/Options.td lldb/tools/lldb-vscode/README.md lldb/tools/lldb-vscode/VSCode.cpp lldb/tools/lldb-vscode/VSCode.h lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1065,50 +1065,62 @@ FillResponse(request, response); llvm::json::Object body; auto arguments = request.getObject("arguments"); - std::string text = std::string(GetString(arguments, "text")); + + // If we have a frame, try to set the context for variable completions. + lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments); + if (frame.IsValid()) { +frame.GetThread().GetProcess().SetSelectedThread(frame.GetThread()); +frame.GetThread().SetSelectedFrame(frame.GetFrameID()); + } + + std::string text = GetString(arguments, "text").str(); auto original_column = GetSigned(arguments, "column", text.size()); - auto actual_column = original_column - 1; + auto original_line = GetSigned(arguments, "line", 1); + auto offset = original_column - 1; + if (original_line > 1) { +llvm::SmallVector<::llvm::StringRef, 2> lines; +llvm::StringRef(text).split(lines, '\n'); +for (int i = 0; i < original_line - 1; i++) { + offset += lines[i].size(); +} + } llvm::json::Array targets; - // NOTE: the 'line' argument is not needed, as multiline expressions - // work well already - // TODO: support frameID. Currently - // g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions - // is frame-unaware. - - if (!text.empty() && text[0] == '`') { -text = text.substr(1); -actual_column--; - } else { + + if (g_vsc.DetectExpressionContext(frame, text) == + ExpressionContext::Variable) { char command[] = "expression -- "; text = command + text; -actual_column += strlen(command); +offset += strlen(command); } lldb::SBStringList matches; lldb::SBStringList descriptions; - g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions( - text.c_str(), actual_column, 0, -1, matches, descriptions); - size_t count = std::min((uint32_t)100, matches.GetSize()); - targets.reserve(count); - for (size_t i = 0; i < count; i++) { -std::string match = matches.GetStringAtIndex(i); -std::string description = descriptions.GetStringAtIndex(i); - -llvm::json::Object item; - -llvm::StringRef match_ref = match; -for (llvm::StringRef commit_point : {".", "->"}) { - if (match_ref.contains(commit_point)) { -match_ref = match_ref.rsplit(commit_point).second; + + if (g_vsc.debugger.GetCommandInterpreter().HandleCompletionWithDescriptions( + text.c_str(), offset, 0, 100, matches, descriptions)) { +// The first element is the common substring after the cursor position for +// all the matches. The rest of the elements are the matches so ignore the +// first result. +targets.reserve(matches.GetSize() - 1); +for (size_t i = 1; i < matches.GetSize(); i++) { + std::string match = matches.GetStringAtIndex(i); + std::string description = descriptions.GetStringAtIndex(i); + + llvm::json::Object item; + llvm::StringRef match_ref = match; + for (llvm::StringRef commit_point : {".", "->"}) { +if (match_ref.contains(commit_point)) { + match_ref = match_ref.rsplit(commit_point).second; +} } -} -EmplaceSafeString(item, "text", match_ref); + EmplaceSafeString(item, "text", match_ref); -if (description.empty()) - EmplaceSafeString(item, "label", match); -else - EmplaceSafeString(item, "label", match + " -- " + description); + if (description.empty()) +EmplaceSafeString(item, "label", match); + else +EmplaceSafeString(item, "label", match + " -- " + description); -targets.emplace_back(std::move(item)); + targets.emplace_back(std::move(item)); +} } body.try_emplace("targets", std::move(targets)); @@ -1223,12 +1235,17 @@ llvm::json::Object body; auto arguments = request.getObject("arguments"); lldb::SBFrame frame = g_vsc.GetLLDBFrame(*arguments); - const auto
[Lldb-commits] [PATCH] D154989: [lldb-vsocde] Add a 'continued' event for programmatic continue events.
This revision was automatically updated to reflect the committed changes. Closed by commit rG3ab73a398422: [lldb-vsocde] Add a 'continued' event for programmatic continue events. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154989/new/ https://reviews.llvm.org/D154989 Files: lldb/tools/lldb-vscode/JSONUtils.cpp lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -191,6 +191,28 @@ g_vsc.SendJSON(llvm::json::Value(std::move(event))); } +// Send a "continued" event to indicate the process is in the running state. +void SendContinuedEvent() { + lldb::SBProcess process = g_vsc.target.GetProcess(); + if (!process.IsValid()) { +return; + } + + // If the focus thread is not set then we haven't reported any thread status + // to the client, so nothing to report. + if (!g_vsc.configuration_done_sent || + g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) { +return; + } + + llvm::json::Object event(CreateEventObject("continued")); + llvm::json::Object body; + body.try_emplace("threadId", (int64_t)g_vsc.focus_tid); + body.try_emplace("allThreadsContinued", true); + event.try_emplace("body", std::move(body)); + g_vsc.SendJSON(llvm::json::Value(std::move(event))); +} + // Send a "terminated" event to indicate the process is done being // debugged. void SendTerminatedEvent() { @@ -252,7 +274,7 @@ } } - // We will have cleared g_vsc.focus_tid if he focus thread doesn't have + // We will have cleared g_vsc.focus_tid if the focus thread doesn't have // a stop reason, so if it was cleared, or wasn't set, or doesn't exist, // then set the focus thread to the first thread with a stop reason. if (!focus_thread_exists || g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) @@ -262,6 +284,7 @@ // we at least let the UI know we stopped. if (num_threads_with_reason == 0) { lldb::SBThread thread = process.GetThreadAtIndex(0); +g_vsc.focus_tid = thread.GetThreadID(); g_vsc.SendJSON(CreateThreadStopped(thread, stop_id)); } else { for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) { @@ -468,6 +491,7 @@ break; case lldb::eStateRunning: g_vsc.WillContinue(); +SendContinuedEvent(); break; case lldb::eStateExited: // When restarting, we can get an "exited" event for the process we @@ -766,10 +790,6 @@ llvm::json::Object response; FillResponse(request, response); lldb::SBProcess process = g_vsc.target.GetProcess(); - auto arguments = request.getObject("arguments"); - // Remember the thread ID that caused the resume so we can set the - // "threadCausedFocus" boolean value in the "stopped" events. - g_vsc.focus_tid = GetUnsigned(arguments, "threadId", LLDB_INVALID_THREAD_ID); lldb::SBError error = process.Continue(); llvm::json::Object body; body.try_emplace("allThreadsContinued", true); Index: lldb/tools/lldb-vscode/JSONUtils.cpp === --- lldb/tools/lldb-vscode/JSONUtils.cpp +++ lldb/tools/lldb-vscode/JSONUtils.cpp @@ -907,6 +907,8 @@ uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1); snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64, bp_id, bp_loc_id); + body.try_emplace("hitBreakpointIds", + llvm::json::Array{llvm::json::Value(bp_id)}); EmplaceSafeString(body, "description", desc_str); } } break; @@ -951,6 +953,7 @@ EmplaceSafeString(body, "description", std::string(description)); } } + // "threadCausedFocus" is used in tests to validate breaking behavior. if (tid == g_vsc.focus_tid) { body.try_emplace("threadCausedFocus", true); } Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -191,6 +191,28 @@ g_vsc.SendJSON(llvm::json::Value(std::move(event))); } +// Send a "continued" event to indicate the process is in the running state. +void SendContinuedEvent() { + lldb::SBProcess process = g_vsc.target.GetProcess(); + if (!process.IsValid()) { +return; + } + + // If the focus thread is not set then we haven't reported any thread status + // to the client, so nothing to report. + if (!g_vsc.configuration_done_sent || + g_vsc.focus_tid == LLDB_INVALID_THREAD_ID) { +return; + } + + llvm::json::Object event(CreateEventObject("continued")); + llvm::json::Object body; + body.try_emplace("threadId", (int64_t)g_vsc.focus_tid); + body.try_emplace("allThr
[Lldb-commits] [PATCH] D154990: [lldb-vsocde] Cleaning up the usage of the Separate helper in Options.td.
This revision was automatically updated to reflect the committed changes. Closed by commit rG011cc6d8bfba: [lldb-vsocde] Cleaning up the usage of the Separate helper in Options.td. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154990/new/ https://reviews.llvm.org/D154990 Files: lldb/tools/lldb-vscode/Options.td Index: lldb/tools/lldb-vscode/Options.td === --- lldb/tools/lldb-vscode/Options.td +++ lldb/tools/lldb-vscode/Options.td @@ -17,25 +17,25 @@ Alias, HelpText<"Alias for --wait-for-debugger">; -def port: Separate<["--", "-"], "port">, +def port: S<"port">, MetaVarName<"">, HelpText<"Communicate with the lldb-vscode tool over the defined port.">; def: Separate<["-"], "p">, Alias, HelpText<"Alias for --port">; -def launch_target: Separate<["--", "-"], "launch-target">, +def launch_target: S<"launch-target">, MetaVarName<"">, HelpText<"Launch a target for the launchInTerminal request. Any argument " "provided after this one will be passed to the target. The parameter " "--comm-file must also be specified.">; -def comm_file: Separate<["--", "-"], "comm-file">, +def comm_file: S<"comm-file">, MetaVarName<"">, HelpText<"The fifo file used to communicate the with the debug adaptor " "when using --launch-target.">; -def debugger_pid: Separate<["--", "-"], "debugger-pid">, +def debugger_pid: S<"debugger-pid">, MetaVarName<"">, HelpText<"The PID of the lldb-vscode instance that sent the launchInTerminal " "request when using --launch-target.">; Index: lldb/tools/lldb-vscode/Options.td === --- lldb/tools/lldb-vscode/Options.td +++ lldb/tools/lldb-vscode/Options.td @@ -17,25 +17,25 @@ Alias, HelpText<"Alias for --wait-for-debugger">; -def port: Separate<["--", "-"], "port">, +def port: S<"port">, MetaVarName<"">, HelpText<"Communicate with the lldb-vscode tool over the defined port.">; def: Separate<["-"], "p">, Alias, HelpText<"Alias for --port">; -def launch_target: Separate<["--", "-"], "launch-target">, +def launch_target: S<"launch-target">, MetaVarName<"">, HelpText<"Launch a target for the launchInTerminal request. Any argument " "provided after this one will be passed to the target. The parameter " "--comm-file must also be specified.">; -def comm_file: Separate<["--", "-"], "comm-file">, +def comm_file: S<"comm-file">, MetaVarName<"">, HelpText<"The fifo file used to communicate the with the debug adaptor " "when using --launch-target.">; -def debugger_pid: Separate<["--", "-"], "debugger-pid">, +def debugger_pid: S<"debugger-pid">, MetaVarName<"">, HelpText<"The PID of the lldb-vscode instance that sent the launchInTerminal " "request when using --launch-target.">; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [PATCH] D156465: [lldb-vscode] Adding support for displaying backtraces.
This revision was automatically updated to reflect the committed changes. Closed by commit rG1bf6f55911ca: [lldb-vscode] Adding support for displaying backtraces. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D156465/new/ https://reviews.llvm.org/D156465 Files: lldb/tools/lldb-vscode/JSONUtils.cpp lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -2687,13 +2687,72 @@ const auto startFrame = GetUnsigned(arguments, "startFrame", 0); const auto levels = GetUnsigned(arguments, "levels", 0); const auto endFrame = (levels == 0) ? INT64_MAX : (startFrame + levels); +auto totalFrames = thread.GetNumFrames(); + +// This will always return an invalid thread when +// libBacktraceRecording.dylib is not loaded or if there is no extended +// backtrace. +lldb::SBThread queue_backtrace_thread = +thread.GetExtendedBacktraceThread("libdispatch"); +if (queue_backtrace_thread.IsValid()) { + // One extra frame as a label to mark the enqueued thread. + totalFrames += queue_backtrace_thread.GetNumFrames() + 1; +} + +// This will always return an invalid thread when there is no exception in +// the current thread. +lldb::SBThread exception_backtrace_thread = +thread.GetCurrentExceptionBacktrace(); +if (exception_backtrace_thread.IsValid()) { + // One extra frame as a label to mark the exception thread. + totalFrames += exception_backtrace_thread.GetNumFrames() + 1; +} + for (uint32_t i = startFrame; i < endFrame; ++i) { - auto frame = thread.GetFrameAtIndex(i); + lldb::SBFrame frame; + std::string prefix; + if (i < thread.GetNumFrames()) { +frame = thread.GetFrameAtIndex(i); + } else if (queue_backtrace_thread.IsValid() && + i < (thread.GetNumFrames() + + queue_backtrace_thread.GetNumFrames() + 1)) { +if (i == thread.GetNumFrames()) { + const uint32_t thread_idx = + queue_backtrace_thread.GetExtendedBacktraceOriginatingIndexID(); + const char *queue_name = queue_backtrace_thread.GetQueueName(); + auto name = llvm::formatv("Enqueued from {0} (Thread {1})", +queue_name, thread_idx); + stackFrames.emplace_back( + llvm::json::Object{{"id", thread.GetThreadID() + 1}, + {"name", name}, + {"presentationHint", "label"}}); + continue; +} +frame = queue_backtrace_thread.GetFrameAtIndex( +i - thread.GetNumFrames() - 1); + } else if (exception_backtrace_thread.IsValid()) { +if (i == thread.GetNumFrames() + + (queue_backtrace_thread.IsValid() + ? queue_backtrace_thread.GetNumFrames() + 1 + : 0)) { + stackFrames.emplace_back( + llvm::json::Object{{"id", thread.GetThreadID() + 2}, + {"name", "Original Exception Backtrace"}, + {"presentationHint", "label"}}); + continue; +} + +frame = exception_backtrace_thread.GetFrameAtIndex( +i - thread.GetNumFrames() - +(queue_backtrace_thread.IsValid() + ? queue_backtrace_thread.GetNumFrames() + 1 + : 0)); + } if (!frame.IsValid()) break; stackFrames.emplace_back(CreateStackFrame(frame)); } -const auto totalFrames = thread.GetNumFrames(); + body.try_emplace("totalFrames", totalFrames); } body.try_emplace("stackFrames", std::move(stackFrames)); Index: lldb/tools/lldb-vscode/JSONUtils.cpp === --- lldb/tools/lldb-vscode/JSONUtils.cpp +++ lldb/tools/lldb-vscode/JSONUtils.cpp @@ -815,17 +815,30 @@ llvm::json::Value CreateThread(lldb::SBThread &thread) { llvm::json::Object object; object.try_emplace("id", (int64_t)thread.GetThreadID()); - char thread_str[64]; - snprintf(thread_str, sizeof(thread_str), "Thread #%u", thread.GetIndexID()); - const char *name = thread.GetName(); - if (name) { -std::string thread_with_name(thread_str); -thread_with_name += ' '; -thread_with_name += name; -EmplaceSafeString(object, "name", thread_with_name); + const char *thread_name = thread.GetName(); + const char *queue_name = thread.GetQueueName(); + + std::string thread_str; + if (thread_name) { +thread_str = std::string(thread_name); + } else if (queue_name) { +auto kind = thread.GetQueue().GetKind(); +std::string queue_kind_label = ""; +if (kind == lldb::eQueueKindSe
[Lldb-commits] [PATCH] D156493: [lldb-vsocde] Adding support for the "disassemble" request.
This revision was automatically updated to reflect the committed changes. Closed by commit rGca71dc1b5404: [lldb-vscode] Adding support for the "disassemble" request. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D156493/new/ https://reviews.llvm.org/D156493 Files: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py lldb/test/API/tools/lldb-vscode/coreFile/TestVSCode_coreFile.py lldb/test/API/tools/lldb-vscode/disassemble/Makefile lldb/test/API/tools/lldb-vscode/disassemble/TestVSCode_disassemble.py lldb/test/API/tools/lldb-vscode/disassemble/main.c lldb/tools/lldb-vscode/JSONUtils.cpp lldb/tools/lldb-vscode/JSONUtils.h lldb/tools/lldb-vscode/SourceReference.h lldb/tools/lldb-vscode/VSCode.cpp lldb/tools/lldb-vscode/VSCode.h lldb/tools/lldb-vscode/VSCodeForward.h lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -50,6 +50,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" @@ -1563,6 +1564,8 @@ body.try_emplace("supportsStepInTargetsRequest", false); // The debug adapter supports the completions request. body.try_emplace("supportsCompletionsRequest", true); + // The debug adapter supports the disassembly request. + body.try_emplace("supportsDisassembleRequest", true); llvm::json::Array completion_characters; completion_characters.emplace_back("."); @@ -2588,18 +2591,7 @@ void request_source(const llvm::json::Object &request) { llvm::json::Object response; FillResponse(request, response); - llvm::json::Object body; - - auto arguments = request.getObject("arguments"); - auto source = arguments->getObject("source"); - auto sourceReference = GetSigned(source, "sourceReference", -1); - auto pos = g_vsc.source_map.find((lldb::addr_t)sourceReference); - if (pos != g_vsc.source_map.end()) { -EmplaceSafeString(body, "content", pos->second.content); - } else { -response["success"] = llvm::json::Value(false); - } - EmplaceSafeString(body, "mimeType", "text/x-lldb.disassembly"); + llvm::json::Object body{{"content", ""}}; response.try_emplace("body", std::move(body)); g_vsc.SendJSON(llvm::json::Value(std::move(response))); } @@ -3301,6 +3293,211 @@ g_vsc.SendJSON(llvm::json::Value(std::move(response))); } +// "DisassembleRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "Disassembles code stored at the provided +// location.\nClients should only call this request if the corresponding +// capability `supportsDisassembleRequest` is true.", "properties": { +// "command": { +// "type": "string", +// "enum": [ "disassemble" ] +// }, +// "arguments": { +// "$ref": "#/definitions/DisassembleArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// }, +// "DisassembleArguments": { +// "type": "object", +// "description": "Arguments for `disassemble` request.", +// "properties": { +// "memoryReference": { +// "type": "string", +// "description": "Memory reference to the base location containing the +// instructions to disassemble." +// }, +// "offset": { +// "type": "integer", +// "description": "Offset (in bytes) to be applied to the reference +// location before disassembling. Can be negative." +// }, +// "instructionOffset": { +// "type": "integer", +// "description": "Offset (in instructions) to be applied after the byte +// offset (if any) before disassembling. Can be negative." +// }, +// "instructionCount": { +// "type": "integer", +// "description": "Number of instructions to disassemble starting at the +// specified location and offset.\nAn adapter must return exactly this +// number of instructions - any unavailable instructions should be +// replaced with an implementation-defined 'invalid instruction' value." +// }, +// "resolveSymbols": { +// "type": "boolean", +// "description": "If true, the adapter should attempt to resolve memory +// addresses and other values to symbolic names." +// } +// }, +// "required": [ "memoryReference", "instructionCount" ] +// }, +// "DisassembleResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to `disassemble` request.", +// "properties": { +// "body": { +//
[Lldb-commits] [PATCH] D153447: Creating a startDebugging reverse DAP request handler in lldb-vscode.
This revision was automatically updated to reflect the committed changes. Closed by commit rG227b2180eb2b: Creating a startDebugging reverse DAP request handler in lldb-vscode. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D153447/new/ https://reviews.llvm.org/D153447 Files: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py lldb/test/API/tools/lldb-vscode/runInTerminal/TestVSCode_runInTerminal.py lldb/test/API/tools/lldb-vscode/startDebugging/Makefile lldb/test/API/tools/lldb-vscode/startDebugging/TestVSCode_startDebugging.py lldb/test/API/tools/lldb-vscode/startDebugging/main.c lldb/tools/lldb-vscode/JSONUtils.cpp lldb/tools/lldb-vscode/README.md lldb/tools/lldb-vscode/VSCode.cpp lldb/tools/lldb-vscode/VSCode.h lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1471,6 +1471,13 @@ g_vsc.debugger = lldb::SBDebugger::Create(source_init_file, log_cb, nullptr); + auto cmd = g_vsc.debugger.GetCommandInterpreter().AddMultiwordCommand( + "lldb-vscode", nullptr); + cmd.AddCommand( + "startDebugging", &g_vsc.start_debugging_request_handler, + "Sends a startDebugging request from the debug adapter to the client to " + "start a child debug session of the same type as the caller."); + g_vsc.progress_event_thread = std::thread(ProgressEventThreadFunction); // Start our event thread so we can receive events from the debugger, target, @@ -1564,7 +1571,8 @@ g_vsc.SendJSON(llvm::json::Value(std::move(response))); } -llvm::Error request_runInTerminal(const llvm::json::Object &launch_request) { +llvm::Error request_runInTerminal(const llvm::json::Object &launch_request, + const uint64_t timeout_seconds) { g_vsc.is_attach = true; lldb::SBAttachInfo attach_info; @@ -1582,13 +1590,15 @@ #endif llvm::json::Object reverse_request = CreateRunInTerminalReverseRequest( launch_request, g_vsc.debug_adaptor_path, comm_file.m_path, debugger_pid); - llvm::json::Object reverse_response; - lldb_vscode::PacketStatus status = - g_vsc.SendReverseRequest(reverse_request, reverse_response); - if (status != lldb_vscode::PacketStatus::Success) -return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Process cannot be launched by the IDE. %s", - comm_channel.GetLauncherError().c_str()); + g_vsc.SendReverseRequest("runInTerminal", std::move(reverse_request), + [](llvm::Expected value) { + if (!value) { + llvm::Error err = value.takeError(); + llvm::errs() + << "runInTerminal request failed: " + << llvm::toString(std::move(err)) << "\n"; + } + }); if (llvm::Expected pid = comm_channel.GetLauncherPid()) attach_info.SetProcessID(*pid); @@ -1676,7 +1686,7 @@ const uint64_t timeout_seconds = GetUnsigned(arguments, "timeout", 30); if (GetBoolean(arguments, "runInTerminal", false)) { -if (llvm::Error err = request_runInTerminal(request)) +if (llvm::Error err = request_runInTerminal(request, timeout_seconds)) error.SetErrorString(llvm::toString(std::move(err)).c_str()); } else if (launchCommands.empty()) { // Disable async events so the launch will be successful when we return from @@ -3464,17 +3474,13 @@ g_vsc.output.descriptor = StreamDescriptor::from_file(new_stdout_fd, false); } - while (!g_vsc.sent_terminated_event) { -llvm::json::Object object; -lldb_vscode::PacketStatus status = g_vsc.GetNextObject(object); -if (status == lldb_vscode::PacketStatus::EndOfFile) - break; -if (status != lldb_vscode::PacketStatus::Success) - return 1; // Fatal error - -if (!g_vsc.HandleObject(object)) - return 1; + bool CleanExit = true; + if (auto Err = g_vsc.Loop()) { +if (g_vsc.log) + *g_vsc.log << "Transport Error: " << llvm::toString(std::move(Err)) + << "\n"; +CleanExit = false; } - return EXIT_SUCCESS; + return CleanExit ? EXIT_SUCCESS : EXIT_FAILURE; } Index: lldb/tools/lldb-vscode/VSCode.h === --- lldb/tools/lldb-vscode/VSCode.h +++ lldb/tools/lldb-vscode/VSCode.h @@ -11,8 +11,10 @@ #include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX +#include #include #include +#include #include #include #include @@ -73,6 +75,7 @@ }; typedef void (*RequestCallback)(const llvm::json::Object &command); +typedef void (*ResponseCallbac
[Lldb-commits] [PATCH] D154028: [lldb-vscode] Prior to running the launchCommands during a launch request set the launch info so the configured launch information is accessible by the launch commands.
This revision was automatically updated to reflect the committed changes. Closed by commit rGfc52f8dc6ce2: [lldb-vscode] Prior to running the launchCommands during a launch request set… (authored by ashgti, committed by dgoldman). Changed prior to commit: https://reviews.llvm.org/D154028?vs=535576&id=535943#toc Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154028/new/ https://reviews.llvm.org/D154028 Files: lldb/tools/lldb-vscode/README.md lldb/tools/lldb-vscode/lldb-vscode.cpp Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1695,6 +1695,9 @@ g_vsc.target.Launch(launch_info, error); g_vsc.debugger.SetAsync(true); } else { +// Set the launch info so that run commands can access the configured +// launch details. +g_vsc.target.SetLaunchInfo(launch_info); g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands); // The custom commands might have created a new target so we should use the // selected target after these commands are run. Index: lldb/tools/lldb-vscode/README.md === --- lldb/tools/lldb-vscode/README.md +++ lldb/tools/lldb-vscode/README.md @@ -95,6 +95,7 @@ |**initCommands** |[string]| | LLDB commands executed upon debugger startup prior to creating the LLDB target. Commands and command output will be sent to the debugger console when they are executed. |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed. |**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed. +|**launchCommands** |[string]| | LLDB commands executed to launch the program. Commands and command output will be sent to the debugger console when they are executed. |**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed. |**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed. |**sourceMap** |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname. Index: lldb/tools/lldb-vscode/lldb-vscode.cpp === --- lldb/tools/lldb-vscode/lldb-vscode.cpp +++ lldb/tools/lldb-vscode/lldb-vscode.cpp @@ -1695,6 +1695,9 @@ g_vsc.target.Launch(launch_info, error); g_vsc.debugger.SetAsync(true); } else { +// Set the launch info so that run commands can access the configured +// launch details. +g_vsc.target.SetLaunchInfo(launch_info); g_vsc.RunLLDBCommands("Running launchCommands:", launchCommands); // The custom commands might have created a new target so we should use the // selected target after these commands are run. Index: lldb/tools/lldb-vscode/README.md === --- lldb/tools/lldb-vscode/README.md +++ lldb/tools/lldb-vscode/README.md @@ -95,6 +95,7 @@ |**initCommands** |[string]| | LLDB commands executed upon debugger startup prior to creating the LLDB target. Commands and command output will be sent to the debugger console when they are executed. |**preRunCommands** |[string]| | LLDB commands executed just before launching after the LLDB target has been created. Commands and command output will be sent to the debugger console when they are executed. |**stopCommands** |[string]| | LLDB commands executed just after each stop. Commands and command output will be sent to the debugger console when they are executed. +|**launchCommands** |[string]| | LLDB commands executed to launch the program. Commands and command output will be sent to the debugger console when they are executed. |**exitCommands** |[string]| | LLDB commands executed when the program exits. Commands and command output will be sent to the debugger console when they are executed. |**terminateCommands** |[string]| | LLDB commands executed when the debugging session ends. Commands and command output will be sent to the debugger console when they are executed. |**sourceMap** |[string[2]]| | Specify an array of path re-mappings. Each element in the array must be a two element array containing a source and destination pathname. ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-
[Lldb-commits] [PATCH] D154026: [lldb-vscode] Adjusting CreateSource to detect compiler generated frames.
This revision was automatically updated to reflect the committed changes. Closed by commit rGb9b0ab32f9d0: [lldb-vscode] Adjusting CreateSource to detect compiler generated frames. (authored by ashgti, committed by dgoldman). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D154026/new/ https://reviews.llvm.org/D154026 Files: lldb/tools/lldb-vscode/JSONUtils.cpp Index: lldb/tools/lldb-vscode/JSONUtils.cpp === --- lldb/tools/lldb-vscode/JSONUtils.cpp +++ lldb/tools/lldb-vscode/JSONUtils.cpp @@ -613,7 +613,9 @@ llvm::json::Value CreateSource(lldb::SBFrame &frame, int64_t &disasm_line) { disasm_line = 0; auto line_entry = frame.GetLineEntry(); - if (line_entry.GetFileSpec().IsValid()) + // A line entry of 0 indicates the line is compiler generated i.e. no source + // file so don't return early with the line entry. + if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0) return CreateSource(line_entry); llvm::json::Object object; @@ -650,7 +652,11 @@ } const auto num_insts = insts.GetSize(); if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) { -EmplaceSafeString(object, "name", frame.GetFunctionName()); +if (line_entry.GetLine() == 0) { + EmplaceSafeString(object, "name", ""); +} else { + EmplaceSafeString(object, "name", frame.GetDisplayFunctionName()); +} SourceReference source; llvm::raw_string_ostream src_strm(source.content); std::string line; Index: lldb/tools/lldb-vscode/JSONUtils.cpp === --- lldb/tools/lldb-vscode/JSONUtils.cpp +++ lldb/tools/lldb-vscode/JSONUtils.cpp @@ -613,7 +613,9 @@ llvm::json::Value CreateSource(lldb::SBFrame &frame, int64_t &disasm_line) { disasm_line = 0; auto line_entry = frame.GetLineEntry(); - if (line_entry.GetFileSpec().IsValid()) + // A line entry of 0 indicates the line is compiler generated i.e. no source + // file so don't return early with the line entry. + if (line_entry.GetFileSpec().IsValid() && line_entry.GetLine() != 0) return CreateSource(line_entry); llvm::json::Object object; @@ -650,7 +652,11 @@ } const auto num_insts = insts.GetSize(); if (low_pc != LLDB_INVALID_ADDRESS && num_insts > 0) { -EmplaceSafeString(object, "name", frame.GetFunctionName()); +if (line_entry.GetLine() == 0) { + EmplaceSafeString(object, "name", ""); +} else { + EmplaceSafeString(object, "name", frame.GetDisplayFunctionName()); +} SourceReference source; llvm::raw_string_ostream src_strm(source.content); std::string line; ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits