[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
@@ -0,0 +1,103 @@ +import * as vscode from "vscode"; +import * as child_process from "child_process"; +import * as util from "util"; +import { LLDBDapServer } from "./lldb-dap-server"; +import { createDebugAdapterExecutable } from "./debug-adapter-factory"; +import { ConfigureButton, showErrorMessage } from "./ui/show-error-message"; +import { ErrorWithNotification } from "./ui/error-with-notification"; + +const exec = util.promisify(child_process.execFile); + +/** + * Determines whether or not the given lldb-dap executable supports executing + * in server mode. + * + * @param exe the path to the lldb-dap executable + * @returns a boolean indicating whether or not lldb-dap supports server mode + */ +async function isServerModeSupported(exe: string): Promise { + const { stdout } = await exec(exe, ["--help"]); + return /--connection/.test(stdout); +} + +export class LLDBDapConfigurationProvider + implements vscode.DebugConfigurationProvider +{ + constructor(private readonly server: LLDBDapServer) {} + + async resolveDebugConfiguration( +folder: vscode.WorkspaceFolder | undefined, +debugConfiguration: vscode.DebugConfiguration, matthewbastien wrote: I really like this idea! Playing around with your code locally, I found that we would also need some more complex validators for things like making sure `debugAdapterPort` and `debugAdapterExecutable` aren't set together. Would also be nice to have some of the validators coerce strings to numbers for things like the port information which accept both. I think this definitely warrants a separate PR that consolidates the validation logic. https://github.com/llvm/llvm-project/pull/129262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Show target.debug-file-search-paths setting from python SBDebugger (PR #131683)
https://github.com/da-viper closed https://github.com/llvm/llvm-project/pull/131683 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Target] Clear selected frame index after a StopInfo::PerformAction (PR #133078)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/133078 >From 91110b85aab9ddf41d1b52b9fc23d68883966b93 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 26 Mar 2025 13:20:24 + Subject: [PATCH 1/2] [lldb][Target] Clear selected frame index after a StopInfo::PerformAction --- lldb/include/lldb/Target/StackFrameList.h | 3 +++ lldb/include/lldb/Target/Thread.h | 5 + lldb/source/Target/Process.cpp| 2 ++ lldb/source/Target/StackFrameList.cpp | 4 4 files changed, 14 insertions(+) diff --git a/lldb/include/lldb/Target/StackFrameList.h b/lldb/include/lldb/Target/StackFrameList.h index 8a66296346f2d..d805b644b0b31 100644 --- a/lldb/include/lldb/Target/StackFrameList.h +++ b/lldb/include/lldb/Target/StackFrameList.h @@ -46,6 +46,9 @@ class StackFrameList { /// Mark a stack frame as the currently selected frame and return its index. uint32_t SetSelectedFrame(lldb_private::StackFrame *frame); + /// Resets the selected frame index of this object. + void ClearSelectedFrameIndex(); + /// Get the currently selected frame index. /// We should only call SelectMostRelevantFrame if (a) the user hasn't already /// selected a frame, and (b) if this really is a user facing diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index 1d1e3dcfc1dc6..9eb9cda983c4a 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -480,6 +480,11 @@ class Thread : public std::enable_shared_from_this, bool SetSelectedFrameByIndexNoisily(uint32_t frame_idx, Stream &output_stream); + /// Resets the selected frame index of this object. + void ClearSelectedFrameIndex() { +return GetStackFrameList()->ClearSelectedFrameIndex(); + } + void SetDefaultFileAndLineToSelectedFrame() { GetStackFrameList()->SetDefaultFileAndLineToSelectedFrame(); } diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f2f5598f0ab53..6843d5b220742 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4257,6 +4257,8 @@ bool Process::ProcessEventData::ShouldStop(Event *event_ptr, // appropriately. We also need to stop processing actions, since they // aren't expecting the target to be running. +thread_sp->ClearSelectedFrameIndex(); + // FIXME: we might have run. if (stop_info_sp->HasTargetRunSinceMe()) { SetRestarted(true); diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index 9c6208e9e0a65..3592c3c03db74 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -936,3 +936,7 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame, strm.IndentLess(); return num_frames_displayed; } + +void StackFrameList::ClearSelectedFrameIndex() { + m_selected_frame_idx.reset(); +} >From a7b6bd3f84225875755d0adb6c33c972fba5eaf1 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 26 Mar 2025 13:35:23 + Subject: [PATCH 2/2] fixup! clang-format --- lldb/source/Target/Process.cpp | 6 ++ 1 file changed, 6 insertions(+) diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 6843d5b220742..af805183b24fb 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -4257,6 +4257,12 @@ bool Process::ProcessEventData::ShouldStop(Event *event_ptr, // appropriately. We also need to stop processing actions, since they // aren't expecting the target to be running. +// Clear the selected frame which may have been set as part of utility +// expressions that have been run as part of this stop. If we didn't +// clear this, then StopInfo::GetSuggestedStackFrameIndex would not +// take affect when we next called SelectMostRelevantFrame. PerformAction +// should not be the one setting a selected frame, instead this should be +// done via GetSuggestedStackFrameIndex. thread_sp->ClearSelectedFrameIndex(); // FIXME: we might have run. ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][NFC]Move fields that might be referenced in scope-exit to beginning (PR #133785)
https://github.com/JDevlieghere approved this pull request. https://github.com/llvm/llvm-project/pull/133785 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding support for cancelling a request. (PR #130169)
@@ -778,28 +817,121 @@ llvm::Error DAP::Disconnect(bool terminateDebuggee) { return ToError(error); } +bool DAP::IsCancelled(const protocol::Request &req) { + std::lock_guard lock(m_cancelled_requests_mutex); + return m_cancelled_requests.contains(req.seq); +} + +void DAP::ClearCancelRequest(const CancelArguments &args) { + std::lock_guard cancalled_requests_lock( + m_cancelled_requests_mutex); + if (args.requestId) +m_cancelled_requests.erase(*args.requestId); +} + +template +static std::optional getArgumentsIfRequest(const Message &pm, + llvm::StringLiteral command) { + auto *const req = std::get_if(&pm); + if (!req || req->command != command) +return std::nullopt; + + T args; + llvm::json::Path::Root root; + if (!fromJSON(req->arguments, args, root)) { +return std::nullopt; + } + + return std::move(args); +} + llvm::Error DAP::Loop() { - auto cleanup = llvm::make_scope_exit([this]() { + std::future queue_reader = std::async([&]() -> llvm::Error { labath wrote: I think this should explicitly use the std::launch::async flag as it won't work in the "deferred" policy and "If more than one flag is set, it is implementation-defined which policy is selected." https://github.com/llvm/llvm-project/pull/130169 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Show target.debug-file-search-paths setting from python SBDebugger (PR #131683)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-remote-linux-win` running on `as-builder-10` while building `lldb` at step 17 "test-check-lldb-api". Full details are available at: https://lab.llvm.org/buildbot/#/builders/197/builds/2978 Here is the relevant piece of the build log for the reference ``` Step 17 (test-check-lldb-api) failure: Test just built components: check-lldb-api completed (failure) TEST 'lldb-api :: commands/settings/TestSettings.py' FAILED Script: -- C:/Python312/python.exe C:/buildbot/as-builder-10/lldb-x-aarch64/llvm-project/lldb\test\API\dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=C:/buildbot/as-builder-10/lldb-x-aarch64/build/./lib --env LLVM_INCLUDE_DIR=C:/buildbot/as-builder-10/lldb-x-aarch64/build/include --env LLVM_TOOLS_DIR=C:/buildbot/as-builder-10/lldb-x-aarch64/build/./bin --arch aarch64 --build-dir C:/buildbot/as-builder-10/lldb-x-aarch64/build/lldb-test-build.noindex --lldb-module-cache-dir C:/buildbot/as-builder-10/lldb-x-aarch64/build/lldb-test-build.noindex/module-cache-lldb\lldb-api --clang-module-cache-dir C:/buildbot/as-builder-10/lldb-x-aarch64/build/lldb-test-build.noindex/module-cache-clang\lldb-api --executable C:/buildbot/as-builder-10/lldb-x-aarch64/build/./bin/lldb.exe --compiler C:/buildbot/as-builder-10/lldb-x-aarch64/build/./bin/clang.exe --dsymutil C:/buildbot/as-builder-10/lldb-x-aarch64/build/./bin/dsymutil.exe --make C:/ninja/make.exe --llvm-tools-dir C:/buildbot/as-builder-10/lldb-x-aarch64/build/./bin --lldb-obj-root C:/buildbot/as-builder-10/lldb-x-aarch64/build/tools/lldb --lldb-libs-dir C:/buildbot/as-builder-10/lldb-x-aarch64/build/./lib --platform-url connect://jetson-agx-0086.lab.llvm.org:1234 --platform-working-dir /home/ubuntu/lldb-tests --sysroot c:/buildbot/fs/jetson-agx-ubuntu --env ARCH_CFLAGS=-mcpu=cortex-a78 --platform-name remote-linux --skip-category=lldb-server C:\buildbot\as-builder-10\lldb-x-aarch64\llvm-project\lldb\test\API\commands\settings -p TestSettings.py -- Exit Code: 1 Command Output (stdout): -- lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 4b419840c883b0de03ae72c7d352c37f24c1932c) clang revision 4b419840c883b0de03ae72c7d352c37f24c1932c llvm revision 4b419840c883b0de03ae72c7d352c37f24c1932c Setting up remote platform 'remote-linux' Connecting to remote platform 'remote-linux' at 'connect://jetson-agx-0086.lab.llvm.org:1234'... Connected. Setting remote platform working directory to '/home/ubuntu/lldb-tests'... Skipping the following test categories: ['lldb-server', 'dsym', 'gmodules', 'debugserver', 'objc', 'lldb-dap'] -- Command Output (stderr): -- PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_all_settings_exist (TestSettings.SettingsCommandTestCase.test_all_settings_exist) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_append_target_env_vars (TestSettings.SettingsCommandTestCase.test_append_target_env_vars) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_apropos_should_also_search_settings_description (TestSettings.SettingsCommandTestCase.test_apropos_should_also_search_settings_description) UNSUPPORTED: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_disassembler_settings (TestSettings.SettingsCommandTestCase.test_disassembler_settings) (skipping due to the following parameter(s): architecture) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_experimental_settings (TestSettings.SettingsCommandTestCase.test_experimental_settings) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_global_option (TestSettings.SettingsCommandTestCase.test_global_option) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_insert_before_and_after_target_run_args (TestSettings.SettingsCommandTestCase.test_insert_before_and_after_target_run_args) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_launchsimple_args_and_env_vars (TestSettings.SettingsCommandTestCase.test_launchsimple_args_and_env_vars) UNSUPPORTED: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_pass_host_env_vars (TestSettings.SettingsCommandTestCase.test_pass_host_env_vars) (skip on remote platform) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_print_array_setting (TestSettings.SettingsCommandTestCase.test_print_array_setting) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64) :: test_print_dictionary_setting (TestSettings.SettingsCommandTestCase.test_print_dictionary_setting) PASS: LLDB (C:\buildbot\as-builder-10\lldb-x-aarch64\build\bin\clang.exe-aarch64
[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
@@ -0,0 +1,130 @@ +import * as child_process from "node:child_process"; +import * as vscode from "vscode"; + +function areArraysEqual(lhs: T[], rhs: T[]): boolean { + if (lhs.length !== rhs.length) { +return false; + } + for (let i = 0; i < lhs.length; i++) { +if (lhs[i] !== rhs[i]) { + return false; +} + } + return true; +} matthewbastien wrote: Done. https://github.com/llvm/llvm-project/pull/129262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [lldb] Reland: [clang] preserve class type sugar when taking pointer to member (PR #132401)
rupprecht wrote: Still seeing a crash even with the latest fix applied ``` assertion failed at clang/include/clang/AST/Type.h:945 in const ExtQualsTypeCommonBase *clang::QualType::getCommonPtr() const: !isNull() && "Cannot retrieve a NULL type pointer" *** Check failure stack trace: *** @ 0x55e0dffed1f5 DeduceTemplateArgumentsByTypeMatch() @ 0x55e0dffecc3e DeduceTemplateArgumentsByTypeMatch() @ 0x55e0dfff79f1 DeduceTemplateArguments() @ 0x55e0dffe3ce9 DeduceTemplateArguments() @ 0x55e0dffe47c0 clang::Sema::DeduceTemplateArguments() @ 0x55e0e008943b clang::Sema::InstantiateClassTemplateSpecialization() @ 0x55e0e018b8a3 llvm::function_ref<>::callback_fn<>() @ 0x55e0e0b04caf clang::StackExhaustionHandler::runWithSufficientStackSpace() @ 0x55e0e01741a8 clang::Sema::RequireCompleteTypeImpl() @ 0x55e0e01739b5 clang::Sema::RequireCompleteType() @ 0x55e0df8e6914 clang::Sema::RequireCompleteDeclContext() @ 0x55e0dfd44fa9 clang::Sema::LookupParsedName() @ 0x55e0dfb3b113 clang::Sema::BuildQualifiedDeclarationNameExpr() @ 0x55e0e00d83e8 clang::TreeTransform<>::TransformDependentScopeDeclRefExpr() @ 0x55e0e00d2529 clang::TreeTransform<>::TransformCallExpr() @ 0x55e0e00ef218 clang::TreeTransform<>::TransformReturnStmt() @ 0x55e0e00d9018 clang::TreeTransform<>::TransformCompoundStmt() @ 0x55e0e008aa0a clang::Sema::SubstStmt() @ 0x55e0e011f3ce clang::Sema::InstantiateFunctionDefinition() @ 0x55e0e0b04caf clang::StackExhaustionHandler::runWithSufficientStackSpace() @ 0x55e0dffed9d6 clang::Sema::DeduceReturnType() @ 0x55e0dfb2bac5 clang::Sema::DiagnoseUseOfDecl() @ 0x55e0dfeb8361 FinishOverloadedCallExpr() @ 0x55e0dfeb8274 clang::Sema::BuildOverloadedCallExpr() @ 0x55e0dfb322ba clang::Sema::BuildCallExpr() @ 0x55e0dfb492b8 clang::Sema::ActOnCallExpr() @ 0x55e0e00d2704 clang::TreeTransform<>::TransformCallExpr() @ 0x55e0e008d052 clang::TreeTransform<>::TransformExprs() @ 0x55e0e00d258c clang::TreeTransform<>::TransformCallExpr() @ 0x55e0e008d052 clang::TreeTransform<>::TransformExprs() @ 0x55e0e00d258c clang::TreeTransform<>::TransformCallExpr() @ 0x55e0e00ef218 clang::TreeTransform<>::TransformReturnStmt() @ 0x55e0e00d9018 clang::TreeTransform<>::TransformCompoundStmt() @ 0x55e0e008aa0a clang::Sema::SubstStmt() @ 0x55e0e011f3ce clang::Sema::InstantiateFunctionDefinition() @ 0x55e0e01227ba clang::Sema::PerformPendingInstantiations() @ 0x55e0df88aaac clang::Sema::ActOnEndOfTranslationUnitFragment() @ 0x55e0df88b22b clang::Sema::ActOnEndOfTranslationUnit() @ 0x55e0df5a1e5a clang::Parser::ParseTopLevelDecl() @ 0x55e0df59e05e clang::ParseAST() ... ``` In the meantime, I'll try reducing this https://github.com/llvm/llvm-project/pull/132401 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding support for cancelling a request. (PR #130169)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/130169 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][lldb-dap] Added support for "WriteMemory" request. (PR #131820)
santhoshe447 wrote: > There is another Pull Request for the same functionality #108036. The other > PR seems to be outdated, though, and this PR seems to be further along (e.g. > it also has test cases). CC @jennphilqc @walter-erquinigo @clayborg since you > commented on the other PR and might also be interested in this PR Yes, you are right. She was my colleague. I am continuing her work and adding and adding test cases based on the new refactor changes. https://github.com/llvm/llvm-project/pull/131820 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding a DAPError for showing users error messages. (PR #132255)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/132255 >From a696c1c3ce5cf0f652e0a016c5d5d422b2ae24d3 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Thu, 20 Mar 2025 10:08:53 -0700 Subject: [PATCH 1/3] [lldb-dap] Adding a DAPError for showing users error messages. The `DAPError` can be used to craft an error message that is displayed to a user (with showUser=true). Any request handler implementation using subclassing `RequestHandler<>` should be able to use this. I updated SourceRequestHandler to report DAPError's specifically. --- lldb/tools/lldb-dap/CMakeLists.txt| 1 + lldb/tools/lldb-dap/DAPError.cpp | 26 +++ lldb/tools/lldb-dap/DAPError.h| 33 +++ lldb/tools/lldb-dap/Handler/RequestHandler.h | 28 .../lldb-dap/Handler/SourceRequestHandler.cpp | 4 +-- 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 lldb/tools/lldb-dap/DAPError.cpp create mode 100644 lldb/tools/lldb-dap/DAPError.h diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 93c5ee4426783..e9773db7586e6 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -18,6 +18,7 @@ add_lldb_tool(lldb-dap Breakpoint.cpp BreakpointBase.cpp DAP.cpp + DAPError.cpp DAPLog.cpp EventHelper.cpp ExceptionBreakpoint.cpp diff --git a/lldb/tools/lldb-dap/DAPError.cpp b/lldb/tools/lldb-dap/DAPError.cpp new file mode 100644 index 0..044c9b48d61c6 --- /dev/null +++ b/lldb/tools/lldb-dap/DAPError.cpp @@ -0,0 +1,26 @@ +//===-- DAPError.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "DAPError.h" +#include "llvm/Support/Error.h" +#include + +namespace lldb_dap { + +char DAPError::ID; + +DAPError::DAPError(std::string message, bool show_user) +: m_message(message), m_show_user(show_user) {} + +void DAPError::log(llvm::raw_ostream &OS) const { OS << m_message; } + +std::error_code DAPError::convertToErrorCode() const { + return llvm::inconvertibleErrorCode(); +} + +} // namespace lldb_dap diff --git a/lldb/tools/lldb-dap/DAPError.h b/lldb/tools/lldb-dap/DAPError.h new file mode 100644 index 0..b990bcdb5ceb0 --- /dev/null +++ b/lldb/tools/lldb-dap/DAPError.h @@ -0,0 +1,33 @@ +//===-- DAPError.h ===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "llvm/Support/Error.h" +#include + +namespace lldb_dap { + +/// An Error that is reported as a DAP Error Message, which may be presented to +/// the user. +class DAPError : public llvm::ErrorInfo { +public: + static char ID; + + DAPError(std::string message, bool show_user = false); + + void log(llvm::raw_ostream &OS) const override; + std::error_code convertToErrorCode() const override; + + const std::string &getMessage() const { return m_message; } + bool getShowUser() const { return m_show_user; } + +private: + std::string m_message; + bool m_show_user; +}; + +} // namespace lldb_dap diff --git a/lldb/tools/lldb-dap/Handler/RequestHandler.h b/lldb/tools/lldb-dap/Handler/RequestHandler.h index d327820224a30..01eaf3a6cfe65 100644 --- a/lldb/tools/lldb-dap/Handler/RequestHandler.h +++ b/lldb/tools/lldb-dap/Handler/RequestHandler.h @@ -10,11 +10,13 @@ #define LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H #include "DAP.h" +#include "DAPError.h" #include "DAPLog.h" #include "Protocol/ProtocolBase.h" #include "Protocol/ProtocolRequests.h" #include "lldb/API/SBError.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include "llvm/Support/JSON.h" #include #include @@ -118,20 +120,32 @@ class RequestHandler : public BaseRequestHandler { std::string parse_failure; llvm::raw_string_ostream OS(parse_failure); root.printErrorContext(request.arguments, OS); + + protocol::ErrorMessage error; + error.format = parse_failure; + response.success = false; - response.message = parse_failure; + response.body = std::move(error); + dap.Send(response); return; } -auto body = Run(arguments); -// FIXME: Add a dedicated DAPError for enhanced errors that are -// user-visibile. +llvm::Expected body = Run(arguments); if (auto Err = body.takeError()) { + protocol::ErrorMessage error; + if (llvm::Error unhandled = llvm::handle
[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)
@@ -66,6 +75,40 @@ struct LLDBBaseTelemetryInfo : public llvm::telemetry::TelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; +/// Describes an exit status. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct TargetInfo : public LLDBBaseTelemetryInfo { + lldb::ModuleSP exec_mod; + + // The same as the executable-module's UUID. + std::string target_uuid; + std::string arch_name; + + // If true, this entry was emitted at the beginning of an event (eg., before + // the executable laod). Otherwise, it was emitted at the end of an event + // (eg., after the module and any dependency were loaded.) + bool is_start_entry; + + // Describes the exit of the executable module. JDevlieghere wrote: ```suggestion /// Describes the exit of the executable module. ``` https://github.com/llvm/llvm-project/pull/127834 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Add RegisterCheckpoint overload for register methods in RegisterContextThreadMemory (PR #132079)
felipepiovezan wrote: Based on the 2013 commit that added those, I don't think there is a clean way of testing this. That said, since these methods simply forward to the underlying register context, I think it's ok to rely on the lack of regression from the OS plugin tests https://github.com/llvm/llvm-project/pull/132079 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Enable runInTerminal tests on macOS. (PR #133824)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: John Harrison (ashgti) Changes These tests are currently filtered on macOS if your on an M1 (or newer) device. These tests do work on macOS, for me at least on M1 Max with macOS 15.3.2 and Xcode 16.2. Enabling them again, but if we have CI problems with them we can keep them disabled. --- Full diff: https://github.com/llvm/llvm-project/pull/133824.diff 2 Files Affected: - (modified) lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py (+2-2) - (modified) lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py (+8-8) ``diff diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py index 5a9938c25c2c8..a94c9860c1508 100644 --- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py +++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py @@ -21,7 +21,7 @@ def isTestSupported(self): return False @skipIfWindows -@skipIf(archs=["arm"]) # Always times out on buildbot +@skipIf(oslist=["linux"], archs=["arm"]) # Always times out on buildbot def test_basic_functionality(self): """ Test basic restarting functionality when the process is running in @@ -61,7 +61,7 @@ def test_basic_functionality(self): ) @skipIfWindows -@skipIf(archs=["arm"]) # Always times out on buildbot +@skipIf(oslist=["linux"], archs=["arm"]) # Always times out on buildbot def test_stopOnEntry(self): """ Check that stopOnEntry works correctly when using runInTerminal. diff --git a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py index 9141565ac1b9b..9aab7ca3293db 100644 --- a/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py +++ b/lldb/test/API/tools/lldb-dap/runInTerminal/TestDAP_runInTerminal.py @@ -44,7 +44,7 @@ def isTestSupported(self): return False @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_runInTerminal(self): if not self.isTestSupported(): return @@ -90,7 +90,7 @@ def test_runInTerminal(self): env = self.dap_server.request_evaluate("foo")["body"]["result"] self.assertIn("bar", env) -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_runInTerminalWithObjectEnv(self): if not self.isTestSupported(): return @@ -114,7 +114,7 @@ def test_runInTerminalWithObjectEnv(self): self.assertEqual("BAR", request_envs["FOO"]) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_runInTerminalInvalidTarget(self): if not self.isTestSupported(): return @@ -133,7 +133,7 @@ def test_runInTerminalInvalidTarget(self): ) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_missingArgInRunInTerminalLauncher(self): if not self.isTestSupported(): return @@ -148,7 +148,7 @@ def test_missingArgInRunInTerminalLauncher(self): ) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self): if not self.isTestSupported(): return @@ -175,7 +175,7 @@ def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self): self.assertIn("No such file or directory", stderr) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self): if not self.isTestSupported(): return @@ -202,7 +202,7 @@ def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self): self.assertIn("foo", stdout) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self): if not self.isTestSupported(): return @@ -223,7 +223,7 @@ def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self): self.assertIn("FOO=BAR", stdout) @skipIfWindows -@skipIf(archs=no_match(["x86_64"])) +@skipIf(oslist=["linux"], archs=no_match(["x86_64"])) def test_NonAttachedRunInTerminalLauncher(self): if not self.isTestSupported(): return `` https://github.com/llvm/llvm-project/pull/133824 ___ lldb-commits mailing list lldb-commits@lists.llvm
[Lldb-commits] [lldb] [lldb] Implement CLI support for reverse-continue (PR #132783)
rocallahan wrote: I suppose we need to add documentation for this but I'm not sure where... https://github.com/llvm/llvm-project/pull/132783 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply LLDB-Telemetry TargetInfo branch (pr/127834) (PR #132043)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/132043 >From 9f0a47af2b7fdb90e4fa4cc7f8f97c840af1d2bc Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Wed, 19 Mar 2025 10:44:12 -0400 Subject: [PATCH 1/4] Reapply "[LLDB][Telemetry]Define TargetInfo for collecting data about a target (#127834)" This reverts commit 7dbcdd578cd4d37b1f4094dbd17556be6382f1cc. --- lldb/include/lldb/Core/Telemetry.h| 74 +-- lldb/source/Core/Telemetry.cpp| 25 ++- .../source/Interpreter/CommandInterpreter.cpp | 2 +- lldb/source/Target/Process.cpp| 21 ++ lldb/source/Target/Target.cpp | 21 ++ 5 files changed, 134 insertions(+), 9 deletions(-) diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 29ec36b2d64d1..28897f283dc55 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -23,9 +23,12 @@ #include #include #include +#include #include #include #include +#include +#include namespace lldb_private { namespace telemetry { @@ -46,12 +49,18 @@ struct LLDBConfig : public ::llvm::telemetry::Config { // Specifically: // - Length: 8 bits // - First two bits (MSB) must be 11 - the common prefix +// - Last two bits (LSB) are reserved for grand-children of LLDBTelemetryInfo // If any of the subclass has descendents, those descendents -// must have their LLDBEntryKind in the similar form (ie., share common prefix) +// must have their LLDBEntryKind in the similar form (ie., share common prefix +// and differ by the last two bits) struct LLDBEntryKind : public ::llvm::telemetry::EntryKind { - static const llvm::telemetry::KindType BaseInfo = 0b1100; - static const llvm::telemetry::KindType CommandInfo = 0b1101; - static const llvm::telemetry::KindType DebuggerInfo = 0b11000100; + // clang-format off + static const llvm::telemetry::KindType BaseInfo= 0b1100; + static const llvm::telemetry::KindType CommandInfo = 0b1101; + static const llvm::telemetry::KindType DebuggerInfo= 0b11001000; + static const llvm::telemetry::KindType ExecModuleInfo = 0b11000100; + static const llvm::telemetry::KindType ProcessExitInfo = 0b11001100; + // clang-format on }; /// Defines a convenient type for timestamp of various events. @@ -89,7 +98,7 @@ struct CommandInfo : public LLDBBaseTelemetryInfo { /// session. Necessary because we'd send off an entry right before a command's /// execution and another right after. This is to avoid losing telemetry if /// the command does not execute successfully. - uint64_t command_id; + uint64_t command_id = 0; /// The command name(eg., "breakpoint set") std::string command_name; /// These two fields are not collected by default due to PII risks. @@ -116,7 +125,7 @@ struct CommandInfo : public LLDBBaseTelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; - static uint64_t GetNextId(); + static uint64_t GetNextID(); private: // We assign each command (in the same session) a unique id so that their @@ -146,6 +155,59 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; +struct ExecutableModuleInfo : public LLDBBaseTelemetryInfo { + lldb::ModuleSP exec_mod; + /// The same as the executable-module's UUID. + UUID uuid; + /// PID of the process owned by this target. + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + /// The triple of this executable module. + std::string triple; + + /// If true, this entry was emitted at the beginning of an event (eg., before + /// the executable is set). Otherwise, it was emitted at the end of an + /// event (eg., after the module and any dependency were loaded.) + bool is_start_entry = false; + + ExecutableModuleInfo() = default; + + llvm::telemetry::KindType getKind() const override { +return LLDBEntryKind::ExecModuleInfo; + } + + static bool classof(const TelemetryInfo *T) { +// Subclasses of this is also acceptable +return (T->getKind() & LLDBEntryKind::ExecModuleInfo) == + LLDBEntryKind::ExecModuleInfo; + } + void serialize(llvm::telemetry::Serializer &serializer) const override; +}; + +/// Describes an exit status. +struct ExitDescription { + int exit_code; + std::string description; +}; + +struct ProcessExitInfo : public LLDBBaseTelemetryInfo { + // The executable-module's UUID. + UUID module_uuid; + lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; + bool is_start_entry = false; + std::optional exit_desc; + + llvm::telemetry::KindType getKind() const override { +return LLDBEntryKind::ProcessExitInfo; + } + + static bool classof(const TelemetryInfo *T) { +// Subclasses of this is also acceptable +return (T->getKind() & LLDBEntryKind::ProcessExitInfo) == + LLDBEntryKind::ProcessExitInfo; + } + void serialize(llvm::t
[Lldb-commits] [lldb] Reapply "[lldb] Return *const* UnwindPlan pointers from FuncUnwinders " (PR #134246)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes This reverts commit 094904303d50e0ab14bc5f2586a602f79af95953, reapplying d7afafdbc464e65c56a0a1d77bad426aa7538306 (#133247). The failure ought to be fixed by 0509932bb6a291ba11253f30c465ab3ad164ae08. --- Patch is 48.52 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134246.diff 7 Files Affected: - (modified) lldb/include/lldb/Symbol/FuncUnwinders.h (+41-37) - (modified) lldb/include/lldb/Symbol/UnwindPlan.h (+2-2) - (modified) lldb/include/lldb/Target/RegisterContextUnwind.h (+9-7) - (modified) lldb/source/Commands/CommandObjectTarget.cpp (+49-57) - (modified) lldb/source/Symbol/FuncUnwinders.cpp (+105-102) - (modified) lldb/source/Symbol/UnwindPlan.cpp (+1-1) - (modified) lldb/source/Target/RegisterContextUnwind.cpp (+40-44) ``diff diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h index 1d4c28324e90f..479ccf87b6e2c 100644 --- a/lldb/include/lldb/Symbol/FuncUnwinders.h +++ b/lldb/include/lldb/Symbol/FuncUnwinders.h @@ -36,18 +36,19 @@ class FuncUnwinders { ~FuncUnwinders(); - lldb::UnwindPlanSP GetUnwindPlanAtCallSite(Target &target, Thread &thread); + std::shared_ptr GetUnwindPlanAtCallSite(Target &target, +Thread &thread); - lldb::UnwindPlanSP GetUnwindPlanAtNonCallSite(Target &target, -lldb_private::Thread &thread); + std::shared_ptr + GetUnwindPlanAtNonCallSite(Target &target, lldb_private::Thread &thread); - lldb::UnwindPlanSP GetUnwindPlanFastUnwind(Target &target, - lldb_private::Thread &thread); + std::shared_ptr + GetUnwindPlanFastUnwind(Target &target, lldb_private::Thread &thread); - lldb::UnwindPlanSP + std::shared_ptr GetUnwindPlanArchitectureDefault(lldb_private::Thread &thread); - lldb::UnwindPlanSP + std::shared_ptr GetUnwindPlanArchitectureDefaultAtFunctionEntry(lldb_private::Thread &thread); Address &GetFirstNonPrologueInsn(Target &target); @@ -77,32 +78,34 @@ class FuncUnwinders { // used. Instead, clients should ask for the *behavior* they are looking for, // using one of the above UnwindPlan retrieval methods. - lldb::UnwindPlanSP GetAssemblyUnwindPlan(Target &target, Thread &thread); + std::shared_ptr GetAssemblyUnwindPlan(Target &target, + Thread &thread); - lldb::UnwindPlanSP GetObjectFileUnwindPlan(Target &target); + std::shared_ptr GetObjectFileUnwindPlan(Target &target); - lldb::UnwindPlanSP GetObjectFileAugmentedUnwindPlan(Target &target, - Thread &thread); + std::shared_ptr + GetObjectFileAugmentedUnwindPlan(Target &target, Thread &thread); - lldb::UnwindPlanSP GetEHFrameUnwindPlan(Target &target); + std::shared_ptr GetEHFrameUnwindPlan(Target &target); - lldb::UnwindPlanSP GetEHFrameAugmentedUnwindPlan(Target &target, - Thread &thread); + std::shared_ptr + GetEHFrameAugmentedUnwindPlan(Target &target, Thread &thread); - lldb::UnwindPlanSP GetDebugFrameUnwindPlan(Target &target); + std::shared_ptr GetDebugFrameUnwindPlan(Target &target); - lldb::UnwindPlanSP GetDebugFrameAugmentedUnwindPlan(Target &target, - Thread &thread); + std::shared_ptr + GetDebugFrameAugmentedUnwindPlan(Target &target, Thread &thread); - lldb::UnwindPlanSP GetCompactUnwindUnwindPlan(Target &target); + std::shared_ptr GetCompactUnwindUnwindPlan(Target &target); - lldb::UnwindPlanSP GetArmUnwindUnwindPlan(Target &target); + std::shared_ptr GetArmUnwindUnwindPlan(Target &target); - lldb::UnwindPlanSP GetSymbolFileUnwindPlan(Thread &thread); + std::shared_ptr GetSymbolFileUnwindPlan(Thread &thread); - lldb::UnwindPlanSP GetArchDefaultUnwindPlan(Thread &thread); + std::shared_ptr GetArchDefaultUnwindPlan(Thread &thread); - lldb::UnwindPlanSP GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread); + std::shared_ptr + GetArchDefaultAtFuncEntryUnwindPlan(Thread &thread); private: lldb::UnwindAssemblySP GetUnwindAssemblyProfiler(Target &target); @@ -113,7 +116,8 @@ class FuncUnwinders { // unwind rule for the pc, and LazyBoolCalculate if it was unable to // determine this for some reason. lldb_private::LazyBool CompareUnwindPlansForIdenticalInitialPCLocation( - Thread &thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); + Thread &thread, const std::shared_ptr &a, + const std::shared_ptr &b); UnwindTable &m_unwind_table; @@ -129,22 +133,22 @@ class FuncUnwinders { std::recursive_mutex m_mutex; - lldb::UnwindPlanSP m_unwind_plan_assembly_sp; - lldb::UnwindPlanSP m_unwind_plan_object_file_sp; - lldb::Unw
[Lldb-commits] [lldb] [lldb] Fix TestBreakpointLocations (PR #131890)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Dave Lee (kastiglione) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/131890.diff 1 Files Affected: - (modified) lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py (+2-2) ``diff diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py b/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py index e0c93e3c18581..779dc16567dfd 100644 --- a/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py +++ b/lldb/test/API/functionalities/breakpoint/breakpoint_locations/TestBreakpointLocations.py @@ -47,9 +47,9 @@ def set_breakpoint(self): self.expect( "breakpoint list -f", "Breakpoint locations shown correctly", +ordered=False, substrs=[ -"1: file = 'main.c', line = %d, exact_match = 0, locations = 3" -% self.line +f"1: file = 'main.c', line = {self.line}, exact_match = 0, locations = 3" ], patterns=[ "where = a.out`func_inlined .+unresolved, hit count = 0", `` https://github.com/llvm/llvm-project/pull/131890 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][MIPS] Fix signal SIGBUS number mismatch error on mips target (PR #132688)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff HEAD~1 HEAD --extensions cpp -- lldb/source/Plugins/Process/Utility/LinuxSignals.cpp `` View the diff from clang-format here. ``diff diff --git a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index d254ab3fb..65184c9ee 100644 --- a/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -8,9 +8,9 @@ #include "LinuxSignals.h" -// Now, because we do not support mips debugging, if we compile LLVM on mips target, -// would report error `static assertion failed:Value mismatch for signal number -// SIGBUS`, so add this condition to avoid error. +// Now, because we do not support mips debugging, if we compile LLVM on mips +// target, would report error `static assertion failed:Value mismatch for signal +// number SIGBUS`, so add this condition to avoid error. #if defined(__linux__) && !defined(__mips__) #include `` https://github.com/llvm/llvm-project/pull/132688 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
@@ -0,0 +1,130 @@ +import * as child_process from "node:child_process"; +import * as vscode from "vscode"; + +function areArraysEqual(lhs: T[], rhs: T[]): boolean { + if (lhs.length !== rhs.length) { +return false; + } + for (let i = 0; i < lhs.length; i++) { +if (lhs[i] !== rhs[i]) { + return false; +} + } + return true; +} + +/** + * Represents a running lldb-dap process that is accepting connections (i.e. in "server mode"). + * + * Handles startup of the process if it isn't running already as well as prompting the user + * to restart when arguments have changed. + */ +export class LLDBDapServer implements vscode.Disposable { + private serverProcess?: child_process.ChildProcessWithoutNullStreams; + private serverInfo?: Promise<{ host: string; port: number }>; + + /** + * Starts the server with the provided options. The server will be restarted or reused as + * necessary. + * + * @param dapPath the path to the debug adapter executable + * @param args the list of arguments to provide to the debug adapter + * @param options the options to provide to the debug adapter process + * @returns a promise that resolves with the host and port information or `undefined` if unable to launch the server. + */ + async start( +dapPath: string, +args: string[], +options?: child_process.SpawnOptionsWithoutStdio, + ): Promise<{ host: string; port: number } | undefined> { +const dapArgs = [...args, "--connection", "connect://localhost:0"]; +if (!(await this.shouldContinueStartup(dapPath, dapArgs))) { + return undefined; +} + +if (this.serverInfo) { + return this.serverInfo; +} + +this.serverInfo = new Promise((resolve, reject) => { + const process = child_process.spawn(dapPath, dapArgs, options); + process.on("error", (error) => { +reject(error); +this.serverProcess = undefined; +this.serverInfo = undefined; + }); + process.on("exit", (code, signal) => { +let errorMessage = "Server process exited early"; +if (code !== undefined) { + errorMessage += ` with code ${code}`; +} else if (signal !== undefined) { + errorMessage += ` due to signal ${signal}`; +} +reject(new Error(errorMessage)); +this.serverProcess = undefined; +this.serverInfo = undefined; + }); + process.stdout.setEncoding("utf8").on("data", (data) => { +const connection = /connection:\/\/\[([^\]]+)\]:(\d+)/.exec( + data.toString(), +); +if (connection) { + const host = connection[1]; + const port = Number(connection[2]); + resolve({ host, port }); + process.stdout.removeAllListeners(); +} + }); + this.serverProcess = process; +}); +return this.serverInfo; + } + + /** + * Checks to see if the server needs to be restarted. If so, it will prompt the user + * to ask if they wish to restart. + * + * @param dapPath the path to the debug adapter + * @param args the arguments for the debug adapter + * @returns whether or not startup should continue depending on user input + */ + private async shouldContinueStartup( +dapPath: string, +args: string[], + ): Promise { +if (!this.serverProcess || !this.serverInfo) { + return true; +} + +if (areArraysEqual(this.serverProcess.spawnargs, [dapPath, ...args])) { + return true; +} + +const userInput = await vscode.window.showInformationMessage( + "A server mode instance of lldb-dap is already running, but the arguments are different from what is requested in your debug configuration or settings. Would you like to restart the server?", matthewbastien wrote: I like this way better because the modal reads nicer this way as well. Done. https://github.com/llvm/llvm-project/pull/129262 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Telemetry] Collect telemetry from client when allowed. (PR #129728)
@@ -965,6 +965,22 @@ SBTarget SBDebugger::GetDummyTarget() { return sb_target; } +void SBDebugger::DispatchClientTelemetry(const lldb::SBStructuredData &entry) { + LLDB_INSTRUMENT_VA(this); + // Disable client-telemetry for SWIG. + // This prevent arbitrary python client (pretty printers, whatnot) from sending + // telemetry without vendors knowing. +#ifndef SWIG labath wrote: I have a feeling this is recreating a small version of the `#ifdef TELEMETRY` hell we've escaped only recently. I can definitely understand the desire/need to restrict access to this API to the world outside (lib)lldb. However, does that have to be achieved by deleting the function declaration? Could it be enough to have the declaration unconditionally, but put the implementation behind some build-time flag (or even a runtime flag that's controlled by the telemetry plugin -- and have the downstream implementation never set it)? (this question is mainly for Jonas. I'm aware you didn't ask for support for this to be added upstream, but I think Vy's attempt to do that demonstrates the kind of problems you're setting yourself up for if you choose that strategy. I think it be better to figure out a different solution, as I think you won't be the only one with that concern.) Vy: note that this question is independent of the question whether to expose the function to python. `ifdef SWIG` prevents SWIG from seeing a function (so it doesn't generate bindings for it). The function will always be present in the binary. This is why SWIG guard doesn't have to be applied to function bodies as the swig never reads those. I'm pretty sure this is what Jonas meant when he suggested moving the ifdef to the header -- search for other instances of `#ifndef SWIG` https://github.com/llvm/llvm-project/pull/129728 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb][lldb-dap] Implement jump to cursor (PR #130503)
@@ -0,0 +1,118 @@ +//===-- GoToRequestHandler.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "DAP.h" +#include "EventHelper.h" +#include "JSONUtils.h" + +namespace lldb_dap { + +/// Creates an \p StoppedEvent with the reason \a goto +static void SendThreadGotoEvent(DAP &dap, lldb::tid_t thread_id) { + llvm::json::Object event(CreateEventObject("stopped")); + llvm::json::Object body; + body.try_emplace("reason", "goto"); + body.try_emplace("description", "Paused on Jump To Cursor"); + body.try_emplace("threadId", thread_id); + body.try_emplace("preserveFocusHint", false); + body.try_emplace("allThreadsStopped", true); + + event.try_emplace("body", std::move(body)); + dap.SendJSON(llvm::json::Value(std::move(event))); +} + +// "GotoRequest": { +// "allOf": [ { "$ref": "#/definitions/Request" }, { +// "type": "object", +// "description": "The request sets the location where the debuggee will +// continue to run.\nThis makes it possible to skip the execution of code or +// to execute code again.\nThe code between the current location and the +// goto target is not executed but skipped.\nThe debug adapter first sends +// the response and then a `stopped` event with reason `goto`.\nClients +// should only call this request if the corresponding capability +// `supportsGotoTargetsRequest` is true (because only then goto targets +// exist that can be passed as arguments).", +//."properties": { +// "command": { +// "type": "string", +// "enum": [ "goto" ] +// }, +// "arguments": { +// "$ref": "#/definitions/GotoArguments" +// } +// }, +// "required": [ "command", "arguments" ] +// }] +// } +// "GotoArguments": { +// "type": "object", +// "description": "Arguments for `goto` request.", +// "properties": { +// "threadId": { +// "type": "integer", +// "description": "Set the goto target for this thread." +// }, +// "targetId": { +// "type": "integer", +// "description": "The location where the debuggee will continue to run." +// } +// }, +// "required": [ "threadId", "targetId" ] +// } +// "GotoResponse": { +// "allOf": [ { "$ref": "#/definitions/Response" }, { +// "type": "object", +// "description": "Response to `goto` request. This is just an +// acknowledgement, so no body field is required." +// }] +// } +void GoToRequestHandler::operator()(const llvm::json::Object &request) const { + llvm::json::Object response; + FillResponse(request, response); + + auto SendError = [&](auto &&message) { +response["success"] = false; +response["message"] = message; +dap.SendJSON(llvm::json::Value(std::move(response))); + }; ashgti wrote: I had been meaning to follow up on this with a `DAPError` class, I sent #132255 to implement that. Also, as vogelsgesang said, I wouldn't block this PR on using that once #132255 is in, that should help clean up the code a bit. https://github.com/llvm/llvm-project/pull/130503 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Make the DAP server resilient against broken pipes (PR #133791)
https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/133791 This makes the DAP test server resilient against broken pipes. I'm not sure what is causing the broken pipe, but IIRC this isn't the first time we've seen an issues related to that. I worry about swooping it under the rug, but on the other hand having the test suite hangup isn't great either. Based this on https://bugs.python.org/issue21619: > The best way to clean up a subprocess that I have come up with to > close the pipe(s) and call wait() in two separate steps, such as: ``` try: proc.stdin.close() except BrokenPipeError: pass proc.wait() ``` Fixes #133782 (or rather: works around it) >From 88bd875f9f294a055dc37f52a6476fc661742fae Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 31 Mar 2025 13:20:03 -0700 Subject: [PATCH] [lldb-dap] Make the DAP server resilient against broken pipes This makes the DAP test server resilient against broken pipes. I'm not sure what is causing the broken pipe, but IIRC this isn't the first time we've seen an issues related to that. I worry about swooping it under the rug, but on the other hand having the test suite hangup isn't great either. Based this on https://bugs.python.org/issue21619: > The best way to clean up a subprocess that I have come up with to > close the pipe(s) and call wait() in two separate steps, such as: ``` try: proc.stdin.close() except BrokenPipeError: pass proc.wait() ``` --- .../Python/lldbsuite/test/tools/lldb-dap/dap_server.py | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 01ef4b68f2653..57907b1d2f19b 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -1174,8 +1174,10 @@ def request_testGetTargetBreakpoints(self): return self.send_recv(command_dict) def terminate(self): -self.send.close() -# self.recv.close() +try: +self.send.close() +except BrokenPipeError: +pass def request_setInstructionBreakpoints(self, memory_reference=[]): breakpoints = [] ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Protect SetBreakpoint with the API mutex (PR #134030)
https://github.com/ashgti approved this pull request. Looks great! https://github.com/llvm/llvm-project/pull/134030 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [llvm] [clang-doc] Add regression test for test comments in macros (PR #132360)
https://github.com/ZhongUncle closed https://github.com/llvm/llvm-project/pull/132360 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,283 @@ +//===-- DILParser.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Utility/DiagnosticsRendering.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" +#include +#include +#include +#include +#include + +namespace lldb_private::dil { + +DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr, + const std::string &message, uint32_t loc, + uint16_t err_len) +: ErrorInfo(make_error_code(std::errc::invalid_argument)) { + DiagnosticDetail::SourceLocation sloc = { + FileSpec{}, /*line=*/1, static_cast(loc + 1), + err_len,false, /*in_user_input=*/true}; + std::string rendered_msg = + llvm::formatv(":1:{0}: {1}\n 1 | {2}\n | ^", +loc + 1, message, expr); + DiagnosticDetail detail; + detail.source_location = sloc; + detail.severity = lldb::eSeverityError; + detail.message = message; + detail.rendered = rendered_msg; + m_detail = std::move(detail); +} + +llvm::Expected +DILParser::Parse(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) { + Status lldb_error; + // Cannot declare an llvm::Error without initializing it to something, because + // llvm::Error::Error() constructor is protected. If there's a better way to + // handle this, please let me know. + llvm::Error error(lldb_error.takeError()); + DILParser parser(dil_input_expr, lexer, frame_sp, use_dynamic, use_synthetic, + fragile_ivar, check_ptr_vs_member, error); + + ASTNodeUP node_up = parser.Run(); + + if (error) +return error; + + return node_up; +} + +DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member, + llvm::Error &error) +: m_ctx_scope(frame_sp), m_input_expr(dil_input_expr), + m_dil_lexer(std::move(lexer)), m_error(error), m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic), m_fragile_ivar(fragile_ivar), + m_check_ptr_vs_member(check_ptr_vs_member) {} + +ASTNodeUP DILParser::Run() { + ASTNodeUP expr = ParseExpression(); + + Expect(Token::Kind::eof); + + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +ASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"(" expression ")" +// +ASTNodeUP DILParser::ParsePrimaryExpression() { + if (CurToken().IsOneOf({Token::coloncolon, Token::identifier})) { +// Save the source location for the diagnostics message. +uint32_t loc = CurToken().GetLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier, m_use_dynamic, +m_ctx_scope); + } + + if (CurToken().Is(Token::l_paren)) { +m_dil_lexer.Advance(); +auto expr = ParseExpression(); +Expect(Token::r_paren); +m_dil_lexer.Advance(); +return expr; + } + + BailOut(ErrorCode::kInvalidExpressionSyntax, + llvm::formatv("Unexpected token: {0}", CurToken()), + CurToken().GetLocation()); + return std::make_unique(); +} + +// Parse nested_name_specifier. +// +// nested_name_specifier: +//type_name "::" +//namespace_name "::" +//nested_name_specifier identifier "::" +// +std::string DILParser::ParseNestedNameSpecifier() { + // The first token in nested_name_specifier is always an identifier, or + // '(anonymous namespace)'. + if (CurToken().IsNot(Token::identifier) && CurToken().IsNot(Token::l_paren)) +return ""; + + // Anonymous namespaces need to be treated specially: They are represented + // the the string '(anonymous namespace)', which has a space in it (throwing + // off normal parsing) and is not actually proper C++> Check to see if w
[Lldb-commits] [lldb] [lldb/DWARF] Remove "range lower than function low_pc" check (PR #132395)
https://github.com/labath created https://github.com/llvm/llvm-project/pull/132395 The check is not correct for discontinuous functions, as one of the blocks could very well begin before the function entry point. To catch dead-stripped ranges, I check whether the functions is after the first known code address. I don't print any error in this case as that is a common/expected situation. If the block ranges is not a subrange of the enclosing block then this will range will currently be added to the outer block as well (i.e., we get the same behavior that's currently possible for non-subrange blocks larger than function_low_pc). However, this code path is buggy and I'd like to change that (#117725). >From 3326940bbae82afa6b19e1ee696447a39ea3723b Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Fri, 21 Mar 2025 14:04:12 +0100 Subject: [PATCH] [lldb/DWARF] Remove "range lower than function low_pc" check The check is not correct for discontinuous functions, as one of the blocks could very well begin before the function entry point. To catch dead-stripped ranges, I check whether the functions is after the first known code address. I don't print any error in this case as that is a common/expected situation. If the block ranges is not a subrange of the enclosing block then this will range will currently be added to the outer block as well (i.e., we get the same behavior that's currently possible for non-subrange blocks larger than function_low_pc). However, this code path is buggy and I'd like to change that (#117725). --- .../SymbolFile/DWARF/SymbolFileDWARF.cpp | 12 +- .../DWARF/range-lower-then-low-pc.s | 317 -- .../DWARF/x86/discontinuous-inline-function.s | 38 +-- 3 files changed, 20 insertions(+), 347 deletions(-) delete mode 100644 lldb/test/Shell/SymbolFile/DWARF/range-lower-then-low-pc.s diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index d1aaf0bd36de4..58d8969c54e27 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1346,19 +1346,9 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(CompileUnit &comp_unit, decl_line, decl_column, call_file, call_line, call_column, nullptr)) { for (const llvm::DWARFAddressRange &range : ranges) { -if (!range.valid()) - continue; -if (range.LowPC >= subprogram_low_pc) +if (range.valid() && range.LowPC >= m_first_code_address) block->AddRange(Block::Range(range.LowPC - subprogram_low_pc, range.HighPC - range.LowPC)); -else { - GetObjectFile()->GetModule()->ReportError( - "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base " - "that is less than the function's low PC {3:x16}. Please file " - "a bug and attach the file at the " - "start of this error message", - block->GetID(), range.LowPC, range.HighPC, subprogram_low_pc); -} } block->FinalizeRanges(); diff --git a/lldb/test/Shell/SymbolFile/DWARF/range-lower-then-low-pc.s b/lldb/test/Shell/SymbolFile/DWARF/range-lower-then-low-pc.s deleted file mode 100644 index e3cc84db12652..0 --- a/lldb/test/Shell/SymbolFile/DWARF/range-lower-then-low-pc.s +++ /dev/null @@ -1,317 +0,0 @@ -# REQUIRES: x86 - -# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t -# RUN: lldb-test symbols %t &> %t.txt -# RUN: cat %t.txt | FileCheck %s - -# Tests that error is printed correctly when DW_AT_low_pc value is -# greater then a range entry. - -# CHECK: 0x006e: adding range [0x-0x001f) -# CHECK-SAME: which has a base that is less than the function's low PC 0x0021. -# CHECK-SAME: Please file a bug and attach the file at the start of this error message - - - -# Test was manually modified to change DW_TAG_lexical_block -# to use DW_AT_ranges, and value lower then DW_AT_low_pc value -# in DW_TAG_subprogram -# static int foo(bool b) { -# if (b) { -#int food = 1; -# return food; -# } -# return 0; -# } -# int main() { -# return foo(true); -# } - .text - .file "main.cpp" - .section.text.main,"ax",@progbits - .globl main# -- Begin function main - .p2align4, 0x90 - .type main,@function -main: # @main -.Lfunc_begin0: - .file 1 "base-lower-then-range-entry" "main.cpp" - .loc1 8 0 # main.cpp:8:0 - .cfi_startproc -# %bb.0:# %entry - pushq %rbp - .cfi_def_cfa_offset 16 - .cfi_offset %rbp, -16 - movq%rsp, %rbp - .cfi_def_cfa_register %rbp - subq$16, %rsp -
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [llvm] [clang-doc] Add regression test for test comments in macros (PR #132360)
ZhongUncle wrote: I am not familiar with PR, so accidentally closed this PR. I create a new one #132510 https://github.com/llvm/llvm-project/pull/132360 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Reapply LLDB-Telemetry TargetInfo branch (pr/127834) (PR #132043)
oontvoo wrote: > @labath Hi, friendly ping? thanks Sorry - ignore this ping, i put the comment on the wrong patch. meant to ping on https://github.com/llvm/llvm-project/pull/129728 https://github.com/llvm/llvm-project/pull/132043 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Adding support for cancelling a request. (PR #130169)
https://github.com/ashgti edited https://github.com/llvm/llvm-project/pull/130169 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][lldb-dap] Added support for "WriteMemory" request. (PR #131820)
@@ -394,6 +394,13 @@ class TestGetTargetBreakpointsRequestHandler : public LegacyRequestHandler { void operator()(const llvm::json::Object &request) const override; }; +class WriteMemoryRequestHandler : public LegacyRequestHandler { vogelsgesang wrote: I would prefer if we would directly use the non-legacy approach here https://github.com/llvm/llvm-project/pull/131820 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Update examples in docs/use/python-reference.rst to work with Python 3 (PR #134204)
https://github.com/jimingham commented: LGTM https://github.com/llvm/llvm-project/pull/134204 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Target] RunThreadPlan to save/restore the ExecutionContext's frame if one exists (PR #134097)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/134097 >From 151ad919ab6f2d87991511b293f4a9797210f82f Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Wed, 2 Apr 2025 15:48:25 +0100 Subject: [PATCH 1/4] [lldb][Target] RunThreadPlan to save/restore the ExecutionContext's frame if one exists When using `SBFrame::EvaluateExpression` on a frame that's not the currently selected frame, we would sometimes run into errors such as: ``` error: error: The context has changed before we could JIT the expression! error: errored out in DoExecute, couldn't PrepareToExecuteJITExpression ``` Durin expression parsing, we call `RunStaticInitializers`. On our internal fork this happens quite frequently because any usage of, e.g., function pointers, will inject ptrauth fixup code into the expression. The static initializers are run using `RunThreadPlan`. The `ExecutionContext::m_frame_sp` going into the `RunThreadPlan` is the `SBFrame` that we called `EvaluateExpression` on. LLDB then tries to save this frame to restore it later (the restore occurs by unconditionally overwriting whatever is in `ExecutionContext::m_frame_sp`). However, if the `selected_frame_sp` is not the same as the `SBFrame`, then `RunThreadPlan` would set the `ExecutionContext`'s frame to a different frame than what we started with. When we `PrepareToExecuteJITExpression`, LLDB checks whether the `ExecutionContext` frame changed from when we initially `EvaluateExpression`, and if did, bails out with the error above. One such test-case is attached. This currently passes regardless of the fix because our ptrauth static initializers code isn't upstream yet. But the plan is to upstream it soon. This patch addresses the issue by saving/restoring the frame of the incoming `ExecutionContext`, if such frame exists. Otherwise, fall back to using the selected frame. --- lldb/source/Target/Process.cpp| 8 - .../expr-from-non-zero-frame/Makefile | 3 ++ .../TestExprFromNonZeroFrame.py | 29 +++ .../expr-from-non-zero-frame/main.cpp | 6 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 lldb/test/API/commands/expression/expr-from-non-zero-frame/Makefile create mode 100644 lldb/test/API/commands/expression/expr-from-non-zero-frame/TestExprFromNonZeroFrame.py create mode 100644 lldb/test/API/commands/expression/expr-from-non-zero-frame/main.cpp diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 369933234ccca..f4ecb0b7ea307 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -5080,7 +5080,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, return eExpressionSetupError; } - StackID ctx_frame_id = selected_frame_sp->GetStackID(); + // If the ExecutionContext has a frame, we want to make sure to save/restore + // that frame into exe_ctx. This can happen when we run expressions from a + // non-selected SBFrame, in which case we don't want some thread-plan + // to overwrite the ExecutionContext frame. + StackID ctx_frame_id = exe_ctx.HasFrameScope() + ? exe_ctx.GetFrameRef().GetStackID() + : selected_frame_sp->GetStackID(); // N.B. Running the target may unset the currently selected thread and frame. // We don't want to do that either, so we should arrange to reset them as diff --git a/lldb/test/API/commands/expression/expr-from-non-zero-frame/Makefile b/lldb/test/API/commands/expression/expr-from-non-zero-frame/Makefile new file mode 100644 index 0..8b20bcb05 --- /dev/null +++ b/lldb/test/API/commands/expression/expr-from-non-zero-frame/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/commands/expression/expr-from-non-zero-frame/TestExprFromNonZeroFrame.py b/lldb/test/API/commands/expression/expr-from-non-zero-frame/TestExprFromNonZeroFrame.py new file mode 100644 index 0..e87279abde406 --- /dev/null +++ b/lldb/test/API/commands/expression/expr-from-non-zero-frame/TestExprFromNonZeroFrame.py @@ -0,0 +1,29 @@ +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class ExprFromNonZeroFrame(TestBase): +NO_DEBUG_INFO_TESTCASE = True + +@skipIf(archs=no_match(["arm64e"])) +def test(self): +""" +Tests that we can use SBFrame::EvaluateExpression on a frame +that we're not stopped in, even if thread-plans run as part of +parsing the expression (e.g., when running static initializers). +""" +self.build() + +(_, _, thread, _) = lldbutil.run_to_source_breakpoint( +self, "Break here", lldb.SBFileSpec("main.cpp") +) +frame = thread.GetFrameAtIndex(1) + +# Using a function pointer inside the expression ensures we +
[Lldb-commits] [lldb] [lldb] Convert Breakpoint & Watchpoints structs to classes (NFC) (PR #133780)
@@ -52,14 +37,33 @@ struct SourceBreakpoint : public Breakpoint { static bool BreakpointHitCallback(void *baton, lldb::SBProcess &process, lldb::SBThread &thread, lldb::SBBreakpointLocation &location); -}; -inline bool operator<(const SourceBreakpoint &lhs, - const SourceBreakpoint &rhs) { - if (lhs.line == rhs.line) -return lhs.column < rhs.column; - return lhs.line < rhs.line; -} + inline bool operator<(const SourceBreakpoint &rhs) { +if (line == rhs.line) + return column < rhs.column; +return line < rhs.line; + } + + uint32_t GetLine() const { return line; } + uint32_t GetColumn() const { return column; } + +protected: + // logMessage part can be either a raw text or an expression. + struct LogMessagePart { +LogMessagePart(llvm::StringRef text, bool is_expr) +: text(text), is_expr(is_expr) {} +std::string text; +bool is_expr; + }; ashgti wrote: I think other kinds of breakpoints can have log messages. Should we make this into its own helper that is shared between all the BP types? https://github.com/llvm/llvm-project/pull/133780 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Fix intel trace plugin tests (PR #133826)
https://github.com/dmpots created https://github.com/llvm/llvm-project/pull/133826 The tests for the [intel-pt](https://github.com/llvm/llvm-project/blob/348374028970c956f2e49ab7553b495d7408ccd9/lldb/docs/use/intel_pt.rst) trace plugin were failing for multiple reasons. On machines where tracing is supported many of the tests were crashing because of a nullptr dereference. It looks like the `core_file` parameter in `ProcessTrace::CreateInstance` was once ignored, but was changed to always being dereferenced. This caused the tests to fail even when tracing was supported. On machines where tracing is not supported we would still run tests that attempt to take a trace. These would obviously fail because the required hardware is not present. Note that some of the tests simply read serialized json as trace files which does not require any special hardware. This PR fixes these two issues by guarding the pointer dereference and then skipping unsupported tests on machines. With these changes the trace tests pass on both types of machines. We also add a new unit test to validate that a process can be created with a nullptr core_file through the generic process trace plugin path. >From 6a6e5e98860112cf50e83059dbad94bdc9dd4cc2 Mon Sep 17 00:00:00 2001 From: David Peixotto Date: Mon, 31 Mar 2025 13:14:49 -0700 Subject: [PATCH] [lldb] Fix intel trace plugin tests The tests for the [intel-pt](https://github.com/llvm/llvm-project/blob/348374028970c956f2e49ab7553b495d7408ccd9/lldb/docs/use/intel_pt.rst) trace plugin were failing for multiple reasons. On machines where tracing is supported many of the tests were crashing because of a nullptr dereference. It looks like the `core_file` parameter in `ProcessTrace::CreateInstance` was once ignored, but was changed to always being dereferenced. This caused the tests to fail even when tracing was supported. On machines where tracing is not supported we would still run tests that attempt to take a trace. These would obviously fail because the required hardware is not present. Note that some of the tests simply read serialized json as trace files which does not require any special hardware. This PR fixes these two issues by guarding the pointer dereference and then skipping unsupported tests on machines. With these changes the trace tests pass on both types of machines. We also add a new unit test to validate that a process can be created with a nullptr core_file through the generic process trace plugin path. --- .../test/tools/intelpt/intelpt_testcase.py| 7 +++ lldb/source/Target/ProcessTrace.cpp | 3 +- .../trace/TestTraceDumpFunctionCalls.py | 2 + .../API/commands/trace/TestTraceEvents.py | 1 + lldb/test/API/commands/trace/TestTraceSave.py | 2 + .../API/commands/trace/TestTraceStartStop.py | 1 + lldb/test/API/commands/trace/TestTraceTSC.py | 1 + .../TestTraceStartStopMultipleThreads.py | 1 + lldb/unittests/Process/CMakeLists.txt | 4 +- lldb/unittests/Process/ProcessTraceTest.cpp | 63 +++ 10 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 lldb/unittests/Process/ProcessTraceTest.cpp diff --git a/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py index f1b7d7c33bf07..176dce6a435f7 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/intelpt/intelpt_testcase.py @@ -18,6 +18,13 @@ def wrapper(*args, **kwargs): return wrapper +def skipIfCpuDoesNotSupportIntelPT(func): +"""Skip tests if the system does not support tracing.""" + +supported = os.path.exists("/sys/bus/event_source/devices/intel_pt/type") +return unittest.skipIf(not supported, "intel-pt tracing is unsupported")(func) + + # Class that should be used by all python Intel PT tests. # # It has a handy check that skips the test if the intel-pt plugin is not enabled. diff --git a/lldb/source/Target/ProcessTrace.cpp b/lldb/source/Target/ProcessTrace.cpp index f131339905474..02272b1651da5 100644 --- a/lldb/source/Target/ProcessTrace.cpp +++ b/lldb/source/Target/ProcessTrace.cpp @@ -36,7 +36,8 @@ ProcessSP ProcessTrace::CreateInstance(TargetSP target_sp, bool can_connect) { if (can_connect) return nullptr; - return std::make_shared(target_sp, listener_sp, *crash_file); + return std::make_shared(target_sp, listener_sp, +crash_file ? *crash_file : FileSpec()); } bool ProcessTrace::CanDebug(TargetSP target_sp, bool plugin_specified_by_name) { diff --git a/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py b/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py index 761c262ae4de0..8b30414953d7d 100644 --- a/lldb/test/API/commands/trace/TestTraceDumpFunctionCalls.py +++ b/lldb/test/API/commands/trace/TestTraceDumpF
[Lldb-commits] [lldb] [lldb][AIX] Support for XCOFF Sections (PR #131304)
@@ -7,6 +7,9 @@ # CHECK: Stripped: false # CHECK: Type: executable # CHECK: Strata: unknown +# CHECK: Name: .text +# CHECK-NEXT: code +# CHECK-NEXT: r-x labath wrote: The test is pretty weak. It should be very simple to add one of each kind of sections that you're handling (data, bss, debug info), right? And to (at least) check that the section size and virtual address are correct? https://github.com/llvm/llvm-project/pull/131304 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][NFC] Move ShouldShow/ShouldSelect logic into Stopinfo (PR #134160)
@@ -118,6 +118,19 @@ class StopInfo : public std::enable_shared_from_this { StructuredData::ObjectSP GetExtendedInfo() { return m_extended_info; } + /// Returns true if this is a stop reason that should be shown to a user when + /// stopping. jimingham wrote: stopping -> viewing the thread with this stop info This happens not just at stop. https://github.com/llvm/llvm-project/pull/134160 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Convert Breakpoint & Watchpoints structs to classes (NFC) (PR #133780)
@@ -52,14 +37,33 @@ struct SourceBreakpoint : public Breakpoint { static bool BreakpointHitCallback(void *baton, lldb::SBProcess &process, lldb::SBThread &thread, lldb::SBBreakpointLocation &location); ashgti wrote: Does `BreakpointHitCallback` need to be in the header here? I guess that may be a functional change if we move this into the .cpp file. I also think other breakpoint types can also have log callbacks, but I'm not sure if they're all handled consistently. https://github.com/llvm/llvm-project/pull/133780 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Create a default rate limit constant in Progress (NFC) (PR #133506)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/133506 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Add enable/disable api for SystemRuntime plugins (PR #133794)
https://github.com/dmpots created https://github.com/llvm/llvm-project/pull/133794 This commit adds support for enabling and disabling plugins by name. The changes are made generically in the `PluginInstances` class, but currently we only expose the ability to SystemRuntime plugins. Other plugins types can be added easily. We had a few design goals for how disabled plugins should work 1. Plugins that are disabled should still be visible to the system. This allows us to dynamically enable and disable plugins and report their state to the user. 2. Plugin order should be stable across disable and enable changes. We want avoid changing the order of plugin lookup. When a plugin is re-enabled it should return to its original slot in the creation order. 3. Disabled plugins should not appear in PluginManager operations. Clients should be able to assume that only enabled plugins will be returned from the PluginManager. For the implementation we modify the plugin instance to maintain a bool of its enabled state. Existing clients external to the Instances class expect to iterate over only enabled instance so we skip over disabed instances in the query and snapshot apis. This way the client does not have to manually check which instances are enabled. >From 73d16e0c44319860018735708ca2dc18864c9953 Mon Sep 17 00:00:00 2001 From: David Peixotto Date: Fri, 7 Mar 2025 17:27:11 -0800 Subject: [PATCH] Add enable/disable api for SystemRuntime plugins This commit adds support for enabling and disabling plugins by name. The changes are made generically in the `PluginInstances` class, but currently we only expose the ability to SystemRuntime plugins. Other plugins types can be added easily. We had a few design goals for how disabled plugins should work 1. Plugins that are disabled should still be visible to the system. This allows us to dynamically enable and disable plugins and report their state to the user. 2. Plugin order should be stable across disable and enable changes. We want avoid changing the order of plugin lookup. When a plugin is re-enabled it should return to its original slot in the creation order. 3. Disabled plugins should not appear in PluginManager operations. Clients should be able to assume that only enabled plugins will be returned from the PluginManager. For the implementation we modify the plugin instance to maintain a bool of its enabled state. Existing clients external to the Instances class expect to iterate over only enabled instance so we skip over disabed instances in the query and snapshot apis. This way the client does not have to manually check which instances are enabled. --- lldb/include/lldb/Core/PluginManager.h| 13 + lldb/source/Core/PluginManager.cpp| 55 +++- lldb/unittests/Core/CMakeLists.txt| 1 + lldb/unittests/Core/PluginManagerTest.cpp | 367 ++ 4 files changed, 433 insertions(+), 3 deletions(-) create mode 100644 lldb/unittests/Core/PluginManagerTest.cpp diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index e4e0c3eea67f8..a6dab045adf27 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -22,6 +22,7 @@ #include #include +#include #define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName) \ namespace lldb_private { \ @@ -47,6 +48,12 @@ class CommandInterpreter; class Debugger; class StringList; +struct RegisteredPluginInfo { + llvm::StringRef name = ""; + llvm::StringRef description = ""; + bool enabled = false; +}; + class PluginManager { public: static void Initialize(); @@ -168,6 +175,12 @@ class PluginManager { static SystemRuntimeCreateInstance GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx); + static std::vector GetSystemRuntimePluginInfo(); + + // Modify the enabled state of a SystemRuntime plugin. + // Returns false if the plugin name is not found. + static bool SetSystemRuntimePluginEnabled(llvm::StringRef name, bool enabled); + // ObjectFile static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 95eb940efcef2..e6cb248ef31ce 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -188,11 +188,13 @@ template struct PluginInstance { PluginInstance(llvm::StringRef name, llvm::StringRef description, Callback create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr) - : name(name), description(description), create_callback(create_callback), + : name(name), description(description), enabled(true), +create_callback(create_callback), debugger_init_callback(debugger_init_callback) {} llvm::StringRef name; llvm
[Lldb-commits] [lldb] Reapply "[lldb] Implement basic support for reverse-continue (#125242)" (again) (PR #128156)
Michael137 wrote: Seems to be something else though? ``` An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... An exception happened when receiving the response from the gdb server. Closing the client... ``` https://github.com/llvm/llvm-project/pull/128156 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 4492632 - [lldb-dap] Do not take ownership of stdin. (#133811)
Author: John Harrison Date: 2025-03-31T15:51:07-07:00 New Revision: 4492632432190ed8ab3bc39ff8ee5ba9a89256cf URL: https://github.com/llvm/llvm-project/commit/4492632432190ed8ab3bc39ff8ee5ba9a89256cf DIFF: https://github.com/llvm/llvm-project/commit/4492632432190ed8ab3bc39ff8ee5ba9a89256cf.diff LOG: [lldb-dap] Do not take ownership of stdin. (#133811) There isn't any benefit to taking ownership of stdin and it may cause issues if `Transport` is dealloced. Added: Modified: lldb/tools/lldb-dap/lldb-dap.cpp Removed: diff --git a/lldb/tools/lldb-dap/lldb-dap.cpp b/lldb/tools/lldb-dap/lldb-dap.cpp index 062c3a5f989f3..b91c62e921428 100644 --- a/lldb/tools/lldb-dap/lldb-dap.cpp +++ b/lldb/tools/lldb-dap/lldb-dap.cpp @@ -571,9 +571,9 @@ int main(int argc, char *argv[]) { } lldb::IOObjectSP input = std::make_shared( - fileno(stdin), File::eOpenOptionReadOnly, true); + fileno(stdin), File::eOpenOptionReadOnly, NativeFile::Unowned); lldb::IOObjectSP output = std::make_shared( - stdout_fd, File::eOpenOptionWriteOnly, false); + stdout_fd, File::eOpenOptionWriteOnly, NativeFile::Unowned); constexpr llvm::StringLiteral client_name = "stdin/stdout"; Transport transport(client_name, log.get(), input, output); ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Emit progress events in SymbolFileDWARFDebugMap (PR #133211)
https://github.com/adrian-prantl approved this pull request. Will be great when debugging LLDB itself! https://github.com/llvm/llvm-project/pull/133211 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 825460a - [lldb/gdb-remote] Do not crash on an invalid server response (#131979)
Author: Igor Kudrin Date: 2025-03-19T10:51:27-07:00 New Revision: 825460a7728662d0062405e690485b7a1b689484 URL: https://github.com/llvm/llvm-project/commit/825460a7728662d0062405e690485b7a1b689484 DIFF: https://github.com/llvm/llvm-project/commit/825460a7728662d0062405e690485b7a1b689484.diff LOG: [lldb/gdb-remote] Do not crash on an invalid server response (#131979) An invalid RLE sequence in the received packet could result in an out-of-bounds reading that could cause a crash. Added: Modified: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp Removed: diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index dad72a176b5fa..77eadfc8c9f6c 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -788,9 +788,14 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, // Copy the packet from m_bytes to packet_str expanding the run-length // encoding in the process. - std ::string packet_str = + auto maybe_packet_str = ExpandRLE(m_bytes.substr(content_start, content_end - content_start)); - packet = StringExtractorGDBRemote(packet_str); + if (!maybe_packet_str) { +m_bytes.erase(0, total_length); +packet.Clear(); +return GDBRemoteCommunication::PacketType::Invalid; + } + packet = StringExtractorGDBRemote(*maybe_packet_str); if (m_bytes[0] == '$' || m_bytes[0] == '%') { assert(checksum_idx < m_bytes.size()); @@ -1311,17 +1316,22 @@ void llvm::format_provider::format( } } -std::string GDBRemoteCommunication::ExpandRLE(std::string packet) { +std::optional +GDBRemoteCommunication::ExpandRLE(std::string packet) { // Reserve enough byte for the most common case (no RLE used). std::string decoded; decoded.reserve(packet.size()); for (std::string::const_iterator c = packet.begin(); c != packet.end(); ++c) { if (*c == '*') { + if (decoded.empty()) +return std::nullopt; // '*' indicates RLE. Next character will give us the repeat count and // previous character is what is to be repeated. char char_to_repeat = decoded.back(); // Number of time the previous character is repeated. - int repeat_count = *++c + 3 - ' '; + if (++c == packet.end()) +return std::nullopt; + int repeat_count = *c + 3 - ' '; // We have the char_to_repeat and repeat_count. Now push it in the // packet. for (int i = 0; i < repeat_count; ++i) @@ -1329,7 +1339,9 @@ std::string GDBRemoteCommunication::ExpandRLE(std::string packet) { } else if (*c == 0x7d) { // 0x7d is the escape character. The next character is to be XOR'd with // 0x20. - char escapee = *++c ^ 0x20; + if (++c == packet.end()) +return std::nullopt; + char escapee = *c ^ 0x20; decoded.push_back(escapee); } else { decoded.push_back(*c); diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 754797ba7f504..107c0896c4e61 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -168,7 +168,7 @@ class GDBRemoteCommunication : public Communication { GDBRemoteCommunication &server); /// Expand GDB run-length encoding. - static std::string ExpandRLE(std::string); + static std::optional ExpandRLE(std::string); protected: std::chrono::seconds m_packet_timeout; diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp index 425f6cfcd5bc9..3da1f0a718fc5 100644 --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationTest.cpp @@ -68,3 +68,26 @@ TEST_F(GDBRemoteCommunicationTest, ReadPacket) { ASSERT_EQ(PacketResult::Success, server.GetAck()); } } + +// Test that packets with incorrect RLE sequences do not cause a crash and +// reported as invalid. +TEST_F(GDBRemoteCommunicationTest, CheckForPacket) { + using PacketType = GDBRemoteCommunication::PacketType; + struct TestCase { +llvm::StringLiteral Packet; +PacketType Result; + }; + static constexpr TestCase Tests[] = { + {{"$#00"}, PacketType::Standard}, + {{"$xx*#00"}, PacketType::Invalid}, // '*' without a count + {{"$*#00"}, PacketType::Invalid}, // '*' without a preceding charac
[Lldb-commits] [lldb] [LLDB][NFC] Added the interface DWARFExpression::Delegate to break dependencies and reduce lldb-server size (PR #131645)
@@ -38,7 +39,7 @@ enum DWARFProducer { eProducerOther }; -class DWARFUnit : public UserID { +class DWARFUnit : public UserID, public DWARFExpression::Delegate { labath wrote: ```suggestion class DWARFUnit : public DWARFExpression::Delegate, public UserID { ``` (because Delegate is a "true" base class (with virtual methods and whatnot) while UserID is a mixin) https://github.com/llvm/llvm-project/pull/131645 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb][lldb-dap] Implement jump to cursor (PR #130503)
https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/130503 >From 7bad765585b2ae96faf2d2558b099f4b965d2791 Mon Sep 17 00:00:00 2001 From: Ezike Ebuka Date: Sun, 9 Mar 2025 12:46:54 + Subject: [PATCH 01/23] [lldb-dap] implement jump to cursor. --- lldb/cmake/modules/LLDBConfig.cmake | 2 +- lldb/tools/lldb-dap/CMakeLists.txt| 2 + lldb/tools/lldb-dap/DAP.cpp | 23 +++- lldb/tools/lldb-dap/DAP.h | 27 +++- .../lldb-dap/Handler/GoToRequestHandler.cpp | 103 +++ .../Handler/GoToTargetsRequestHandler.cpp | 120 ++ lldb/tools/lldb-dap/Handler/RequestHandler.h | 14 ++ lldb/tools/lldb-dap/lldb-dap.cpp | 2 + 8 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 lldb/tools/lldb-dap/Handler/GoToRequestHandler.cpp create mode 100644 lldb/tools/lldb-dap/Handler/GoToTargetsRequestHandler.cpp diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 9df71edd8b359..a2f9a29b6d5d5 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -57,7 +57,7 @@ add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" Curse add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLDB" LibLZMA LIBLZMA_FOUND) add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND) add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND) -add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8) +add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION) add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in LLDB" FBSDVMCore FBSDVMCore_FOUND QUIET) option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index 93c5ee4426783..0709b2b2dc699 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -45,6 +45,8 @@ add_lldb_tool(lldb-dap Handler/DisconnectRequestHandler.cpp Handler/EvaluateRequestHandler.cpp Handler/ExceptionInfoRequestHandler.cpp +Handler/GoToRequestHandler.cpp +Handler/GoToTargetsRequestHandler.cpp Handler/InitializeRequestHandler.cpp Handler/LaunchRequestHandler.cpp Handler/LocationsRequestHandler.cpp diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 65de0488729e5..986ac5c3bb408 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -81,7 +81,7 @@ DAP::DAP(llvm::StringRef path, Log *log, const ReplMode default_repl_mode, configuration_done_sent(false), waiting_for_run_in_terminal(false), progress_event_reporter( [&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }), - reverse_request_seq(0), repl_mode(default_repl_mode) {} + reverse_request_seq(0), repl_mode(default_repl_mode), goto_id_map() {} DAP::~DAP() = default; @@ -841,6 +841,27 @@ lldb::SBError DAP::WaitForProcessToStop(uint32_t seconds) { return error; } +std::optional Gotos::GetLineEntry(uint64_t id) const { + const auto iter = line_entries.find(id); + if (iter != line_entries.end()) +return iter->second; + + return std::nullopt; +} + +uint64_t Gotos::InsertLineEntry(lldb::SBLineEntry line_entry) { + const auto spec_id = this->NewSpecId(); + line_entries.insert(std::make_pair(spec_id, line_entry)); + return spec_id; +} + +void Gotos::Clear() { + new_id = 0UL; + line_entries.clear(); +} + +uint64_t Gotos::NewSpecId() { return new_id++; } + void Variables::Clear() { locals.Clear(); globals.Clear(); diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 4b4d471161137..c280adb57d0c5 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -77,6 +77,27 @@ enum class PacketStatus { enum class ReplMode { Variable = 0, Command, Auto }; +class Gotos { +public: + /// \return the line_entry corresponding with \p id + /// + /// If \p id is invalid std::nullopt is returned. + std::optional GetLineEntry(uint64_t id) const; + + /// Insert a new \p line_entry. + /// \return id assigned to this line_entry. + uint64_t InsertLineEntry(lldb::SBLineEntry line_entry); + + /// clears all line entries and reset the generated ids. + void Clear(); + +private: + uint64_t NewSpecId(); + + llvm::DenseMap line_entries; + uint64_t new_id = 0ul; +}; + struct Variables { /// Variable_reference start index of permanent expandable variable. static constexpr int64_t PermanentVariableStartIndex = (1ll << 32); @@ -205,6 +226,7 @@ struct DAP { // empty; if the previous expression was a variable expression, this string //
[Lldb-commits] [lldb] [lldb][NFC] use platform independent path separator in testSettings.py. (PR #132392)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-x86_64-debian` running on `lldb-x86_64-debian` while building `lldb` at step 6 "test". Full details are available at: https://lab.llvm.org/buildbot/#/builders/162/builds/18611 Here is the relevant piece of the build log for the reference ``` Step 6 (test) failure: build (failure) ... PASS: lldb-api :: tools/lldb-server/TestGdbRemoteForkResume.py (73 of 2801) PASS: lldb-api :: source-manager/TestSourceManager.py (74 of 2801) PASS: lldb-api :: tools/lldb-server/TestGdbRemoteAuxvSupport.py (75 of 2801) PASS: lldb-api :: commands/watchpoints/hello_watchlocation/TestWatchLocation.py (76 of 2801) PASS: lldb-api :: tools/lldb-dap/console/TestDAP_console.py (77 of 2801) PASS: lldb-api :: lang/cpp/namespace/TestNamespaceLookup.py (78 of 2801) PASS: lldb-api :: types/TestLongTypes.py (79 of 2801) PASS: lldb-api :: functionalities/tail_call_frames/disambiguate_tail_call_seq/TestDisambiguateTailCallSeq.py (80 of 2801) PASS: lldb-api :: tools/lldb-server/vCont-threads/TestPartialResume.py (81 of 2801) PASS: lldb-api :: functionalities/inferior-crashing/recursive-inferior/TestRecursiveInferior.py (82 of 2801) FAIL: lldb-api :: commands/settings/TestSettings.py (83 of 2801) TEST 'lldb-api :: commands/settings/TestSettings.py' FAILED Script: -- /usr/bin/python3 /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./lib --env LLVM_INCLUDE_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/include --env LLVM_TOOLS_DIR=/home/worker/2.0.1/lldb-x86_64-debian/build/./bin --arch x86_64 --build-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex --lldb-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/worker/2.0.1/lldb-x86_64-debian/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/lldb --compiler /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/clang --dsymutil /home/worker/2.0.1/lldb-x86_64-debian/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./bin --lldb-obj-root /home/worker/2.0.1/lldb-x86_64-debian/build/tools/lldb --lldb-libs-dir /home/worker/2.0.1/lldb-x86_64-debian/build/./lib -t /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/commands/settings -p TestSettings.py -- Exit Code: 1 Command Output (stdout): -- lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 5286511adc94529c2d0ee9ea37c121ff7eaea223) clang revision 5286511adc94529c2d0ee9ea37c121ff7eaea223 llvm revision 5286511adc94529c2d0ee9ea37c121ff7eaea223 Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc'] -- Command Output (stderr): -- Change dir to: /home/worker/2.0.1/lldb-x86_64-debian/llvm-project/lldb/test/API/commands/settings runCmd: settings clear -all output: runCmd: settings set symbols.enable-external-lookup false output: runCmd: settings set target.inherit-tcc true output: runCmd: settings set target.disable-aslr false output: runCmd: settings set target.detach-on-error false output: ``` https://github.com/llvm/llvm-project/pull/132392 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] ee60f7c - [lldb] Hoist UUID generation into the UUID class (#133662)
Author: Jonas Devlieghere Date: 2025-04-02T08:50:28-07:00 New Revision: ee60f7c7a4e4e400918c83decb6cd498aff94012 URL: https://github.com/llvm/llvm-project/commit/ee60f7c7a4e4e400918c83decb6cd498aff94012 DIFF: https://github.com/llvm/llvm-project/commit/ee60f7c7a4e4e400918c83decb6cd498aff94012.diff LOG: [lldb] Hoist UUID generation into the UUID class (#133662) Hoist UUID generation into the UUID class and add a trivial unit test. This also changes the telemetry code to drop the double underscore if we failed to generate a UUID and subsequently logs to the Host instead of Object log channel. Added: Modified: lldb/include/lldb/Utility/UUID.h lldb/source/Core/Telemetry.cpp lldb/source/Utility/UUID.cpp lldb/unittests/Utility/UUIDTest.cpp Removed: diff --git a/lldb/include/lldb/Utility/UUID.h b/lldb/include/lldb/Utility/UUID.h index bc4b4acd5a7d8..b0356dbf4c144 100644 --- a/lldb/include/lldb/Utility/UUID.h +++ b/lldb/include/lldb/Utility/UUID.h @@ -12,26 +12,27 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" #include #include #include namespace lldb_private { - class Stream; +class Stream; +/// Represents UUID's of various sizes. In all cases, a uuid of all zeros is +/// treated as an "Invalid UUID" marker, and the UUID created from such data +/// will return false for IsValid. class UUID { - // Represents UUID's of various sizes. In all cases, a uuid of all zeros is - // treated as an "Invalid UUID" marker, and the UUID created from such data - // will return false for IsValid. public: UUID() = default; - - /// Creates a uuid from the data pointed to by the bytes argument. + + /// Create a uuid from the data pointed to by the bytes argument. UUID(llvm::ArrayRef bytes) : m_bytes(bytes) { if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) { Clear(); - } +} } // Reference: @@ -50,13 +51,12 @@ class UUID { /// Create a UUID from CvRecordPdb70. UUID(CvRecordPdb70 debug_info); - /// Creates a UUID from the data pointed to by the bytes argument. + /// Create a UUID from the data pointed to by the bytes argument. UUID(const void *bytes, uint32_t num_bytes) { if (!bytes) return; -*this -= UUID(llvm::ArrayRef(reinterpret_cast(bytes), - num_bytes)); +*this = UUID(llvm::ArrayRef( +reinterpret_cast(bytes), num_bytes)); } void Clear() { m_bytes.clear(); } @@ -67,7 +67,7 @@ class UUID { explicit operator bool() const { return IsValid(); } bool IsValid() const { return !m_bytes.empty(); } - + std::string GetAsString(llvm::StringRef separator = "-") const; bool SetFromStringRef(llvm::StringRef str); @@ -88,6 +88,9 @@ class UUID { DecodeUUIDBytesFromString(llvm::StringRef str, llvm::SmallVectorImpl &uuid_bytes); + /// Create a random UUID. + static UUID Generate(uint32_t num_bytes = 16); + private: // GNU ld generates 20-byte build-ids. Size chosen to avoid heap allocations // for this case. diff --git a/lldb/source/Core/Telemetry.cpp b/lldb/source/Core/Telemetry.cpp index c7789d43c7899..8db29889e0846 100644 --- a/lldb/source/Core/Telemetry.cpp +++ b/lldb/source/Core/Telemetry.cpp @@ -9,15 +9,18 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Telemetry.h" #include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/UUID.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Format.h" #include "llvm/Support/RandomNumberGenerator.h" #include "llvm/Telemetry/Telemetry.h" #include #include +#include #include #include #include @@ -37,18 +40,9 @@ static uint64_t ToNanosec(const SteadyTimePoint Point) { // This reduces the chances of getting the same UUID, even when the same // user runs the two copies of binary at the same time. static std::string MakeUUID() { - uint8_t random_bytes[16]; - std::string randomString = "_"; - if (auto ec = llvm::getRandomBytes(random_bytes, 16)) { -LLDB_LOG(GetLog(LLDBLog::Object), - "Failed to generate random bytes for UUID: {0}", ec.message()); - } else { -randomString = UUID(random_bytes).GetAsString(); - } - - return llvm::formatv( - "{0}_{1}", randomString, - std::chrono::steady_clock::now().time_since_epoch().count()); + auto timestmap = std::chrono::steady_clock::now().time_since_epoch().count(); + UUID uuid = UUID::Generate(); + return llvm::formatv("{0}_{1}", uuid.GetAsString(), timestmap); } void LLDBBaseTelemetryInfo::serialize(Serializer &serializer) const { diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index 370b8b6848c7e..0af0c3837627f 100644 --- a/lldb/s
[Lldb-commits] [lldb] [lldb][lldb-dap] Added support for "WriteMemory" request. (PR #131820)
@@ -463,6 +463,8 @@ void InitializeRequestHandler::operator()( body.try_emplace("supportsDataBreakpoints", true); // The debug adapter supports the `readMemory` request. body.try_emplace("supportsReadMemoryRequest", true); + // The debug adapter supports the 'writeMemory' request. + body.try_emplace("supportsWriteMemoryRequest", true); vogelsgesang wrote: with the recent refactoring from https://github.com/llvm/llvm-project/pull/131943, this capability should be declared in the `WriteMemoryRequestHandler` https://github.com/llvm/llvm-project/pull/131820 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Migrating DAP 'initialize' to new typed RequestHandler. (PR #133007)
https://github.com/ashgti created https://github.com/llvm/llvm-project/pull/133007 This adds new types and helpers to support the 'initialize' request with the new typed RequestHandler. While working on this I found there were a few cases where we incorrectly treated initialize arguments as capabilities. The new `lldb_dap::protocol::InitializeRequestArguments` and `lldb_dap::protocol::Capabilities` uncovered the inconsistencies. >From 045101907513d445fdeb8c06da08467032c4c3d0 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Tue, 25 Mar 2025 14:58:03 -0700 Subject: [PATCH] [lldb-dap] Migrating DAP 'initialize' to new typed RequestHandler. This adds new types and helpers to support the 'initialize' request with the new typed RequestHandler. While working on this I found there were a few cases where we incorrectly treated initialize arguments as capabilities. The new `lldb_dap::protocol::InitializeRequestArguments` and `lldb_dap::protocol::Capabilities` uncovered the inconsistencies. --- .../test/tools/lldb-dap/dap_server.py | 5 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 3 +- lldb/tools/lldb-dap/DAP.cpp | 145 -- lldb/tools/lldb-dap/DAP.h | 6 +- .../Handler/InitializeRequestHandler.cpp | 162 ++- .../tools/lldb-dap/Handler/RequestHandler.cpp | 1 + lldb/tools/lldb-dap/Handler/RequestHandler.h | 89 +++--- lldb/tools/lldb-dap/JSONUtils.cpp | 34 +-- lldb/tools/lldb-dap/JSONUtils.h | 3 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 52 .../lldb-dap/Protocol/ProtocolRequests.h | 69 + .../tools/lldb-dap/Protocol/ProtocolTypes.cpp | 199 ++ lldb/tools/lldb-dap/Protocol/ProtocolTypes.h | 255 ++ 13 files changed, 800 insertions(+), 223 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 359ac718138b2..01ef4b68f2653 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -776,7 +776,8 @@ def request_initialize(self, sourceInitFile): "supportsVariablePaging": True, "supportsVariableType": True, "supportsStartDebuggingRequest": True, -"sourceInitFile": sourceInitFile, +"supportsProgressReporting": True, +"$__lldb_sourceInitFile": sourceInitFile, }, } response = self.send_recv(command_dict) @@ -1261,7 +1262,7 @@ def launch(cls, /, executable, env=None, log_file=None, connection=None): expected_prefix = "Listening for: " out = process.stdout.readline().decode() if not out.startswith(expected_prefix): -self.process.kill() +process.kill() raise ValueError( "lldb-dap failed to print listening address, expected '{}', got '{}'".format( expected_prefix, out diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 0c92e5bff07c6..64c99019a1c9b 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -524,8 +524,7 @@ def test_version(self): # The first line is the prompt line like "(lldb) version", so we skip it. version_eval_output_without_prompt_line = version_eval_output.splitlines()[1:] -lldb_json = self.dap_server.get_initialize_value("__lldb") -version_string = lldb_json["version"] +version_string = self.dap_server.get_initialize_value("$__lldb_version") self.assertEqual( version_eval_output_without_prompt_line, version_string.splitlines(), diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 65de0488729e5..0da8ce43f73c4 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -14,6 +14,7 @@ #include "LLDBUtils.h" #include "OutputRedirector.h" #include "Protocol/ProtocolBase.h" +#include "Protocol/ProtocolTypes.h" #include "Transport.h" #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" @@ -1144,31 +1145,137 @@ lldb::SBValue Variables::FindVariable(uint64_t variablesReference, return variable; } -llvm::StringMap DAP::GetCapabilities() { - llvm::StringMap capabilities; +static void mergeCapabilities(protocol::Capabilities &into, + const protocol::Capabilities &from) { + if (from.supportsConfigurationDoneRequest) +into.supportsConfigurationDoneRequest = +*from.supportsConfigurationDoneRequest; + if (from.supportsFunctionBreakpoints) +into.supportsFunctionBreakpoints = *from.supportsFunctionBreakpoints; + if (from.supportsConditionalBreakpoints) +int
[Lldb-commits] [lldb] [lldb] Implement CLI support for reverse-continue (PR #132783)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Robert O'Callahan (rocallahan) Changes This introduces the options "-F/--forward" and "-R/--reverse" to `process continue`. These only work if you're running with a gdbserver backend that supports reverse execution, such as rr. For testing we rely on the fake reverse-execution functionality in `lldbreverse.py`. --- Full diff: https://github.com/llvm/llvm-project/pull/132783.diff 6 Files Affected: - (modified) lldb/source/Commands/CommandObjectProcess.cpp (+23-1) - (modified) lldb/source/Commands/Options.td (+4) - (added) lldb/test/API/commands/process/reverse-continue/Makefile (+3) - (added) lldb/test/API/commands/process/reverse-continue/TestReverseContinue.py (+66) - (added) lldb/test/API/commands/process/reverse-continue/TestReverseContinueNotSupported.py (+51) - (added) lldb/test/API/commands/process/reverse-continue/main.c (+12) ``diff diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp index 654dfa83ea444..bed81ef0fa7cd 100644 --- a/lldb/source/Commands/CommandObjectProcess.cpp +++ b/lldb/source/Commands/CommandObjectProcess.cpp @@ -468,7 +468,23 @@ class CommandObjectProcessContinue : public CommandObjectParsed { case 'b': m_run_to_bkpt_args.AppendArgument(option_arg); m_any_bkpts_specified = true; - break; +break; + case 'F': +if (m_base_direction == lldb::RunDirection::eRunReverse) { + error = Status::FromErrorString( + "cannot specify both 'forward' and 'reverse'"); + break; +} +m_base_direction = lldb::RunDirection::eRunForward; +break; + case 'R': +if (m_base_direction == lldb::RunDirection::eRunForward) { + error = Status::FromErrorString( + "cannot specify both 'forward' and 'reverse'"); + break; +} +m_base_direction = lldb::RunDirection::eRunReverse; +break; default: llvm_unreachable("Unimplemented option"); } @@ -479,6 +495,7 @@ class CommandObjectProcessContinue : public CommandObjectParsed { m_ignore = 0; m_run_to_bkpt_args.Clear(); m_any_bkpts_specified = false; + m_base_direction = std::nullopt; } llvm::ArrayRef GetDefinitions() override { @@ -488,6 +505,7 @@ class CommandObjectProcessContinue : public CommandObjectParsed { uint32_t m_ignore = 0; Args m_run_to_bkpt_args; bool m_any_bkpts_specified = false; +std::optional m_base_direction; }; void DoExecute(Args &command, CommandReturnObject &result) override { @@ -654,6 +672,10 @@ class CommandObjectProcessContinue : public CommandObjectParsed { } } + if (m_options.m_base_direction.has_value()) { +process->SetBaseDirection(*m_options.m_base_direction); + } + const uint32_t iohandler_id = process->GetIOHandlerID(); StreamString stream; diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index cc579d767eb06..e8c340b85aa92 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -744,6 +744,10 @@ let Command = "process continue" in { Arg<"BreakpointIDRange">, Desc<"Specify a breakpoint to continue to, temporarily " "ignoring other breakpoints. Can be specified more than once. " "The continue action will be done synchronously if this option is specified.">; + def thread_continue_forward : Option<"forward", "F">, Group<3>, +Desc<"Execute in forward direction">; + def thread_continue_reverse : Option<"reverse", "R">, Group<3>, +Desc<"Execute in reverse direction">; } let Command = "process detach" in { diff --git a/lldb/test/API/commands/process/reverse-continue/Makefile b/lldb/test/API/commands/process/reverse-continue/Makefile new file mode 100644 index 0..10495940055b6 --- /dev/null +++ b/lldb/test/API/commands/process/reverse-continue/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/commands/process/reverse-continue/TestReverseContinue.py b/lldb/test/API/commands/process/reverse-continue/TestReverseContinue.py new file mode 100644 index 0..c04d2b9d4b5a5 --- /dev/null +++ b/lldb/test/API/commands/process/reverse-continue/TestReverseContinue.py @@ -0,0 +1,66 @@ +""" +Test the "process continue --reverse" and "--forward" options. +""" + + +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from lldbsuite.test.gdbclientutils import * +from lldbsuite.test.lldbreverse import ReverseTestBase +from lldbsuite.test import lldbutil + + +class TestReverseContinue(ReverseTestBase): +@skipIfRemote +def test_reverse_continue(self): +target, _, _ = self.setup_recording() + +# Set breakpoint and reverse-continue +trigger_bkpt = target.BreakpointCreateByName("trigger_br
[Lldb-commits] [lldb] [lldb] Use UnwindPlan::Row as values, part 2 (PR #132008)
https://github.com/labath closed https://github.com/llvm/llvm-project/pull/132008 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Telemetry]Define TargetInfo for collecting data about a target (PR #127834)
@@ -146,6 +155,59 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; +struct ExecModuleInfo : public LLDBBaseTelemetryInfo { + lldb::ModuleSP exec_mod; + + /// The same as the executable-module's UUID. + UUID exec_uuid; + /// PID of the process owned by this target. + lldb::pid_t pid; + /// The triple of this executable module. + std::string triple; + + /// If true, this entry was emitted at the beginning of an event (eg., before + /// the executable is set). Otherwise, it was emitted at the end of an + /// event (eg., after the module and any dependency were loaded.) + bool is_start_entry; + + ExecModuleInfo() = default; + + llvm::telemetry::KindType getKind() const override { +return LLDBEntryKind::ExecModuleInfo; + } + + static bool classof(const TelemetryInfo *T) { +// Subclasses of this is also acceptable +return (T->getKind() & LLDBEntryKind::ExecModuleInfo) == + LLDBEntryKind::ExecModuleInfo; + } + void serialize(llvm::telemetry::Serializer &serializer) const override; +}; + +/// Describes an exit status. +struct ExitDescription { + int exit_code; oontvoo wrote: done https://github.com/llvm/llvm-project/pull/127834 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Remove UnwindPlan::Row shared_ptrs (PR #132370)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Pavel Labath (labath) Changes The surrounding code doesn't use them anymore. This removes the internal usages. This patch makes the Rows actual values. An alternative would be to make them unique_ptrs. That would make vector resizes faster at the cost of more pointer chasing and heap fragmentation. I don't know which one is better so I picked the simpler option. --- Full diff: https://github.com/llvm/llvm-project/pull/132370.diff 2 Files Affected: - (modified) lldb/include/lldb/Symbol/UnwindPlan.h (+5-22) - (modified) lldb/source/Symbol/UnwindPlan.cpp (+16-16) ``diff diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index db9aade93b6ba..ddc54a9fdc8ae 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -428,8 +428,6 @@ class UnwindPlan { bool m_unspecified_registers_are_undefined = false; }; // class Row - typedef std::shared_ptr RowSP; - UnwindPlan(lldb::RegisterKind reg_kind) : m_register_kind(reg_kind), m_return_addr_register(LLDB_INVALID_REGNUM), m_plan_is_sourced_from_compiler(eLazyBoolCalculate), @@ -437,25 +435,10 @@ class UnwindPlan { m_plan_is_for_signal_trap(eLazyBoolCalculate) {} // Performs a deep copy of the plan, including all the rows (expensive). - UnwindPlan(const UnwindPlan &rhs) - : m_plan_valid_ranges(rhs.m_plan_valid_ranges), -m_register_kind(rhs.m_register_kind), -m_return_addr_register(rhs.m_return_addr_register), -m_source_name(rhs.m_source_name), -m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler), -m_plan_is_valid_at_all_instruction_locations( -rhs.m_plan_is_valid_at_all_instruction_locations), -m_plan_is_for_signal_trap(rhs.m_plan_is_for_signal_trap), -m_lsda_address(rhs.m_lsda_address), -m_personality_func_addr(rhs.m_personality_func_addr) { -m_row_list.reserve(rhs.m_row_list.size()); -for (const RowSP &row_sp : rhs.m_row_list) - m_row_list.emplace_back(new Row(*row_sp)); - } + UnwindPlan(const UnwindPlan &rhs) = default; + UnwindPlan &operator=(const UnwindPlan &rhs) = default; + UnwindPlan(UnwindPlan &&rhs) = default; - UnwindPlan &operator=(const UnwindPlan &rhs) { -return *this = UnwindPlan(rhs); // NB: moving from a temporary (deep) copy - } UnwindPlan &operator=(UnwindPlan &&) = default; ~UnwindPlan() = default; @@ -486,7 +469,7 @@ class UnwindPlan { uint32_t GetInitialCFARegister() const { if (m_row_list.empty()) return LLDB_INVALID_REGNUM; -return m_row_list.front()->GetCFAValue().GetRegisterNumber(); +return m_row_list.front().GetCFAValue().GetRegisterNumber(); } // This UnwindPlan may not be valid at every address of the function span. @@ -569,7 +552,7 @@ class UnwindPlan { } private: - std::vector m_row_list; + std::vector m_row_list; std::vector m_plan_valid_ranges; lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers // are in terms of - will need to be diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index 48089cbdecd97..92daf29630ab6 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -391,29 +391,29 @@ bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const { } void UnwindPlan::AppendRow(Row row) { - if (m_row_list.empty() || m_row_list.back()->GetOffset() != row.GetOffset()) -m_row_list.push_back(std::make_shared(std::move(row))); + if (m_row_list.empty() || m_row_list.back().GetOffset() != row.GetOffset()) +m_row_list.push_back(std::move(row)); else -*m_row_list.back() = std::move(row); +m_row_list.back() = std::move(row); } struct RowLess { - bool operator()(addr_t a, const UnwindPlan::RowSP &b) const { -return a < b->GetOffset(); + bool operator()(addr_t a, const UnwindPlan::Row &b) const { +return a < b.GetOffset(); } - bool operator()(const UnwindPlan::RowSP &a, addr_t b) const { -return a->GetOffset() < b; + bool operator()(const UnwindPlan::Row &a, addr_t b) const { +return a.GetOffset() < b; } }; void UnwindPlan::InsertRow(Row row, bool replace_existing) { auto it = llvm::lower_bound(m_row_list, row.GetOffset(), RowLess()); - if (it == m_row_list.end() || it->get()->GetOffset() > row.GetOffset()) -m_row_list.insert(it, std::make_shared(std::move(row))); + if (it == m_row_list.end() || it->GetOffset() > row.GetOffset()) +m_row_list.insert(it, std::move(row)); else { -assert(it->get()->GetOffset() == row.GetOffset()); +assert(it->GetOffset() == row.GetOffset()); if (replace_existing) - **it = std::move(row); + *it = std::move(row); } } @@ -424,7 +424,7 @@ const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset(int offset)
[Lldb-commits] [lldb] [lldb] s/ValidRange/ValidRanges in UnwindPlan (PR #127661)
https://github.com/labath updated https://github.com/llvm/llvm-project/pull/127661 >From 22c489dbd334fb84b8d81deac8e7e6c5590fc6d9 Mon Sep 17 00:00:00 2001 From: Pavel Labath Date: Tue, 18 Feb 2025 16:14:30 +0100 Subject: [PATCH] [lldb] s/ValidRange/ValidRanges in UnwindPlan To be able to describe discontinuous functions, this patch changes the UnwindPlan to accept more than one address range. I've also squeezed in a couple improvements/modernizations, for example using the lower_bound function instead of a linear scan. --- lldb/include/lldb/Symbol/UnwindPlan.h | 17 ++-- .../ObjectFile/PECOFF/PECallFrameInfo.cpp | 4 +- .../Breakpad/SymbolFileBreakpad.cpp | 12 +-- .../x86/x86AssemblyInspectionEngine.cpp | 4 +- lldb/source/Symbol/CompactUnwindInfo.cpp | 2 +- lldb/source/Symbol/DWARFCallFrameInfo.cpp | 2 +- lldb/source/Symbol/UnwindPlan.cpp | 89 --- lldb/unittests/Symbol/CMakeLists.txt | 1 + lldb/unittests/Symbol/UnwindPlanTest.cpp | 76 .../x86/Testx86AssemblyInspectionEngine.cpp | 6 +- 10 files changed, 138 insertions(+), 75 deletions(-) create mode 100644 lldb/unittests/Symbol/UnwindPlanTest.cpp diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index 7c361bc08bcfe..db9aade93b6ba 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -438,7 +438,7 @@ class UnwindPlan { // Performs a deep copy of the plan, including all the rows (expensive). UnwindPlan(const UnwindPlan &rhs) - : m_plan_valid_address_range(rhs.m_plan_valid_address_range), + : m_plan_valid_ranges(rhs.m_plan_valid_ranges), m_register_kind(rhs.m_register_kind), m_return_addr_register(rhs.m_return_addr_register), m_source_name(rhs.m_source_name), @@ -492,10 +492,8 @@ class UnwindPlan { // This UnwindPlan may not be valid at every address of the function span. // For instance, a FastUnwindPlan will not be valid at the prologue setup // instructions - only in the body of the function. - void SetPlanValidAddressRange(const AddressRange &range); - - const AddressRange &GetAddressRange() const { -return m_plan_valid_address_range; + void SetPlanValidAddressRanges(std::vector ranges) { +m_plan_valid_ranges = std::move(ranges); } bool PlanValidAtAddress(Address addr); @@ -544,11 +542,11 @@ class UnwindPlan { m_plan_is_for_signal_trap = is_for_signal_trap; } - int GetRowCount() const; + int GetRowCount() const { return m_row_list.size(); } void Clear() { m_row_list.clear(); -m_plan_valid_address_range.Clear(); +m_plan_valid_ranges.clear(); m_register_kind = lldb::eRegisterKindDWARF; m_source_name.Clear(); m_plan_is_sourced_from_compiler = eLazyBoolCalculate; @@ -571,9 +569,8 @@ class UnwindPlan { } private: - typedef std::vector collection; - collection m_row_list; - AddressRange m_plan_valid_address_range; + std::vector m_row_list; + std::vector m_plan_valid_ranges; lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers // are in terms of - will need to be // translated to lldb native reg nums at unwind time diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.cpp index 459abe417035e..a7c2e4f0b8dbc 100644 --- a/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.cpp +++ b/lldb/source/Plugins/ObjectFile/PECOFF/PECallFrameInfo.cpp @@ -495,9 +495,9 @@ bool PECallFrameInfo::GetUnwindPlan(const AddressRange &range, for (auto it = rows.rbegin(); it != rows.rend(); ++it) unwind_plan.AppendRow(std::move(*it)); - unwind_plan.SetPlanValidAddressRange(AddressRange( + unwind_plan.SetPlanValidAddressRanges({AddressRange( m_object_file.GetAddress(runtime_function->StartAddress), - runtime_function->EndAddress - runtime_function->StartAddress)); + runtime_function->EndAddress - runtime_function->StartAddress)}); unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); return true; diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index 222e04a6a3464..ce2ba69be2e96 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -656,9 +656,9 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, plan_sp->SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); plan_sp->SetUnwindPlanForSignalTrap(eLazyBoolNo); plan_sp->SetSourcedFromCompiler(eLazyBoolYes); - plan_sp->SetPlanValidAddressRange( - AddressRange(base + init_record->Address, *init_record->Size, - m_objfile_sp->GetModule()->GetSectionList())); + plan_sp->SetPlanValidAddressRanges( +
[Lldb-commits] [clang] [clang-tools-extra] [lldb] [llvm] Add test to clang-doc, it can test comments in macro. Original issue is #59819. (PR #132360)
@@ -0,0 +1,32 @@ +// RUN: rm -rf %t && mkdir -p %t +// RUN: clang-doc --format=md --doxygen --output=%t --executor=standalone %s +// RUN: clang-doc --format=html --doxygen --output=%t --executor=standalone %s +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.md --check-prefix=MD-MyClass-LINE +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.md --check-prefix=MD-MyClass +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.html --check-prefix=HTML-MyClass-LINE +// RUN: FileCheck %s < %t/GlobalNamespace/MyClass.html --check-prefix=HTML-MyClass + +#define DECLARE_METHODS \ +/** + * @brief Declare a method to calculate the sum of two numbers ilovepi wrote: I don't think this comment is in the macro, did you intend it to be? Also as I understand it the bug wasn't filed about comments within macros, which I seldom see. But about comments attached to macros. I'd also suggest a simpler macro that doesn't define a full function (which also doesn't appear to actually be part of the macro.). Maybe the macro could be something like ```c++ /// Your doc comments #define ADD(a, b) a+b ``` https://github.com/llvm/llvm-project/pull/132360 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [libcxxabi] [lldb] [llvm] [WIP] [libcxxabi][ItaniumDemangle] Add infrastructure to track location information of parts of a demangled function name (PR #133249)
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/133249 >From 0875195a7ed39c21e9b639bf66d56b48e9869e51 Mon Sep 17 00:00:00 2001 From: Michael Buch Date: Tue, 11 Mar 2025 08:57:13 + Subject: [PATCH 1/4] [llvm][ItaniumDemangle] Add function name location tracking --- libcxxabi/src/demangle/ItaniumDemangle.h | 21 libcxxabi/src/demangle/Utility.cpp| 112 ++ libcxxabi/src/demangle/Utility.h | 91 +++--- libcxxabi/src/demangle/cp-to-llvm.sh | 62 +++--- llvm/include/llvm/Demangle/ItaniumDemangle.h | 21 llvm/include/llvm/Demangle/Utility.h | 91 +++--- llvm/lib/Demangle/CMakeLists.txt | 1 + llvm/lib/Demangle/README.txt | 61 ++ llvm/lib/Demangle/Utility.cpp | 112 ++ .../Demangle/ItaniumDemangleTest.cpp | 112 ++ 10 files changed, 635 insertions(+), 49 deletions(-) create mode 100644 libcxxabi/src/demangle/Utility.cpp create mode 100644 llvm/lib/Demangle/README.txt create mode 100644 llvm/lib/Demangle/Utility.cpp diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h index 3df41b5f4d7d0..b5a0a86b119f4 100644 --- a/libcxxabi/src/demangle/ItaniumDemangle.h +++ b/libcxxabi/src/demangle/ItaniumDemangle.h @@ -851,11 +851,13 @@ class FunctionType final : public Node { // by printing out the return types's left, then print our parameters, then // finally print right of the return type. void printLeft(OutputBuffer &OB) const override { +auto Scoped = OB.enterFunctionTypePrinting(); Ret->printLeft(OB); OB += " "; } void printRight(OutputBuffer &OB) const override { +auto Scoped = OB.enterFunctionTypePrinting(); OB.printOpen(); Params.printWithComma(OB); OB.printClose(); @@ -971,18 +973,32 @@ class FunctionEncoding final : public Node { const Node *getName() const { return Name; } void printLeft(OutputBuffer &OB) const override { +// Nested FunctionEncoding parsing can happen with following productions: +// * +// * +auto Scoped = OB.enterFunctionTypePrinting(); + if (Ret) { Ret->printLeft(OB); if (!Ret->hasRHSComponent(OB)) OB += " "; } + +OB.FunctionInfo.updateScopeStart(OB); + Name->print(OB); } void printRight(OutputBuffer &OB) const override { +auto Scoped = OB.enterFunctionTypePrinting(); +OB.FunctionInfo.finalizeStart(OB); + OB.printOpen(); Params.printWithComma(OB); OB.printClose(); + +OB.FunctionInfo.finalizeArgumentEnd(OB); + if (Ret) Ret->printRight(OB); @@ -1005,6 +1021,8 @@ class FunctionEncoding final : public Node { OB += " requires "; Requires->print(OB); } + +OB.FunctionInfo.finalizeEnd(OB); } }; @@ -1072,7 +1090,9 @@ struct NestedName : Node { void printLeft(OutputBuffer &OB) const override { Qual->print(OB); OB += "::"; +OB.FunctionInfo.updateScopeEnd(OB); Name->print(OB); +OB.FunctionInfo.updateBasenameEnd(OB); } }; @@ -1633,6 +1653,7 @@ struct NameWithTemplateArgs : Node { void printLeft(OutputBuffer &OB) const override { Name->print(OB); +OB.FunctionInfo.updateBasenameEnd(OB); TemplateArgs->print(OB); } }; diff --git a/libcxxabi/src/demangle/Utility.cpp b/libcxxabi/src/demangle/Utility.cpp new file mode 100644 index 0..04516082b3443 --- /dev/null +++ b/libcxxabi/src/demangle/Utility.cpp @@ -0,0 +1,112 @@ +//===--- Utility.cpp --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Provide some utility classes for use in the demangler. +// There are two copies of this file in the source tree. The one in libcxxabi +// is the original and the one in llvm is the copy. Use cp-to-llvm.sh to update +// the copy. See README.txt for more details. +// +//===--===// + +#include "Utility.h" +#include "DemangleConfig.h" + +DEMANGLE_NAMESPACE_BEGIN + +bool FunctionNameInfo::startedPrintingArguments() const { + return ArgumentLocs.first > 0; +} + +bool FunctionNameInfo::shouldTrack(OutputBuffer &OB) const { + if (!OB.isPrintingTopLevelFunctionType()) +return false; + + if (OB.isGtInsideTemplateArgs()) +return false; + + if (startedPrintingArguments()) +return false; + + return true; +} + +bool FunctionNameInfo::canFinalize(OutputBuffer &OB) const { + if (!OB.isPrintingTopLevelFunctionType()) +return false; + + if (OB.isGtInsideTemplateArgs()) +return false; + + if (!started
[Lldb-commits] [lldb] [lldb-dap] Adding support for cancelling a request. (PR #130169)
@@ -777,28 +798,134 @@ llvm::Error DAP::Disconnect(bool terminateDebuggee) { return ToError(error); } +template +static std::optional getArgumentsIfRequest(const protocol::Message &pm, + llvm::StringLiteral command) { + auto *const req = std::get_if(&pm); + if (!req || req->command != command) +return std::nullopt; + + T args; + llvm::json::Path::Root root; + if (!fromJSON(req->arguments, args, root)) { +return std::nullopt; + } + + return std::move(args); +} + llvm::Error DAP::Loop() { - auto cleanup = llvm::make_scope_exit([this]() { + std::deque queue; + std::condition_variable queue_cv; + std::mutex queue_mutex; + std::future queue_reader = std::async([&]() -> llvm::Error { +llvm::set_thread_name(transport.GetClientName() + ".transport_handler"); +auto cleanup = llvm::make_scope_exit([&]() { + // Ensure we're marked as disconnecting when the reader exits. + disconnecting = true; + queue_cv.notify_all(); +}); + +while (!disconnecting) { + llvm::Expected> next = + transport.Read(std::chrono::seconds(1)); + bool timeout = false; + if (llvm::Error Err = llvm::handleErrors( + next.takeError(), + [&](std::unique_ptr Err) -> llvm::Error { +if (Err->convertToErrorCode() == std::errc::timed_out) { + timeout = true; + return llvm::Error::success(); +} +return llvm::Error(std::move(Err)); + })) +return Err; + + // If the read timed out, continue to check if we should disconnect. + if (timeout) +continue; + + // nullopt is returned on EOF. + if (!*next) +break; + + { +std::lock_guard lock(queue_mutex); + +// If a cancel is requested for the active request, make a best +// effort attempt to interrupt. +if (const auto cancel_args = +getArgumentsIfRequest(**next, + "cancel"); +cancel_args && active_seq == cancel_args->requestId) { + DAP_LOG(log, "({0}) interrupting inflight request {1}", + transport.GetClientName(), active_seq); + debugger.RequestInterrupt(); + debugger.GetCommandInterpreter().InterruptCommand(); +} + +queue.push_back(std::move(**next)); + } + queue_cv.notify_one(); +} + +return llvm::Error::success(); + }); + + auto cleanup = llvm::make_scope_exit([&]() { out.Stop(); err.Stop(); StopEventHandlers(); }); + while (!disconnecting) { -llvm::Expected> next = transport.Read(); -if (!next) - return next.takeError(); +protocol::Message next; +{ + std::unique_lock lock(queue_mutex); + queue_cv.wait(lock, [&] { return disconnecting || !queue.empty(); }); -// nullopt on EOF -if (!*next) - break; + if (queue.empty()) +break; + + next = queue.front(); + queue.pop_front(); + + if (protocol::Request *req = std::get_if(&next)) { +active_seq = req->seq; + +// Check if we should preempt this request from a queued cancel. +bool cancelled = false; +for (const auto &message : queue) { JDevlieghere wrote: Rather than scanning the whole queue, would it be worth having a queue of cancellation requests (ids), so that this scan isn't linear in the number of pending requests? Maybe even make it a set so that duplicated cancellation requests can't create exponential behavior here. https://github.com/llvm/llvm-project/pull/130169 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Make the DAP server resilient against broken pipes (PR #133791)
ashgti wrote: I did that while I was trying to figure out how to have `cancel` request support. I was trying to close the FD to stop the reader thread, but that actually doesn't interrupt in-progress `read` calls. I should have reverted that when I did some of the `Transport` refactors. In my `cancel` request I use the `SelectHelper` to wait for input now. I can send a PR to change that to `false`. https://github.com/llvm/llvm-project/pull/133791 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Make the DAP server resilient against broken pipes (PR #133791)
JDevlieghere wrote: This doesn't seem to be enough. When I added this, the SIGHUP disappeared for a bunch of runs, but now I'm seeing it again, with this patch applied. https://github.com/llvm/llvm-project/pull/133791 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [lldb] Implement CLI support for reverse-continue (PR #132783)
@@ -220,6 +220,8 @@ Changes to LLDB information about the current state of the debugger at the bottom of the terminal. This is on by default and can be configured using the `show-statusline` and `statusline-format` settings. +* LLDB now supports `process continue --reverse` when used with backends DavidSpickett wrote: Agreed. Reader's have --reverse and --forward, that's enough to experiment with. https://github.com/llvm/llvm-project/pull/132783 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Do not take ownership of stdin. (PR #133811)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `lldb-aarch64-ubuntu` running on `linaro-lldb-aarch64-ubuntu` while building `lldb` at step 6 "test". Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/15220 Here is the relevant piece of the build log for the reference ``` Step 6 (test) failure: build (failure) ... PASS: lldb-unit :: Utility/./UtilityTests/7/8 (2101 of 2111) PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/8/11 (2102 of 2111) PASS: lldb-unit :: ValueObject/./LLDBValueObjectTests/9/11 (2103 of 2111) PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/1/2 (2104 of 2111) PASS: lldb-unit :: tools/lldb-server/tests/./LLDBServerTests/0/2 (2105 of 2111) PASS: lldb-unit :: Host/./HostTests/9/12 (2106 of 2111) PASS: lldb-unit :: Target/./TargetTests/11/14 (2107 of 2111) PASS: lldb-unit :: Host/./HostTests/3/12 (2108 of 2111) PASS: lldb-unit :: Process/gdb-remote/./ProcessGdbRemoteTests/8/9 (2109 of 2111) UNRESOLVED: lldb-api :: tools/lldb-server/TestLldbGdbServer.py (2110 of 2111) TEST 'lldb-api :: tools/lldb-server/TestLldbGdbServer.py' FAILED Script: -- /usr/bin/python3.10 /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib --env LLVM_INCLUDE_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/include --env LLVM_TOOLS_DIR=/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --arch aarch64 --build-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex --lldb-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-lldb/lldb-api --clang-module-cache-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/lldb-test-build.noindex/module-cache-clang/lldb-api --executable /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/lldb --compiler /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/clang --dsymutil /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./bin --lldb-obj-root /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/tools/lldb --lldb-libs-dir /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/./lib /home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/llvm-project/lldb/test/API/tools/lldb-server -p TestLldbGdbServer.py -- Exit Code: 1 Command Output (stdout): -- lldb version 21.0.0git (https://github.com/llvm/llvm-project.git revision 4492632432190ed8ab3bc39ff8ee5ba9a89256cf) clang revision 4492632432190ed8ab3bc39ff8ee5ba9a89256cf llvm revision 4492632432190ed8ab3bc39ff8ee5ba9a89256cf Skipping the following test categories: ['libc++', 'dsym', 'gmodules', 'debugserver', 'objc'] -- Command Output (stderr): -- UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hc_then_Csignal_signals_correct_thread_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_another_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_minus_one_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_fails_on_zero_pid_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_Hg_switches_to_3_threads_launch_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this run) PASS: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_and_p_thread_suffix_work_llgs (TestLldbGdbServer.LldbGdbServerTestCase) UNSUPPORTED: LLDB (/home/tcwg-buildbot/worker/lldb-aarch64-ubuntu/build/bin/clang-aarch64) :: test_P_writes_all_gpr_registers_debugserver (TestLldbGdbServer.LldbGdbServerTestCase) (test case does not fall in any category of interest for this
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,273 @@ +//===-- DILParser.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Utility/DiagnosticsRendering.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" +#include +#include +#include +#include +#include + +namespace lldb_private::dil { + +std::string FormatDiagnostics(llvm::StringRef text, const std::string &message, + uint32_t loc, uint16_t err_len) { + DiagnosticDetail::SourceLocation sloc = { + FileSpec{}, /*line=*/1, static_cast(loc + 1), + err_len,false, /*in_user_input=*/true}; + std::string arrow_str = "^"; + std::string rendered_msg = + llvm::formatv(":1:{0}: {1}\n1 | {2}\n | ^", +loc + 1, message, text); + DiagnosticDetail detail; + detail.source_location = sloc; + detail.severity = lldb::eSeverityError; + detail.message = message; + detail.rendered = rendered_msg; + std::vector diagnostics; + diagnostics.push_back(detail); + StreamString diag_stream(true); + RenderDiagnosticDetails(diag_stream, 7, true, diagnostics); + std::string ret_str = text.str() + "\n" + diag_stream.GetString().str(); + return ret_str; +} + +llvm::Expected +DILParser::Parse(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) { + Status error; + DILParser parser(dil_input_expr, lexer, frame_sp, use_dynamic, use_synthetic, + fragile_ivar, check_ptr_vs_member, error); + return parser.Run(); +} + +DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member, Status &error) +: m_ctx_scope(frame_sp), m_input_expr(dil_input_expr), m_dil_lexer(lexer), + m_error(error), m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic), m_fragile_ivar(fragile_ivar), + m_check_ptr_vs_member(check_ptr_vs_member) {} + +llvm::Expected DILParser::Run() { + ASTNodeUP expr = ParseExpression(); + + Expect(Token::Kind::eof); + + if (m_error.Fail()) +return m_error.ToError(); + + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +ASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"(" expression ")" +// +ASTNodeUP DILParser::ParsePrimaryExpression() { + if (CurToken().IsOneOf({Token::coloncolon, Token::identifier})) { +// Save the source location for the diagnostics message. +uint32_t loc = CurToken().GetLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier, m_use_dynamic, +m_ctx_scope); + } else if (CurToken().Is(Token::l_paren)) { +m_dil_lexer.Advance(); +auto expr = ParseExpression(); +Expect(Token::r_paren); +m_dil_lexer.Advance(); +return expr; + } + + BailOut(ErrorCode::kInvalidExpressionSyntax, + llvm::formatv("Unexpected token: {0}", CurToken()), + CurToken().GetLocation()); + return std::make_unique(); +} + +// Parse nested_name_specifier. +// +// nested_name_specifier: +//type_name "::" +//namespace_name "::" +//nested_name_specifier identifier "::" +// +std::string DILParser::ParseNestedNameSpecifier() { + // The first token in nested_name_specifier is always an identifier, or + // '(anonymous namespace)'. + if (CurToken().IsNot(Token::identifier) && CurToken().IsNot(Token::l_paren)) { +return ""; + } + + // Anonymous namespaces need to be treated specially: They are represented + // the the string '(anonymous namespace)', which has a space in it (throwing + // off normal parsing) and is not actually proper C++> Check to see if we're + // looking at '(anonymous namespace)::...' + if (CurToken().Is(Token::l_paren)) { +// Look for all the pieces, in order: +// l_paren 'anonymous
[Lldb-commits] [lldb] [lldb] Create a default rate limit constant in Progress (NFC) (PR #133506)
https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/133506 >From 497d45360ad50ae909d946b4a34b55346c56ff69 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Fri, 28 Mar 2025 11:55:23 -0700 Subject: [PATCH 1/2] [lldb] Create a default rate limit constant in Progress (NFC) In #133211, Greg suggested making the rate limit configurable through a setting. Although adding the setting is easy, the two places where we currently use rate limiting aren't tied to a particular debugger. I still think it's a good idea to be consistent and make it easy to pick the same rate limiting value, so I've moved it into a constant in the Progress class. --- lldb/include/lldb/Core/Progress.h | 4 lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp | 2 +- .../Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h index 3003568e8946b..104a8c0feb80a 100644 --- a/lldb/include/lldb/Core/Progress.h +++ b/lldb/include/lldb/Core/Progress.h @@ -115,6 +115,10 @@ class Progress { /// Used to indicate a non-deterministic progress report static constexpr uint64_t kNonDeterministicTotal = UINT64_MAX; + /// The default rate limit for high frequency progress reports. + static constexpr std::chrono::milliseconds kDefaultRateLimit = + std::chrono::milliseconds(20); + private: void ReportProgress(); static std::atomic g_id; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index 6f2c45e74132c..f6304a7a4b9ba 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -81,7 +81,7 @@ void ManualDWARFIndex::Index() { const uint64_t total_progress = units_to_index.size() * 2 + 8; Progress progress("Manually indexing DWARF", module_desc.GetData(), total_progress, /*debugger=*/nullptr, -/*minimum_report_time=*/std::chrono::milliseconds(20)); +Progress::kDefaultRateLimit); // Share one thread pool across operations to avoid the overhead of // recreating the threads. diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index e346d588a449f..8b72c96dc6f33 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -723,8 +723,7 @@ void SymbolFileDWARFDebugMap::ForEachSymbolFile( std::function closure) { const size_t num_oso_idxs = m_compile_unit_infos.size(); Progress progress(std::move(description), "", num_oso_idxs, -/*debugger=*/nullptr, -/*minimum_report_time=*/std::chrono::milliseconds(20)); +/*debugger=*/nullptr, Progress::kDefaultRateLimit); for (uint32_t oso_idx = 0; oso_idx < num_oso_idxs; ++oso_idx) { if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx)) { progress.Increment(oso_idx, oso_dwarf->GetObjectFile() >From f4ac987ba2cb68c614ed641c9f29731ca9b825fb Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 31 Mar 2025 08:28:50 -0700 Subject: [PATCH 2/2] kDefaultRateLimit -> kDefaultHighFrequencyReportTime --- lldb/include/lldb/Core/Progress.h | 4 ++-- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp | 2 +- .../Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lldb/include/lldb/Core/Progress.h b/lldb/include/lldb/Core/Progress.h index 104a8c0feb80a..93e34084d7ec1 100644 --- a/lldb/include/lldb/Core/Progress.h +++ b/lldb/include/lldb/Core/Progress.h @@ -115,8 +115,8 @@ class Progress { /// Used to indicate a non-deterministic progress report static constexpr uint64_t kNonDeterministicTotal = UINT64_MAX; - /// The default rate limit for high frequency progress reports. - static constexpr std::chrono::milliseconds kDefaultRateLimit = + /// The default report time for high frequency progress reports. + static constexpr std::chrono::milliseconds kDefaultHighFrequencyReportTime = std::chrono::milliseconds(20); private: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index f6304a7a4b9ba..047967a30d098 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -81,7 +81,7 @@ void ManualDWARFIndex::Index() { const uint64_t total_progress = units_to_index.size() * 2 + 8; Progress progress("Manually indexing DWARF", module_desc.GetData(), total_progress, /*debu
[Lldb-commits] [lldb] [lldb] Fix plugin manager test failure on windows (PR #134173)
https://github.com/dmpots closed https://github.com/llvm/llvm-project/pull/134173 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Parallelize module loading in POSIX dyld code (PR #130912)
https://github.com/royitaqi closed https://github.com/llvm/llvm-project/pull/130912 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Move two methods from Platfrom -> Host (NFC) (PR #132119)
https://github.com/JDevlieghere closed https://github.com/llvm/llvm-project/pull/132119 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Clear thread name container before writing UTF8 bytes (PR #134150)
ktraunmueller wrote: Just out of curiosity: I was also surprised by the precondition, which looks unnecessary and, more importantly, very unexpected, to me. How would a caller know (from looking at the API) that passing a non-empty string would be fatal? If there's a preconditions in the code, I would expect it to be reflected in the documentation. But since there's no documentation (also unexpected), does that mean that every method needs to be carefully checked for assertions before using it? https://github.com/llvm/llvm-project/pull/134150 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Handle improperly nested blocks differently (PR #117725)
@@ -0,0 +1,100 @@ +## This test checks that lldb handles (corrupt?) debug info which has improperly +## nested blocks. The behavior here is not prescriptive. We only want to check +## that we do something "reasonable". + + +# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t +# RUN: %lldb %t -o "image lookup -v -s look_me_up1" \ +# RUN: -o "image lookup -v -s look_me_up2" -o exit 2>&1 | FileCheck %s + +# CHECK-LABEL: image lookup -v -s look_me_up1 +# CHECK: warning: {{.*}} block 0x55 has a range [0x2, 0x4) which is not contained in the parent block 0x44 +# CHECK:Function: id = {0x0030}, name = "fn", range = [0x-0x0005) +# CHECK: Blocks: id = {0x0030}, range = [0x-0x0005) +# CHECK-NEXT: id = {0x0044}, range = [0x0001-0x0003) +# CHECK-NEXT: id = {0x0055}, range = [0x0002-0x0004) +# CHECK-NEXT: Symbol: + +# CHECK-LABEL: image lookup -v -s look_me_up2 +# CHECK:Function: id = {0x0030}, name = "fn", range = [0x-0x0005) +# CHECK: Blocks: id = {0x0030}, range = [0x-0x0005) +# CHECK-NEXT: Symbol: + +.text +.p2align 12 +fn: +nop +.Lblock1_begin: +nop +.Lblock2_begin: +look_me_up1: +nop +.Lblock1_end: +look_me_up2: +nop +.Lblock2_end: +nop +.Lfn_end: + + +.section.debug_abbrev,"",@progbits labath wrote: I've added something, though it may not be exactly what you asked for. The problem is definitely in the DWARF. There isn't really a *function* here. The code is there just to provide labels that the debug info can refer to. (Or, think of it like this: it the debug info that defines what lldb considers to be a "function") https://github.com/llvm/llvm-project/pull/117725 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB][Telemetry] Collect telemetry from client when allowed. (PR #129728)
https://github.com/oontvoo updated https://github.com/llvm/llvm-project/pull/129728 >From 21103adacdf9c08cee4065f8a6b90ff812fefbb3 Mon Sep 17 00:00:00 2001 From: Vy Nguyen Date: Tue, 4 Mar 2025 11:01:46 -0500 Subject: [PATCH 01/10] [LLDB][Telemetry] Collect telemetry from client when allowed. This patch is slightly different from other impl in that we dispatch client-telemetry via a different helper method. This is to make it easier for vendor to opt-out (simply by overriding the method to do nothing). There is also a configuration option to disallow collecting client telemetry. --- lldb/include/lldb/API/SBDebugger.h| 3 + lldb/include/lldb/Core/Debugger.h | 5 ++ lldb/include/lldb/Core/Telemetry.h| 89 +--- lldb/source/API/SBDebugger.cpp| 11 +++ lldb/source/Core/Debugger.cpp | 6 ++ lldb/source/Core/Telemetry.cpp| 99 +++ lldb/tools/lldb-dap/DAP.cpp | 5 +- lldb/tools/lldb-dap/LLDBUtils.h | 34 + lldb/unittests/Core/TelemetryTest.cpp | 2 +- 9 files changed, 214 insertions(+), 40 deletions(-) diff --git a/lldb/include/lldb/API/SBDebugger.h b/lldb/include/lldb/API/SBDebugger.h index e0819f1684f8b..28f92f2095951 100644 --- a/lldb/include/lldb/API/SBDebugger.h +++ b/lldb/include/lldb/API/SBDebugger.h @@ -13,6 +13,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBPlatform.h" +#include "lldb/API/SBStructuredData.h" namespace lldb_private { class CommandPluginInterfaceImplementation; @@ -249,6 +250,8 @@ class LLDB_API SBDebugger { lldb::SBTarget GetDummyTarget(); + void DispatchClientTelemetry(const lldb::SBStructuredData &data); + // Return true if target is deleted from the target list of the debugger. bool DeleteTarget(lldb::SBTarget &target); diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h index 6ebc6147800e1..e40666d5ceec7 100644 --- a/lldb/include/lldb/Core/Debugger.h +++ b/lldb/include/lldb/Core/Debugger.h @@ -19,6 +19,8 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/SourceManager.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Core/Telemetry.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/StreamFile.h" @@ -31,6 +33,7 @@ #include "lldb/Utility/Diagnostics.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -127,6 +130,8 @@ class Debugger : public std::enable_shared_from_this, void Clear(); + void DispatchClientTelemetry(const lldb_private::StructuredDataImpl &entry); + bool GetAsyncExecution(); void SetAsyncExecution(bool async); diff --git a/lldb/include/lldb/Core/Telemetry.h b/lldb/include/lldb/Core/Telemetry.h index 7d8716f1659b5..cad4a4a6c9048 100644 --- a/lldb/include/lldb/Core/Telemetry.h +++ b/lldb/include/lldb/Core/Telemetry.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" #include "llvm/Telemetry/Telemetry.h" +#include #include #include #include @@ -28,6 +29,23 @@ namespace lldb_private { namespace telemetry { +struct LLDBConfig : public ::llvm::telemetry::Config { + // If true, we will collect full details about a debug command (eg., args and + // original command). Note: This may contain PII, hence can only be enabled by + // the vendor while creating the Manager. + const bool m_detailed_command_telemetry; + // If true, we will collect telemetry from LLDB's clients (eg., lldb-dap) via + // the SB interface. Must also be enabled by the vendor while creating the + // manager. + const bool m_enable_client_telemetry; + + explicit LLDBConfig(bool enable_telemetry, bool detailed_command_telemetry, + bool enable_client_telemetry) + : ::llvm::telemetry::Config(enable_telemetry), +m_detailed_command_telemetry(detailed_command_telemetry), +m_enable_client_telemetry(enable_client_telemetry) {} +}; + // We expect each (direct) subclass of LLDBTelemetryInfo to // have an LLDBEntryKind in the form 0b11 // Specifically: @@ -37,6 +55,7 @@ namespace telemetry { // must have their LLDBEntryKind in the similar form (ie., share common prefix) struct LLDBEntryKind : public ::llvm::telemetry::EntryKind { static const llvm::telemetry::KindType BaseInfo = 0b1100; + static const llvm::telemetry::KindType ClientInfo = 0b1110; static const llvm::telemetry::KindType DebuggerInfo = 0b11000100; }; @@ -86,6 +105,11 @@ struct DebuggerInfo : public LLDBBaseTelemetryInfo { void serialize(llvm::telemetry::Serializer &serializer) const override; }; +struct ClientInfo : public LLDBBaseTelemetryInfo { + std::string request_name; + std::optional error_msg; +}; + /// The base Telemetry manager instance in LL
[Lldb-commits] [lldb] [lldb] s/ValidRange/ValidRanges in UnwindPlan (PR #127661)
labath wrote: @JDevlieghere, @jasonmolenda any chance I could get a review on this patch? Or ask me questions -- I can explain where I'm trying to go with this. As much as I like refactoring around this code, I do actually need to make progress on adding the functionality. :) https://github.com/llvm/llvm-project/pull/127661 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][lldb-dap] Added support for "WriteMemory" request. (PR #131820)
github-actions[bot] wrote: :warning: Python code formatter, darker found issues in your code. :warning: You can test this locally with the following command: ``bash darker --check --diff -r 351bcd9fe229121fac58e051f9a83dce2d3066ae...9a6d64373f45921c5b23460b12544869355ddd15 lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py `` View the diff from darker here. ``diff --- packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 2025-03-18 15:04:25.00 + +++ packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 2025-03-18 15:15:34.959979 + @@ -723,10 +723,11 @@ "command": "readMemory", "type": "request", "arguments": args_dict, } return self.send_recv(command_dict) + def request_writeMemory(self, memoryReference, offset, data): args_dict = { "memoryReference": memoryReference, "offset": offset, "data": data, `` https://github.com/llvm/llvm-project/pull/131820 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Convert Breakpoint & Watchpoints structs to classes (NFC) (PR #133780)
https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/133780 Convert Breakpoint & Watchpoints structs to classes to provide proper access control. This is in preparation for adopting SBMutex to protect the underlying SBBreakpoint and SBWatchpoint. >From 2f22b24840ec0f3cb650da97ad0bd2caea0a8cef Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Mon, 31 Mar 2025 11:47:02 -0700 Subject: [PATCH] [lldb] Convert Breakpoint & Watchpoints structs to classes (NFC) Convert Breakpoint & Watchpoints structs to classes to provide proper access control. This is in preparation for adopting SBMutex to protect the underlying SBBreakpoint and SBWatchpoint. --- lldb/tools/lldb-dap/Breakpoint.cpp| 24 + lldb/tools/lldb-dap/Breakpoint.h | 14 +++-- lldb/tools/lldb-dap/BreakpointBase.h | 23 lldb/tools/lldb-dap/DAP.cpp | 8 +-- lldb/tools/lldb-dap/DAP.h | 2 +- lldb/tools/lldb-dap/DAPForward.h | 16 +++--- lldb/tools/lldb-dap/ExceptionBreakpoint.cpp | 18 +++ lldb/tools/lldb-dap/ExceptionBreakpoint.h | 28 ++ lldb/tools/lldb-dap/FunctionBreakpoint.cpp| 6 +-- lldb/tools/lldb-dap/FunctionBreakpoint.h | 12 +++-- .../Handler/ExceptionInfoRequestHandler.cpp | 4 +- .../Handler/SetBreakpointsRequestHandler.cpp | 7 +-- .../SetDataBreakpointsRequestHandler.cpp | 4 +- .../SetExceptionBreakpointsRequestHandler.cpp | 4 +- .../SetFunctionBreakpointsRequestHandler.cpp | 8 +-- ...etInstructionBreakpointsRequestHandler.cpp | 6 +-- lldb/tools/lldb-dap/InstructionBreakpoint.cpp | 11 ++-- lldb/tools/lldb-dap/InstructionBreakpoint.h | 19 --- lldb/tools/lldb-dap/JSONUtils.cpp | 8 +-- lldb/tools/lldb-dap/SourceBreakpoint.cpp | 6 +-- lldb/tools/lldb-dap/SourceBreakpoint.h| 52 ++- lldb/tools/lldb-dap/Watchpoint.cpp| 21 lldb/tools/lldb-dap/Watchpoint.h | 22 23 files changed, 180 insertions(+), 143 deletions(-) diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp index eba534dcc51c7..188a51909f111 100644 --- a/lldb/tools/lldb-dap/Breakpoint.cpp +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -19,21 +19,21 @@ using namespace lldb_dap; -void Breakpoint::SetCondition() { bp.SetCondition(condition.c_str()); } +void Breakpoint::SetCondition() { m_bp.SetCondition(condition.c_str()); } void Breakpoint::SetHitCondition() { uint64_t hitCount = 0; if (llvm::to_integer(hitCondition, hitCount)) -bp.SetIgnoreCount(hitCount - 1); +m_bp.SetIgnoreCount(hitCount - 1); } void Breakpoint::CreateJsonObject(llvm::json::Object &object) { // 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. - if (!bp.IsValid()) + if (!m_bp.IsValid()) return; - object.try_emplace("verified", bp.GetNumResolvedLocations() > 0); - object.try_emplace("id", bp.GetID()); + object.try_emplace("verified", m_bp.GetNumResolvedLocations() > 0); + object.try_emplace("id", m_bp.GetID()); // VS Code DAP doesn't currently allow one breakpoint to have multiple // locations so we just report the first one. If we report all locations // then the IDE starts showing the wrong line numbers and locations for @@ -43,20 +43,20 @@ void Breakpoint::CreateJsonObject(llvm::json::Object &object) { // this as the breakpoint location since it will have a complete location // that is at least loaded in the current process. lldb::SBBreakpointLocation bp_loc; - const auto num_locs = bp.GetNumLocations(); + const auto num_locs = m_bp.GetNumLocations(); for (size_t i = 0; i < num_locs; ++i) { -bp_loc = bp.GetLocationAtIndex(i); +bp_loc = m_bp.GetLocationAtIndex(i); if (bp_loc.IsResolved()) break; } // If not locations are resolved, use the first location. if (!bp_loc.IsResolved()) -bp_loc = bp.GetLocationAtIndex(0); +bp_loc = m_bp.GetLocationAtIndex(0); auto bp_addr = bp_loc.GetAddress(); if (bp_addr.IsValid()) { std::string formatted_addr = -"0x" + llvm::utohexstr(bp_addr.GetLoadAddress(bp.GetTarget())); +"0x" + llvm::utohexstr(bp_addr.GetLoadAddress(m_bp.GetTarget())); object.try_emplace("instructionReference", formatted_addr); auto line_entry = bp_addr.GetLineEntry(); const auto line = line_entry.GetLine(); @@ -69,10 +69,12 @@ void Breakpoint::CreateJsonObject(llvm::json::Object &object) { } } -bool Breakpoint::MatchesName(const char *name) { return bp.MatchesName(name); } +bool Breakpoint::MatchesName(const char *name) { + return m_bp.MatchesName(name); +} void Breakpoint::SetBreakpoint() { - bp.AddName(kDAPBreakpointLabel); + m_bp.AddName(kDAPBreakpointLabel); if (!condition.empty()) SetCondition(); if (!hitCondition.empty()) diff --gi
[Lldb-commits] [lldb] [lldb-dap] Adding support for well typed events. (PR #130104)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/130104 >From 2c51a8bdb27764a358e76e554d693a4af57074fc Mon Sep 17 00:00:00 2001 From: John Harrison Date: Thu, 6 Mar 2025 14:13:58 +0100 Subject: [PATCH] [lldb-dap] Adding support for well typed events. This adds a mechanism for registering well typed events with the DAP. For a proof of concept, this updates the 'exited' and the 'process' event to use the new protocol serialization handlers and updates the call sites to use the new helper. --- lldb/tools/lldb-dap/CMakeLists.txt| 6 +- lldb/tools/lldb-dap/DAP.cpp | 5 +- lldb/tools/lldb-dap/DAP.h | 14 +++ lldb/tools/lldb-dap/EventHelper.cpp | 90 --- lldb/tools/lldb-dap/EventHelper.h | 6 -- lldb/tools/lldb-dap/Events/EventHandler.h | 57 .../lldb-dap/Events/ExitedEventHandler.cpp| 20 + .../lldb-dap/Events/ProcessEventHandler.cpp | 34 +++ .../lldb-dap/Handler/AttachRequestHandler.cpp | 2 +- .../Handler/InitializeRequestHandler.cpp | 2 +- .../lldb-dap/Handler/LaunchRequestHandler.cpp | 5 +- lldb/tools/lldb-dap/Protocol/ProtocolBase.h | 4 +- .../lldb-dap/Protocol/ProtocolEvents.cpp | 46 ++ lldb/tools/lldb-dap/Protocol/ProtocolEvents.h | 76 lldb/tools/lldb-dap/lldb-dap.cpp | 1 + 15 files changed, 262 insertions(+), 106 deletions(-) create mode 100644 lldb/tools/lldb-dap/Events/EventHandler.h create mode 100644 lldb/tools/lldb-dap/Events/ExitedEventHandler.cpp create mode 100644 lldb/tools/lldb-dap/Events/ProcessEventHandler.cpp create mode 100644 lldb/tools/lldb-dap/Protocol/ProtocolEvents.cpp create mode 100644 lldb/tools/lldb-dap/Protocol/ProtocolEvents.h diff --git a/lldb/tools/lldb-dap/CMakeLists.txt b/lldb/tools/lldb-dap/CMakeLists.txt index adad75a79fa7a..54e6f3ead2695 100644 --- a/lldb/tools/lldb-dap/CMakeLists.txt +++ b/lldb/tools/lldb-dap/CMakeLists.txt @@ -37,6 +37,9 @@ add_lldb_tool(lldb-dap Transport.cpp Watchpoint.cpp + Events/ExitedEventHandler.cpp + Events/ProcessEventHandler.cpp + Handler/ResponseHandler.cpp Handler/AttachRequestHandler.cpp Handler/BreakpointLocationsHandler.cpp @@ -75,8 +78,9 @@ add_lldb_tool(lldb-dap Handler/VariablesRequestHandler.cpp Protocol/ProtocolBase.cpp - Protocol/ProtocolTypes.cpp + Protocol/ProtocolEvents.cpp Protocol/ProtocolRequests.cpp + Protocol/ProtocolTypes.cpp LINK_LIBS liblldb diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index a1e2187288768..a2ae96eb5d967 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -8,6 +8,7 @@ #include "DAP.h" #include "DAPLog.h" +#include "Events/EventHandler.h" #include "Handler/RequestHandler.h" #include "Handler/ResponseHandler.h" #include "JSONUtils.h" @@ -82,7 +83,9 @@ DAP::DAP(llvm::StringRef path, std::ofstream *log, configuration_done_sent(false), waiting_for_run_in_terminal(false), progress_event_reporter( [&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }), - reverse_request_seq(0), repl_mode(default_repl_mode) {} + reverse_request_seq(0), repl_mode(default_repl_mode), + onExited(ExitedEventHandler(*this)), + onProcess(ProcessEventHandler(*this)) {} DAP::~DAP() = default; diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h index 4c57f9fef3d89..fe902e670cf04 100644 --- a/lldb/tools/lldb-dap/DAP.h +++ b/lldb/tools/lldb-dap/DAP.h @@ -58,6 +58,9 @@ typedef llvm::StringMap FunctionBreakpointMap; typedef llvm::DenseMap InstructionBreakpointMap; +/// A debug adapter initiated event. +template using OutgoingEvent = std::function; + enum class OutputType { Console, Stdout, Stderr, Telemetry }; /// Buffer size for handling output events. @@ -230,6 +233,17 @@ struct DAP { void operator=(const DAP &rhs) = delete; /// @} + /// Typed Events Handlers + /// @{ + + /// onExited sends an event that the debuggee has exited. + OutgoingEvent<> onExited; + /// onProcess sends an event that indicates that the debugger has begun + /// debugging a new process. + OutgoingEvent<> onProcess; + + /// @} + ExceptionBreakpoint *GetExceptionBreakpoint(const std::string &filter); ExceptionBreakpoint *GetExceptionBreakpoint(const lldb::break_id_t bp_id); diff --git a/lldb/tools/lldb-dap/EventHelper.cpp b/lldb/tools/lldb-dap/EventHelper.cpp index 705eb0a457d9c..7908674eb4642 100644 --- a/lldb/tools/lldb-dap/EventHelper.cpp +++ b/lldb/tools/lldb-dap/EventHelper.cpp @@ -32,87 +32,6 @@ static void SendThreadExitedEvent(DAP &dap, lldb::tid_t tid) { dap.SendJSON(llvm::json::Value(std::move(event))); } -// "ProcessEvent": { -// "allOf": [ -// { "$ref": "#/definitions/Event" }, -// { -// "type": "object", -// "description": "Event message for 'process' event type. The event -//
[Lldb-commits] [clang] [clang-tools-extra] [lldb] Reland: [clang] preserve class type sugar when taking pointer to member (PR #132234)
llvmbot wrote: @llvm/pr-subscribers-clang-tools-extra @llvm/pr-subscribers-clang Author: Matheus Izvekov (mizvekov) Changes Original PR: #130537 Reland after updating lldb too. This changes the MemberPointerType representation to use a NestedNameSpecifier instead of a Type to represent the base class. Since the qualifiers are always parsed as nested names, there was an impedance mismatch when converting these back and forth into types, and this led to issues in preserving sugar. The nested names are indeed a better match for these, as the differences which a QualType can represent cannot be expressed syntatically, and they represent the use case more exactly, being either dependent or referring to a CXXRecord, unqualified. This patch also makes the MemberPointerType able to represent sugar for a {up/downcast}cast conversion of the base class, although for now the underlying type is canonical, as preserving the sugar up to that point requires further work. As usual, includes a few drive-by fixes in order to make use of the improvements. --- Patch is 143.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132234.diff 71 Files Affected: - (modified) clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp (+1-2) - (modified) clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp (+3-1) - (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+1-1) - (modified) clang/docs/ReleaseNotes.rst (+1) - (modified) clang/include/clang/AST/ASTContext.h (+3-4) - (modified) clang/include/clang/AST/ASTNodeTraverser.h (+5-2) - (modified) clang/include/clang/AST/CanonicalType.h (+1-1) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+5-4) - (modified) clang/include/clang/AST/Type.h (+15-13) - (modified) clang/include/clang/AST/TypeLoc.h (+19-14) - (modified) clang/include/clang/AST/TypeProperties.td (+6-3) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2-4) - (modified) clang/include/clang/Sema/Sema.h (+9-2) - (modified) clang/lib/AST/ASTContext.cpp (+47-21) - (modified) clang/lib/AST/ASTImporter.cpp (+9-5) - (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+6-2) - (modified) clang/lib/AST/ItaniumMangle.cpp (+10-1) - (modified) clang/lib/AST/NestedNameSpecifier.cpp (+1) - (modified) clang/lib/AST/ODRHash.cpp (+1-1) - (modified) clang/lib/AST/QualTypeNames.cpp (+4-3) - (modified) clang/lib/AST/Type.cpp (+30-4) - (modified) clang/lib/AST/TypePrinter.cpp (+2-2) - (modified) clang/lib/CodeGen/CGCXXABI.cpp (+1-1) - (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+2-2) - (modified) clang/lib/CodeGen/CGVTables.cpp (+2-3) - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) - (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+5-5) - (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+4-3) - (modified) clang/lib/Sema/SemaAccess.cpp (+18-8) - (modified) clang/lib/Sema/SemaCast.cpp (+2-2) - (modified) clang/lib/Sema/SemaExpr.cpp (+4-6) - (modified) clang/lib/Sema/SemaExprCXX.cpp (+3-1) - (modified) clang/lib/Sema/SemaOpenMP.cpp (+2-3) - (modified) clang/lib/Sema/SemaOverload.cpp (+60-27) - (modified) clang/lib/Sema/SemaTemplate.cpp (+6-2) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+16-5) - (modified) clang/lib/Sema/SemaType.cpp (+22-100) - (modified) clang/lib/Sema/TreeTransform.h (+29-30) - (modified) clang/lib/Serialization/ASTReader.cpp (+1-1) - (modified) clang/lib/Serialization/ASTWriter.cpp (+1-1) - (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+3-1) - (modified) clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp (+3-1) - (modified) clang/test/AST/ast-dump-templates.cpp (+238) - (modified) clang/test/AST/ast-dump-types-json.cpp (+338-44) - (modified) clang/test/AST/attr-print-emit.cpp (+1-1) - (modified) clang/test/Analysis/cxx-uninitialized-object-ptr-ref.cpp (+5-5) - (modified) clang/test/CXX/class.access/p6.cpp (+2-2) - (modified) clang/test/CXX/drs/cwg0xx.cpp (+6-6) - (modified) clang/test/CXX/drs/cwg13xx.cpp (+2-2) - (modified) clang/test/CXX/drs/cwg26xx.cpp (+3-3) - (modified) clang/test/CXX/drs/cwg2xx.cpp (+2-2) - (modified) clang/test/CXX/drs/cwg4xx.cpp (+1-1) - (modified) clang/test/CXX/drs/cwg7xx.cpp (+1-2) - (modified) clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp (+1-1) - (modified) clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp (+3-3) - (modified) clang/test/Index/print-type.cpp (+1-1) - (modified) clang/test/SemaCXX/addr-of-overloaded-function.cpp (+13-13) - (modified) clang/test/SemaCXX/builtin-ptrtomember-ambig.cpp (+2-2) - (modified) clang/test/SemaCXX/calling-conv-compat.cpp (+21-21) - (modified) clang/test/SemaCXX/err_init_conversion_failed.cpp (+1-1) - (modified) clang/test/SemaCXX/member-pointer.cpp (+13-4) - (modified) clang/test/SemaOpenACC/combined-construct-if-ast.cpp (+2-2) - (modified) clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp (+2-2) - (modified) c
[Lldb-commits] [lldb] [lldb] Remove raw access to PluginInstances vector (PR #132884)
https://github.com/dmpots updated https://github.com/llvm/llvm-project/pull/132884 >From 6edc108199044d30eed396145aab463db40d6351 Mon Sep 17 00:00:00 2001 From: David Peixotto Date: Thu, 13 Mar 2025 16:13:45 -0700 Subject: [PATCH 1/2] Remove raw access to PluginInstances vector This commit modifies the PluginInstances class to remove direct access to the m_instances vector. Instead, we expose a new `ForEachEnabledPlugin` method that takes a callback to operate on each plugin. All external iteration over the instances is updated to use the new method. The motivation for the change is to allow modifying the way we store instances without having to change all the clients. This is a preliminary change to allow enabling/disabling of plugins in which case we want to iterate over only enabled plugins. We also considered using a custom iterator that wraps the vector iterator and can skip over disabled instances. That works, but the iterator code is a bit messy with all template and typedefs to make a compliant iterator. Instead we go with the `ForEach` approach which is easy to debug and understand. --- lldb/source/Core/PluginManager.cpp | 294 - 1 file changed, 164 insertions(+), 130 deletions(-) diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index 80c9465f9af72..f5c1e15f199ed 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -226,30 +226,26 @@ template class PluginInstances { } typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) { -if (Instance *instance = GetInstanceAtIndex(idx)) +if (const Instance *instance = GetInstanceAtIndex(idx)) return instance->create_callback; return nullptr; } llvm::StringRef GetDescriptionAtIndex(uint32_t idx) { -if (Instance *instance = GetInstanceAtIndex(idx)) +if (const Instance *instance = GetInstanceAtIndex(idx)) return instance->description; return ""; } llvm::StringRef GetNameAtIndex(uint32_t idx) { -if (Instance *instance = GetInstanceAtIndex(idx)) +if (const Instance *instance = GetInstanceAtIndex(idx)) return instance->name; return ""; } typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) { -if (name.empty()) - return nullptr; -for (auto &instance : m_instances) { - if (name == instance.name) -return instance.create_callback; -} +if (const Instance *instance = GetInstanceForName(name)) + return instance->create_callback; return nullptr; } @@ -260,13 +256,44 @@ template class PluginInstances { } } - const std::vector &GetInstances() const { return m_instances; } - std::vector &GetInstances() { return m_instances; } + const Instance *GetInstanceAtIndex(uint32_t idx) { +uint32_t count = 0; - Instance *GetInstanceAtIndex(uint32_t idx) { -if (idx < m_instances.size()) - return &m_instances[idx]; -return nullptr; +const Instance *instance = FindEnabledInstance( +[&](const Instance &instance) { return count++ == idx; }); +return instance; + } + + const Instance *GetInstanceForName(llvm::StringRef name) { +if (name.empty()) + return nullptr; + +const Instance *instance = FindEnabledInstance( +[&](const Instance &instance) { return instance.name == name; }); + +return instance; + } + + // Iterate over all enabled plugins, calling the callback for each one. + void ForEachEnabledPlugin( + std::function callback) const { +for (auto &instance : m_instances) { + if (callback(instance) == IterationAction::Stop) +return; +} + } + + const Instance * + FindEnabledInstance(std::function predicate) const { +const Instance *found = nullptr; +ForEachEnabledPlugin([&](const Instance &instance) { + if (predicate(instance)) { +found = &instance; +return IterationAction::Stop; + } + return IterationAction::Continue; +}); +return found; } private: @@ -571,17 +598,15 @@ PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { LanguageRuntimeGetCommandObject PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { - const auto &instances = GetLanguageRuntimeInstances().GetInstances(); - if (idx < instances.size()) -return instances[idx].command_callback; + if (auto instance = GetLanguageRuntimeInstances().GetInstanceAtIndex(idx)) +return instance->command_callback; return nullptr; } LanguageRuntimeGetExceptionPrecondition PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { - const auto &instances = GetLanguageRuntimeInstances().GetInstances(); - if (idx < instances.size()) -return instances[idx].precondition_callback; + if (auto instance = GetLanguageRuntimeInstances().GetInstanceAtIndex(idx)) +return instance->precondition_callback; return nullptr; } @@ -
[Lldb-commits] [lldb] [lldb-dap] Adding a DAPError for showing users error messages. (PR #132255)
https://github.com/Jlalond approved this pull request. https://github.com/llvm/llvm-project/pull/132255 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Support ordered patterns in lldbtest.expect (PR #131475)
kastiglione wrote: @luporl https://github.com/llvm/llvm-project/pull/131890 https://github.com/llvm/llvm-project/pull/131475 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][Target] RunThreadPlan to save/restore the ExecutionContext's frame if one exists (PR #134097)
Michael137 wrote: > LGTM. Even the variable name made it clear this wasn't being set correctly. > We just usually do evaluate expressions in the selected frame context. This > should cause a failure in the current code if you call > SBThread.SetSelectedFrame for frame A and then get the SBFrame for another > frame and call EvaluateExpression on it? Maybe that would allow you to write > a test that fails more directly? We still need the function pointer stuff (and the ptrauth static initializer code) because that's the only case where we `RunThreadPlan` as part of parsing (before JIT execution) https://github.com/llvm/llvm-project/pull/134097 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Fix tests on Windows (PR #131600)
https://github.com/AlexK0 updated https://github.com/llvm/llvm-project/pull/131600 >From 2186582c6113033a7adf2c3ac7fb1a6fcde5726c Mon Sep 17 00:00:00 2001 From: Aleksandr Korepanov Date: Mon, 17 Mar 2025 11:03:57 +0100 Subject: [PATCH 1/2] [LLDB][tests] Transfer APPDATA env for running tests On Windows without APPDATA environment variable, the test framework cannot import the 'packaging' module. --- lldb/test/API/lit.cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/test/API/lit.cfg.py b/lldb/test/API/lit.cfg.py index 08cf11c8a68db..4336a89d57c5f 100644 --- a/lldb/test/API/lit.cfg.py +++ b/lldb/test/API/lit.cfg.py @@ -343,6 +343,6 @@ def delete_module_cache(path): # Transfer some environment variables into the tests on Windows build host. if platform.system() == "Windows": -for v in ["SystemDrive"]: +for v in ["SystemDrive", "APPDATA"]: if v in os.environ: config.environment[v] = os.environ[v] >From bf21cbc2ff6325367312f106af12dd50bfd9b48b Mon Sep 17 00:00:00 2001 From: Aleksandr Korepanov Date: Mon, 17 Mar 2025 11:06:46 +0100 Subject: [PATCH 2/2] [LLDB][tests] Fix tests for Windows - On Windows there is different error message on setting watchpoint. - Use 'test -d' to check for a directory instead of 'file' because Windows does not have the 'file' utility. --- .../watchpoint/watchlocation/TestTargetWatchAddress.py| 8 +++- lldb/test/Shell/Diagnostics/TestDump.test | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py b/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py index 7a0e42a4fc278..bb024e27fbda1 100644 --- a/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py +++ b/lldb/test/API/python_api/watchpoint/watchlocation/TestTargetWatchAddress.py @@ -201,8 +201,6 @@ def test_watch_address_with_invalid_watch_size(self): value.GetValueAsUnsigned(), 365, wp_opts, error ) self.assertFalse(watchpoint) -self.expect( -error.GetCString(), -exe=False, -substrs=["Setting one of the watchpoint resources failed"], -) +# The message depends on whether the lldb-server implementation or the in-process implementation is used. +self.assertRegex(error.GetCString(), + "Can't enable watchpoint|Setting one of the watchpoint resources failed") diff --git a/lldb/test/Shell/Diagnostics/TestDump.test b/lldb/test/Shell/Diagnostics/TestDump.test index 2adde6b86d35a..cf10991d51c35 100644 --- a/lldb/test/Shell/Diagnostics/TestDump.test +++ b/lldb/test/Shell/Diagnostics/TestDump.test @@ -5,11 +5,11 @@ # RUN: rm -rf %t.existing # RUN: mkdir -p %t.existing # RUN: %lldb -o 'diagnostics dump -d %t.existing' -# RUN: file %t.existing | FileCheck %s +# RUN: test -d %t.existing # Dump to a non-existing directory. # RUN: rm -rf %t.nonexisting # RUN: %lldb -o 'diagnostics dump -d %t.nonexisting' -# RUN: file %t.nonexisting | FileCheck %s +# RUN: test -d %t.nonexisting # CHECK: directory ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Use correct path for lldb-server executable (PR #131519)
llvmbot wrote: /pull-request llvm/llvm-project#134072 https://github.com/llvm/llvm-project/pull/131519 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] Require wide char support in unicode test (PR #131951)
https://github.com/dmpots closed https://github.com/llvm/llvm-project/pull/131951 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] bc6cd82 - [lldb-dap] Creating a common configuration structure for launch and attach requests. (#133960)
Author: John Harrison Date: 2025-04-03T09:45:00-07:00 New Revision: bc6cd825ecea94f015c590c877a1401d3a4a46b8 URL: https://github.com/llvm/llvm-project/commit/bc6cd825ecea94f015c590c877a1401d3a4a46b8 DIFF: https://github.com/llvm/llvm-project/commit/bc6cd825ecea94f015c590c877a1401d3a4a46b8.diff LOG: [lldb-dap] Creating a common configuration structure for launch and attach requests. (#133960) This moves all the common settings of the launch and attach operations into the `lldb_dap::protocol::Configuration`. These common settings can be in both `launch` and `attach` requests and allows us to isolate the DAP configuration operations into a single common location. This is split out from #133624. Added: Modified: lldb/tools/lldb-dap/DAP.cpp lldb/tools/lldb-dap/DAP.h lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp lldb/tools/lldb-dap/Handler/CompletionsHandler.cpp lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp lldb/tools/lldb-dap/Handler/LaunchRequestHandler.cpp lldb/tools/lldb-dap/Handler/RequestHandler.cpp lldb/tools/lldb-dap/Handler/SetVariableRequestHandler.cpp lldb/tools/lldb-dap/Handler/StackTraceRequestHandler.cpp lldb/tools/lldb-dap/Handler/VariablesRequestHandler.cpp lldb/tools/lldb-dap/JSONUtils.cpp lldb/tools/lldb-dap/JSONUtils.h lldb/tools/lldb-dap/Protocol/ProtocolRequests.h lldb/tools/lldb-dap/SourceBreakpoint.cpp lldb/tools/lldb-dap/lldb-dap.cpp Removed: diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 8951384212f11..9361ba968e9c2 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -69,20 +69,20 @@ const char DEV_NULL[] = "/dev/null"; namespace lldb_dap { -DAP::DAP(llvm::StringRef path, Log *log, const ReplMode default_repl_mode, +llvm::StringRef DAP::debug_adapter_path = ""; + +DAP::DAP(Log *log, const ReplMode default_repl_mode, std::vector pre_init_commands, Transport &transport) -: debug_adapter_path(path), log(log), transport(transport), - broadcaster("lldb-dap"), exception_breakpoints(), - pre_init_commands(std::move(pre_init_commands)), - focus_tid(LLDB_INVALID_THREAD_ID), stop_at_entry(false), is_attach(false), - enable_auto_variable_summaries(false), - enable_synthetic_child_debugging(false), - display_extended_backtrace(false), +: log(log), transport(transport), broadcaster("lldb-dap"), + exception_breakpoints(), focus_tid(LLDB_INVALID_THREAD_ID), + stop_at_entry(false), is_attach(false), restarting_process_id(LLDB_INVALID_PROCESS_ID), configuration_done_sent(false), waiting_for_run_in_terminal(false), progress_event_reporter( [&](const ProgressEvent &event) { SendJSON(event.ToJSON()); }), - reverse_request_seq(0), repl_mode(default_repl_mode) {} + reverse_request_seq(0), repl_mode(default_repl_mode) { + configuration.preInitCommands = std::move(pre_init_commands); +} DAP::~DAP() = default; @@ -505,8 +505,9 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression, bool partial_expression) { // Check for the escape hatch prefix. if (!expression.empty() && - llvm::StringRef(expression).starts_with(command_escape_prefix)) { -expression = expression.substr(command_escape_prefix.size()); + llvm::StringRef(expression) + .starts_with(configuration.commandEscapePrefix)) { +expression = expression.substr(configuration.commandEscapePrefix.size()); return ReplMode::Command; } @@ -546,7 +547,7 @@ ReplMode DAP::DetectReplMode(lldb::SBFrame frame, std::string &expression, << "Warning: Expression '" << term << "' is both an LLDB command and variable. It will be evaluated as " "a variable. To evaluate the expression as an LLDB command, use '" - << command_escape_prefix << "' as a prefix.\n"; + << configuration.commandEscapePrefix << "' as a prefix.\n"; } // Variables take preference to commands in auto, since commands can always @@ -593,36 +594,38 @@ DAP::RunLaunchCommands(llvm::ArrayRef launch_commands) { } llvm::Error DAP::RunInitCommands() { - if (!RunLLDBCommands("Running initCommands:", init_commands)) + if (!RunLLDBCommands("Running initCommands:", configuration.initCommands)) return createRunLLDBCommandsErrorMessage("initCommands"); return llvm::Error::success(); } llvm::Error DAP::RunPreInitCommands() { - if (!RunLLDBCommands("Running preInitCommands:", pre_init_commands)) + if (!RunLLDBCommands("Running preInitCommands:", + configuration.preInitCommands)) return createRunLLDBCommandsErrorMessage("preInitCommands"); return llvm::Error::success(); } llvm::Error DAP::RunPreRunCommands() { - if (!RunLLDBCommands("Running preRunCommands:", pre_ru
[Lldb-commits] [lldb] [lldb] Include the version in the lldbassert error message (PR #133740)
https://github.com/JDevlieghere edited https://github.com/llvm/llvm-project/pull/133740 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Minor AIX specific changes (PR #132718)
https://github.com/labath approved this pull request. https://github.com/llvm/llvm-project/pull/132718 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] 50949eb - [lldb] Expose the Target API mutex through the SB API (#133295)
Author: Jonas Devlieghere Date: 2025-03-31T08:19:41-07:00 New Revision: 50949ebf523cc09cc911a12691fb79b6ac97102a URL: https://github.com/llvm/llvm-project/commit/50949ebf523cc09cc911a12691fb79b6ac97102a DIFF: https://github.com/llvm/llvm-project/commit/50949ebf523cc09cc911a12691fb79b6ac97102a.diff LOG: [lldb] Expose the Target API mutex through the SB API (#133295) Expose u target API mutex through the SB API. This is motivated by lldb-dap, which is built on top of the SB API and needs a way to execute a series of SB API calls in an atomic manner (see #131242). We can solve this problem by either introducing an additional layer of locking at the DAP level or by exposing the existing locking at the SB API level. This patch implements the second approach. This was discussed in an RFC on Discourse [0]. The original implementation exposed a move-only lock rather than a mutex [1] which doesn't work well with SWIG 4.0 [2]. This implement the alternative solution of exposing the mutex rather than the lock. The SBMutex conforms to the BasicLockable requirement [3] (which is why the methods are called `lock` and `unlock` rather than Lock and Unlock) so it can be used as `std::lock_guard` and `std::unique_lock`. [0]: https://discourse.llvm.org/t/rfc-exposing-the-target-api-lock-through-the-sb-api/85215/6 [1]: https://github.com/llvm/llvm-project/pull/131404 [2]: https://discourse.llvm.org/t/rfc-bumping-the-minimum-swig-version-to-4-1-0/85377/9 [3]: https://en.cppreference.com/w/cpp/named_req/BasicLockable Added: lldb/bindings/interface/SBMutexExtensions.i lldb/include/lldb/API/SBMutex.h lldb/source/API/SBMutex.cpp lldb/unittests/API/SBMutexTest.cpp Modified: lldb/bindings/interfaces.swig lldb/include/lldb/API/LLDB.h lldb/include/lldb/API/SBDefines.h lldb/include/lldb/API/SBTarget.h lldb/source/API/CMakeLists.txt lldb/source/API/SBTarget.cpp lldb/test/API/python_api/target/TestTargetAPI.py lldb/unittests/API/CMakeLists.txt Removed: diff --git a/lldb/bindings/interface/SBMutexExtensions.i b/lldb/bindings/interface/SBMutexExtensions.i new file mode 100644 index 0..32d3fee468697 --- /dev/null +++ b/lldb/bindings/interface/SBMutexExtensions.i @@ -0,0 +1,12 @@ +%extend lldb::SBMutex { +#ifdef SWIGPYTHON +%pythoncode %{ +def __enter__(self): +self.lock() +return self + +def __exit__(self, exc_type, exc_value, traceback): +self.unlock() +%} +#endif +} diff --git a/lldb/bindings/interfaces.swig b/lldb/bindings/interfaces.swig index 6da56e4e0fa52..e71ed136f20e6 100644 --- a/lldb/bindings/interfaces.swig +++ b/lldb/bindings/interfaces.swig @@ -51,6 +51,7 @@ %include "./interface/SBMemoryRegionInfoListDocstrings.i" %include "./interface/SBModuleDocstrings.i" %include "./interface/SBModuleSpecDocstrings.i" +%include "./interface/SBMutexExtensions.i" %include "./interface/SBPlatformDocstrings.i" %include "./interface/SBProcessDocstrings.i" %include "./interface/SBProcessInfoDocstrings.i" @@ -121,8 +122,8 @@ %include "lldb/API/SBHostOS.h" %include "lldb/API/SBInstruction.h" %include "lldb/API/SBInstructionList.h" -%include "lldb/API/SBLanguages.h" %include "lldb/API/SBLanguageRuntime.h" +%include "lldb/API/SBLanguages.h" %include "lldb/API/SBLaunchInfo.h" %include "lldb/API/SBLineEntry.h" %include "lldb/API/SBListener.h" @@ -130,6 +131,7 @@ %include "lldb/API/SBMemoryRegionInfoList.h" %include "lldb/API/SBModule.h" %include "lldb/API/SBModuleSpec.h" +%include "lldb/API/SBMutex.h" %include "lldb/API/SBPlatform.h" %include "lldb/API/SBProcess.h" %include "lldb/API/SBProcessInfo.h" diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index 126fcef31b416..6485f35302a1c 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -50,6 +50,7 @@ #include "lldb/API/SBMemoryRegionInfoList.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" +#include "lldb/API/SBMutex.h" #include "lldb/API/SBPlatform.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBProcessInfo.h" diff --git a/lldb/include/lldb/API/SBDefines.h b/lldb/include/lldb/API/SBDefines.h index ed5a80da117a5..85f6bbeea5bf9 100644 --- a/lldb/include/lldb/API/SBDefines.h +++ b/lldb/include/lldb/API/SBDefines.h @@ -89,6 +89,7 @@ class LLDB_API SBMemoryRegionInfoList; class LLDB_API SBModule; class LLDB_API SBModuleSpec; class LLDB_API SBModuleSpecList; +class LLDB_API SBMutex; class LLDB_API SBPlatform; class LLDB_API SBPlatformConnectOptions; class LLDB_API SBPlatformShellCommand; diff --git a/lldb/include/lldb/API/SBMutex.h b/lldb/include/lldb/API/SBMutex.h new file mode 100644 index 0..717d5f86cbc1c --- /dev/null +++ b/lldb/include/lldb/API/SBMutex.h @@ -0,0 +1,45 @@ +//===-- SBMutex.h -===//
[Lldb-commits] [lldb] [lldb] Move two methods from Platfrom -> Host (NFC) (PR #132119)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) Changes This moves two functions from Platform to Host: 1. GetCurrentXcodeToolchainDirectory 2. GetCurrentCommandLineToolsDirectory. These two functions caused a layering violation in the Swift fork, which added a dependency from lldbHost to lldbPlatform. As show by this PR, there's no need for these two functions to live in Platform, and we already have similar functions in Host. We have various layering violations but this one is particularly bad, because lldb-dap started depending on lldbHost. On the Swift fork, this library was depending on lldbPlatform which pulled in various Swift files, which libLLDB needs, but lldb-dap itself does not. We were missing RPATHs to resume them, so in the current nightly, lldb-dap crashes because the dynamic loader can't find the missing Swift libs. rdar://146537366 --- Full diff: https://github.com/llvm/llvm-project/pull/132119.diff 7 Files Affected: - (modified) lldb/include/lldb/Host/HostInfoBase.h (+2) - (modified) lldb/include/lldb/Host/macosx/HostInfoMacOSX.h (+5) - (modified) lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm (+27) - (modified) lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (-27) - (modified) lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h (-10) - (modified) lldb/unittests/Host/HostInfoTest.cpp (+23) - (modified) lldb/unittests/Platform/PlatformDarwinTest.cpp (-22) ``diff diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h index 705aad559f3b7..b6a95fffb2db2 100644 --- a/lldb/include/lldb/Host/HostInfoBase.h +++ b/lldb/include/lldb/Host/HostInfoBase.h @@ -126,6 +126,8 @@ class HostInfoBase { static FileSpec GetXcodeContentsDirectory() { return {}; } static FileSpec GetXcodeDeveloperDirectory() { return {}; } + static FileSpec GetCurrentXcodeToolchainDirectory() { return {}; } + static FileSpec GetCurrentCommandLineToolsDirectory() { return {}; } struct SDKOptions { std::optional XcodeSDKSelection; diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h index 9034c80fdefa4..d048418856604 100644 --- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -30,6 +30,8 @@ class HostInfoMacOSX : public HostInfoPosix { static FileSpec GetProgramFileSpec(); static FileSpec GetXcodeContentsDirectory(); static FileSpec GetXcodeDeveloperDirectory(); + static FileSpec GetCurrentXcodeToolchainDirectory(); + static FileSpec GetCurrentCommandLineToolsDirectory(); /// Query xcrun to find an Xcode SDK directory. /// @@ -50,6 +52,9 @@ class HostInfoMacOSX : public HostInfoPosix { static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputeSystemPluginsDirectory(FileSpec &file_spec); static bool ComputeUserPluginsDirectory(FileSpec &file_spec); + + static std::string FindComponentInPath(llvm::StringRef path, + llvm::StringRef component); }; } diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm index 6e924fdc684cf..61f94190c956c 100644 --- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm +++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm @@ -393,6 +393,33 @@ static bool ResolveAndVerifyCandidateSupportDir(FileSpec &path) { return g_developer_directory; } +std::string HostInfoMacOSX::FindComponentInPath(llvm::StringRef path, +llvm::StringRef component) { + auto begin = llvm::sys::path::begin(path); + auto end = llvm::sys::path::end(path); + for (auto it = begin; it != end; ++it) { +if (it->contains(component)) { + llvm::SmallString<128> buffer; + llvm::sys::path::append(buffer, begin, ++it, + llvm::sys::path::Style::posix); + return buffer.str().str(); +} + } + return {}; +} + +FileSpec HostInfoMacOSX::GetCurrentXcodeToolchainDirectory() { + if (FileSpec fspec = HostInfo::GetShlibDir()) +return FileSpec(FindComponentInPath(fspec.GetPath(), ".xctoolchain")); + return {}; +} + +FileSpec HostInfoMacOSX::GetCurrentCommandLineToolsDirectory() { + if (FileSpec fspec = HostInfo::GetShlibDir()) +return FileSpec(FindComponentInPath(fspec.GetPath(), "CommandLineTools")); + return {}; +} + static llvm::Expected xcrun(const std::string &sdk, llvm::ArrayRef arguments, llvm::StringRef developer_dir = "") { diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp index ee8e256748cea..3c3a0aa992d9c 100644 --- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -1337,33 +1337,6 @@ lldb_private::Status PlatformDarwin::FindBundleBinaryInExecSearchPaths( return Status
[Lldb-commits] [lldb] aa889ed - [lldb] Fix statusline terminal resizing
Author: Jonas Devlieghere Date: 2025-03-31T23:53:35-07:00 New Revision: aa889ed129ff26d9341c50a9eaba4db728ca6212 URL: https://github.com/llvm/llvm-project/commit/aa889ed129ff26d9341c50a9eaba4db728ca6212 DIFF: https://github.com/llvm/llvm-project/commit/aa889ed129ff26d9341c50a9eaba4db728ca6212.diff LOG: [lldb] Fix statusline terminal resizing Simplify and fix the logic to clear the old statusline when the terminal window dimensions have changed. I accidentally broke the terminal resizing behavior when addressing code review feedback. I'd really like to figure out a way to test this. PExpect isn't a good fit for this, because I really need to check the result, rather than the control characters, as the latter doesn't tell me whether any part of the old statusline is still visible. Added: Modified: lldb/include/lldb/Core/Statusline.h lldb/source/Core/Statusline.cpp Removed: diff --git a/lldb/include/lldb/Core/Statusline.h b/lldb/include/lldb/Core/Statusline.h index c1449f0f69081..521b9f2526f6b 100644 --- a/lldb/include/lldb/Core/Statusline.h +++ b/lldb/include/lldb/Core/Statusline.h @@ -10,8 +10,6 @@ #define LLDB_CORE_STATUSLINE_H #include "lldb/lldb-forward.h" -#include "llvm/ADT/StringRef.h" -#include #include #include @@ -34,10 +32,6 @@ class Statusline { /// Inform the statusline that the terminal dimensions have changed. void TerminalSizeChanged(); -protected: - /// Pad and trim the given string to fit to the given width. - static std::string TrimAndPad(std::string str, size_t width); - private: /// Draw the statusline with the given text. void Draw(std::string msg); @@ -46,20 +40,15 @@ class Statusline { void UpdateTerminalProperties(); enum ScrollWindowMode { -ScrollWindowExtend, -ScrollWindowShrink, +EnableStatusline, +DisableStatusline, }; /// Set the scroll window for the given mode. void UpdateScrollWindow(ScrollWindowMode mode); - /// Clear the statusline (without redrawing the background). - void Reset(); - Debugger &m_debugger; std::string m_last_str; - - volatile std::sig_atomic_t m_terminal_size_has_changed = 1; uint64_t m_terminal_width = 0; uint64_t m_terminal_height = 0; }; diff --git a/lldb/source/Core/Statusline.cpp b/lldb/source/Core/Statusline.cpp index c01388eb7e7b5..c18fbb6c5561e 100644 --- a/lldb/source/Core/Statusline.cpp +++ b/lldb/source/Core/Statusline.cpp @@ -23,7 +23,8 @@ #define ANSI_SAVE_CURSOR ESCAPE "7" #define ANSI_RESTORE_CURSOR ESCAPE "8" #define ANSI_CLEAR_BELOW ESCAPE "[J" -#define ANSI_CLEAR_LINE "\r\x1B[2K" +#define ANSI_CURSOR_DOWN ESCAPE "[B" +#define ANSI_CLEAR_LINE ESCAPE "[2K" #define ANSI_SET_SCROLL_ROWS ESCAPE "[0;%ur" #define ANSI_TO_START_OF_ROW ESCAPE "[%u;0f" #define ANSI_UP_ROWS ESCAPE "[%dA" @@ -31,12 +32,16 @@ using namespace lldb; using namespace lldb_private; -Statusline::Statusline(Debugger &debugger) : m_debugger(debugger) { Enable(); } +Statusline::Statusline(Debugger &debugger) +: m_debugger(debugger), m_terminal_width(m_debugger.GetTerminalWidth()), + m_terminal_height(m_debugger.GetTerminalHeight()) { + Enable(); +} Statusline::~Statusline() { Disable(); } void Statusline::TerminalSizeChanged() { - m_terminal_size_has_changed = 1; + UpdateTerminalProperties(); // This definitely isn't signal safe, but the best we can do, until we // have proper signal-catching thread. @@ -44,20 +49,16 @@ void Statusline::TerminalSizeChanged() { } void Statusline::Enable() { - UpdateTerminalProperties(); - // Reduce the scroll window to make space for the status bar below. - UpdateScrollWindow(ScrollWindowShrink); + UpdateScrollWindow(EnableStatusline); // Draw the statusline. - Redraw(); + Redraw(/*update=*/true); } void Statusline::Disable() { - UpdateTerminalProperties(); - // Extend the scroll window to cover the status bar. - UpdateScrollWindow(ScrollWindowExtend); + UpdateScrollWindow(DisableStatusline); } void Statusline::Draw(std::string str) { @@ -65,8 +66,6 @@ void Statusline::Draw(std::string str) { if (!stream_sp) return; - UpdateTerminalProperties(); - m_last_str = str; str = ansi::TrimAndPad(str, m_terminal_width); @@ -80,58 +79,37 @@ void Statusline::Draw(std::string str) { locked_stream << ANSI_RESTORE_CURSOR; } -void Statusline::Reset() { - lldb::LockableStreamFileSP stream_sp = m_debugger.GetOutputStreamSP(); - if (!stream_sp) -return; - - LockedStreamFile locked_stream = stream_sp->Lock(); - locked_stream << ANSI_SAVE_CURSOR; - locked_stream.Printf(ANSI_TO_START_OF_ROW, - static_cast(m_terminal_height)); - locked_stream << ANSI_CLEAR_LINE; - locked_stream << ANSI_RESTORE_CURSOR; -} - void Statusline::UpdateTerminalProperties() { - if (m_terminal_size_has_changed == 0) -return; - - // Clear the previous statusline using
[Lldb-commits] [lldb] [lldb] Remove UnwindPlan::Row shared_ptrs, lite (PR #134081)
labath wrote: > LGTM. I got kind of excited by the value semantics, but I don't know how many > copies we're talking about and this is an established way to guarantee > pointer stability. Yeah, this definitely feels less satisfying. It also feels a bit path-dependent, as I don't think we'd fret over this if Rows were values from the beginning. So, I tried to make a small benchmark, and according to the results, copying a Row object with three register values (which is one more than what I'd expect for a typical first/last row of an unwind plan) takes about 50 *nano*seconds. Copying a row with 100 registers (which is like more that most architectures have) takes ~three *micro*seconds. With that in mind, maybe we do want to go ahead with https://github.com/llvm/llvm-project/commit/d55a1ba1a9f4d5201eb578e247a077c1484b251c ? > LGTM. I'm not sure if it's feasible, but perhaps x86AssemblyInspectionEngine > could store an Index to the Row instead? Then you wouldn't need pointers or > worry about their stability. UnwindPlan would just need to hand back some > kind of row pointer/reference on demand and those should not be stored. That doesn't quite work here because the code in question is inserting new rows into the middle of the unwind plan, so the index changes as well (for the last row, at least). I mean, I suppose you could try and keep the index up to date, but that's going to be very fragile. https://github.com/llvm/llvm-project/pull/134081 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Refactoring lldb-dap 'launch' request to use typed RequestHandler<>. (PR #133624)
https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/133624 >From 3240fe49515e5f59c5b9ff9c02423b77504d8a43 Mon Sep 17 00:00:00 2001 From: John Harrison Date: Fri, 28 Mar 2025 14:02:53 -0700 Subject: [PATCH 1/2] [lldb-dap] Refactoring lldb-dap 'launch' request to use typed RequestHandler<>. This converts a number of json::Value's into well defined types that are used throughout lldb-dap and updates the 'launch' command to use the new well defined types. --- .../test/tools/lldb-dap/dap_server.py | 3 +- .../test/tools/lldb-dap/lldbdap_testcase.py | 2 +- .../tools/lldb-dap/launch/TestDAP_launch.py | 6 +- .../restart/TestDAP_restart_runInTerminal.py | 4 +- .../runInTerminal/TestDAP_runInTerminal.py| 16 +- lldb/tools/lldb-dap/DAP.cpp | 82 +--- lldb/tools/lldb-dap/DAP.h | 44 +++-- .../lldb-dap/Handler/AttachRequestHandler.cpp | 33 ++-- .../lldb-dap/Handler/CompletionsHandler.cpp | 7 +- .../Handler/EvaluateRequestHandler.cpp| 3 +- .../lldb-dap/Handler/LaunchRequestHandler.cpp | 118 +++- .../tools/lldb-dap/Handler/RequestHandler.cpp | 96 +- lldb/tools/lldb-dap/Handler/RequestHandler.h | 19 +- .../Handler/RestartRequestHandler.cpp | 54 -- .../Handler/SetVariableRequestHandler.cpp | 3 +- .../Handler/StackTraceRequestHandler.cpp | 2 +- .../Handler/VariablesRequestHandler.cpp | 20 +- lldb/tools/lldb-dap/JSONUtils.cpp | 48 ++--- lldb/tools/lldb-dap/JSONUtils.h | 11 +- .../lldb-dap/Protocol/ProtocolRequests.cpp| 175 +- .../lldb-dap/Protocol/ProtocolRequests.h | 150 +++ lldb/tools/lldb-dap/SourceBreakpoint.cpp | 6 +- 22 files changed, 616 insertions(+), 286 deletions(-) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 01ef4b68f2653..6e13fcddcc933 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -862,7 +862,8 @@ def request_launch( args_dict["enableAutoVariableSummaries"] = enableAutoVariableSummaries args_dict["enableSyntheticChildDebugging"] = enableSyntheticChildDebugging args_dict["displayExtendedBacktrace"] = displayExtendedBacktrace -args_dict["commandEscapePrefix"] = commandEscapePrefix +if commandEscapePrefix: +args_dict["commandEscapePrefix"] = commandEscapePrefix command_dict = {"command": "launch", "type": "request", "arguments": args_dict} response = self.send_recv(command_dict) diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py index 70b04b051e0ec..9ab8a905a79dd 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py @@ -443,7 +443,7 @@ def cleanup(): if not (response and response["success"]): self.assertTrue( -response["success"], "launch failed (%s)" % (response["message"]) +response["success"], "launch failed (%s)" % (response["body"]["error"]["format"]) ) return response diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 64c99019a1c9b..c6a3e9cc879a4 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -41,7 +41,9 @@ def test_termination(self): self.dap_server.request_disconnect() # Wait until the underlying lldb-dap process dies. - self.dap_server.process.wait(timeout=lldbdap_testcase.DAPTestCaseBase.timeoutval) +self.dap_server.process.wait( +timeout=lldbdap_testcase.DAPTestCaseBase.timeoutval +) # Check the return code self.assertEqual(self.dap_server.process.poll(), 0) @@ -459,7 +461,7 @@ def test_failing_launch_commands(self): self.assertFalse(response["success"]) self.assertRegex( -response["message"], +response["body"]["error"]["format"], r"Failed to run launch commands\. See the Debug Console for more details", ) diff --git a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py index 5a9938c25c2c8..a94c9860c1508 100644 --- a/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py +++ b/lldb/test/API/tools/lldb-dap/restart/TestDAP_restart_runInTerminal.py @@ -21,7 +21,7 @@ def isTestSupported(self): return False @skipIfWindows -@skipIf(archs=["arm"]) #
[Lldb-commits] [lldb] 6526cda - [lldb-dap] Migrating DAP 'initialize' to new typed RequestHandler. (#133007)
Author: John Harrison Date: 2025-03-28T09:13:10-07:00 New Revision: 6526cda5d865d55b1db5aa0faffb29448e5c6a23 URL: https://github.com/llvm/llvm-project/commit/6526cda5d865d55b1db5aa0faffb29448e5c6a23 DIFF: https://github.com/llvm/llvm-project/commit/6526cda5d865d55b1db5aa0faffb29448e5c6a23.diff LOG: [lldb-dap] Migrating DAP 'initialize' to new typed RequestHandler. (#133007) This adds new types and helpers to support the 'initialize' request with the new typed RequestHandler. While working on this I found there were a few cases where we incorrectly treated initialize arguments as capabilities. The new `lldb_dap::protocol::InitializeRequestArguments` and `lldb_dap::protocol::Capabilities` uncovered the inconsistencies. - Co-authored-by: Jonas Devlieghere Added: Modified: lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py lldb/tools/lldb-dap/DAP.cpp lldb/tools/lldb-dap/DAP.h lldb/tools/lldb-dap/Handler/InitializeRequestHandler.cpp lldb/tools/lldb-dap/Handler/RequestHandler.cpp lldb/tools/lldb-dap/Handler/RequestHandler.h lldb/tools/lldb-dap/JSONUtils.cpp lldb/tools/lldb-dap/JSONUtils.h lldb/tools/lldb-dap/Protocol/ProtocolBase.cpp lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp lldb/tools/lldb-dap/Protocol/ProtocolRequests.h lldb/tools/lldb-dap/Protocol/ProtocolTypes.cpp lldb/tools/lldb-dap/Protocol/ProtocolTypes.h Removed: diff --git a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py index 359ac718138b2..01ef4b68f2653 100644 --- a/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py +++ b/lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py @@ -776,7 +776,8 @@ def request_initialize(self, sourceInitFile): "supportsVariablePaging": True, "supportsVariableType": True, "supportsStartDebuggingRequest": True, -"sourceInitFile": sourceInitFile, +"supportsProgressReporting": True, +"$__lldb_sourceInitFile": sourceInitFile, }, } response = self.send_recv(command_dict) @@ -1261,7 +1262,7 @@ def launch(cls, /, executable, env=None, log_file=None, connection=None): expected_prefix = "Listening for: " out = process.stdout.readline().decode() if not out.startswith(expected_prefix): -self.process.kill() +process.kill() raise ValueError( "lldb-dap failed to print listening address, expected '{}', got '{}'".format( expected_prefix, out diff --git a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py index 0c92e5bff07c6..64c99019a1c9b 100644 --- a/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py +++ b/lldb/test/API/tools/lldb-dap/launch/TestDAP_launch.py @@ -524,8 +524,7 @@ def test_version(self): # The first line is the prompt line like "(lldb) version", so we skip it. version_eval_output_without_prompt_line = version_eval_output.splitlines()[1:] -lldb_json = self.dap_server.get_initialize_value("__lldb") -version_string = lldb_json["version"] +version_string = self.dap_server.get_initialize_value("$__lldb_version") self.assertEqual( version_eval_output_without_prompt_line, version_string.splitlines(), diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp index 65de0488729e5..23f0400c8bd4d 100644 --- a/lldb/tools/lldb-dap/DAP.cpp +++ b/lldb/tools/lldb-dap/DAP.cpp @@ -14,6 +14,7 @@ #include "LLDBUtils.h" #include "OutputRedirector.h" #include "Protocol/ProtocolBase.h" +#include "Protocol/ProtocolTypes.h" #include "Transport.h" #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBCommandInterpreter.h" @@ -1144,32 +1145,41 @@ lldb::SBValue Variables::FindVariable(uint64_t variablesReference, return variable; } -llvm::StringMap DAP::GetCapabilities() { - llvm::StringMap capabilities; - - // Supported capabilities. - capabilities["supportTerminateDebuggee"] = true; - capabilities["supportsDataBreakpoints"] = true; - capabilities["supportsDelayedStackTraceLoading"] = true; - capabilities["supportsEvaluateForHovers"] = true; - capabilities["supportsExceptionOptions"] = true; - capabilities["supportsLogPoints"] = true; - capabilities["supportsProgressReporting"] = true; - capabilities["supportsSteppingGranularity"] = true; - capabilities["supportsValueFormattingOptions"] = true; - - // Unsupported capabilities. - capabilities["supportsGotoTargetsRequest"] = false; - capabilities["supportsLoadedSourcesRequest"] = false; - capabilities["supportsRestartFrame"] = fal
[Lldb-commits] [lldb] [lldb] Remove UnwindPlan::Row shared_ptrs (PR #132370)
labath wrote: Thanks for reverting this while I was gone. It looks like there's still some pointer persistence. I'll take a look at that a bit later... https://github.com/llvm/llvm-project/pull/132370 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] Revert "[lldb] Remove UnwindPlan::Row shared_ptrs (#132370)" (PR #133299)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Jordan Rupprecht (rupprecht) Changes This reverts commit d7cea2b18717f0cc31b7da4a03f772d89ee201db. It causes crashes in API tests. --- Full diff: https://github.com/llvm/llvm-project/pull/133299.diff 2 Files Affected: - (modified) lldb/include/lldb/Symbol/UnwindPlan.h (+22-5) - (modified) lldb/source/Symbol/UnwindPlan.cpp (+16-16) ``diff diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h index ddc54a9fdc8ae..db9aade93b6ba 100644 --- a/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -428,6 +428,8 @@ class UnwindPlan { bool m_unspecified_registers_are_undefined = false; }; // class Row + typedef std::shared_ptr RowSP; + UnwindPlan(lldb::RegisterKind reg_kind) : m_register_kind(reg_kind), m_return_addr_register(LLDB_INVALID_REGNUM), m_plan_is_sourced_from_compiler(eLazyBoolCalculate), @@ -435,10 +437,25 @@ class UnwindPlan { m_plan_is_for_signal_trap(eLazyBoolCalculate) {} // Performs a deep copy of the plan, including all the rows (expensive). - UnwindPlan(const UnwindPlan &rhs) = default; - UnwindPlan &operator=(const UnwindPlan &rhs) = default; - + UnwindPlan(const UnwindPlan &rhs) + : m_plan_valid_ranges(rhs.m_plan_valid_ranges), +m_register_kind(rhs.m_register_kind), +m_return_addr_register(rhs.m_return_addr_register), +m_source_name(rhs.m_source_name), +m_plan_is_sourced_from_compiler(rhs.m_plan_is_sourced_from_compiler), +m_plan_is_valid_at_all_instruction_locations( +rhs.m_plan_is_valid_at_all_instruction_locations), +m_plan_is_for_signal_trap(rhs.m_plan_is_for_signal_trap), +m_lsda_address(rhs.m_lsda_address), +m_personality_func_addr(rhs.m_personality_func_addr) { +m_row_list.reserve(rhs.m_row_list.size()); +for (const RowSP &row_sp : rhs.m_row_list) + m_row_list.emplace_back(new Row(*row_sp)); + } UnwindPlan(UnwindPlan &&rhs) = default; + UnwindPlan &operator=(const UnwindPlan &rhs) { +return *this = UnwindPlan(rhs); // NB: moving from a temporary (deep) copy + } UnwindPlan &operator=(UnwindPlan &&) = default; ~UnwindPlan() = default; @@ -469,7 +486,7 @@ class UnwindPlan { uint32_t GetInitialCFARegister() const { if (m_row_list.empty()) return LLDB_INVALID_REGNUM; -return m_row_list.front().GetCFAValue().GetRegisterNumber(); +return m_row_list.front()->GetCFAValue().GetRegisterNumber(); } // This UnwindPlan may not be valid at every address of the function span. @@ -552,7 +569,7 @@ class UnwindPlan { } private: - std::vector m_row_list; + std::vector m_row_list; std::vector m_plan_valid_ranges; lldb::RegisterKind m_register_kind; // The RegisterKind these register numbers // are in terms of - will need to be diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index 92daf29630ab6..48089cbdecd97 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -391,29 +391,29 @@ bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const { } void UnwindPlan::AppendRow(Row row) { - if (m_row_list.empty() || m_row_list.back().GetOffset() != row.GetOffset()) -m_row_list.push_back(std::move(row)); + if (m_row_list.empty() || m_row_list.back()->GetOffset() != row.GetOffset()) +m_row_list.push_back(std::make_shared(std::move(row))); else -m_row_list.back() = std::move(row); +*m_row_list.back() = std::move(row); } struct RowLess { - bool operator()(addr_t a, const UnwindPlan::Row &b) const { -return a < b.GetOffset(); + bool operator()(addr_t a, const UnwindPlan::RowSP &b) const { +return a < b->GetOffset(); } - bool operator()(const UnwindPlan::Row &a, addr_t b) const { -return a.GetOffset() < b; + bool operator()(const UnwindPlan::RowSP &a, addr_t b) const { +return a->GetOffset() < b; } }; void UnwindPlan::InsertRow(Row row, bool replace_existing) { auto it = llvm::lower_bound(m_row_list, row.GetOffset(), RowLess()); - if (it == m_row_list.end() || it->GetOffset() > row.GetOffset()) -m_row_list.insert(it, std::move(row)); + if (it == m_row_list.end() || it->get()->GetOffset() > row.GetOffset()) +m_row_list.insert(it, std::make_shared(std::move(row))); else { -assert(it->GetOffset() == row.GetOffset()); +assert(it->get()->GetOffset() == row.GetOffset()); if (replace_existing) - *it = std::move(row); + **it = std::move(row); } } @@ -424,7 +424,7 @@ const UnwindPlan::Row *UnwindPlan::GetRowForFunctionOffset(int offset) const { return nullptr; // upper_bound returns the row strictly greater than our desired offset, which // means that the row before it is a match. - return &*std::prev(it); + return std::prev(it)->get(); } bool UnwindPl
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
cmtice wrote: > > Okay, at this I don't think I have any more comments about functionality. > > The remaining comments are either stylistic (which should be > > self-explanatory) or about error handling (which I'm going to write about > > here). > > For the error handling, I missed the fact that your new implementation > > throws away the structured diagnostic info after using it to construct the > > error string. That kinda misses the point, which is to provide the rest of > > lldb with a structured representation of the error. It looks like the base > > DiagnosticError is abstract, so for that we need to create our own error > > subclass of that. I tried to sketch it out in the inline comments (by > > combining the existing `ExpressionError` class and your code), but this is > > only a rough sketch -- you'll certainly need to adjust it to make it work. > > You can tell whether you've succeded by looking at how the new "frame var" > > error messages are formatted. They should come out in the same was as in > > the snippet that [Jim > > posted](https://github.com/llvm/llvm-project/pull/120971#issuecomment-2722987750). > > The other set of suggested changes is about changing the error > > representation from Status to llvm::Error. We're basically already using > > the error object as if it was an llvm::Error, so I think we should just > > complete the transition and use it throughout the DIL. > > I think you've misunderstood the code? I don't just throw away the > DiagnosticDetail -- its formatted error message, which is what you've been > asking for, gets passed back into the Status error, which LLDB then prints > out. So the current implementation is giving the formatted error messages now > (without any of your further suggested changes): > > (lldb) v externGlobalVar error: externGlobalVar ˄ ╰─ error: use of undeclared > identifier 'externGlobalVar' (lldb) v 'cat + dog' error: cat + dog ˄ ╰─ > error: use of undeclared identifier 'cat' (lldb) v globalVar%%32 error: > globalVar%%32 ˄ ╰─ error: Unexpected token: <'%' (percent)> ``` (lldb) v externGlobalVar error: externGlobalVar ˄ ╰─ error: use of undeclared identifier 'externGlobalVar' (lldb) v 'cat + dog' error: cat + dog ˄ ╰─ error: use of undeclared identifier 'cat' (lldb) v globalVar^32 (int) result = -559038769 (lldb) v globalVar%%32 error: globalVar%%32 ˄ ╰─ error: Unexpected token: <'%' (percent)> (lldb) ``` https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb-dap] Add progress events to the packet list (PR #134157)
https://github.com/Jlalond approved this pull request. Much improved! I should've noticed this in my first patch but great fix for the flakiness https://github.com/llvm/llvm-project/pull/134157 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add DIL code for handling plain variable names. (PR #120971)
@@ -0,0 +1,258 @@ +//===-- DILParser.cpp -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This implements the recursive descent parser for the Data Inspection +// Language (DIL), and its helper functions, which will eventually underlie the +// 'frame variable' command. The language that this parser recognizes is +// described in lldb/docs/dil-expr-lang.ebnf +// +//===--===// + +#include "lldb/ValueObject/DILParser.h" +#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Utility/DiagnosticsRendering.h" +#include "lldb/ValueObject/DILAST.h" +#include "lldb/ValueObject/DILEval.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatAdapters.h" +#include +#include +#include +#include +#include + +namespace lldb_private::dil { + +DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr, + const std::string &message, uint32_t loc, + uint16_t err_len) +: ErrorInfo(make_error_code(std::errc::invalid_argument)) { + DiagnosticDetail::SourceLocation sloc = { + FileSpec{}, /*line=*/1, static_cast(loc + 1), + err_len,false, /*in_user_input=*/true}; + std::string rendered_msg = + llvm::formatv(":1:{0}: {1}\n 1 | {2}\n | ^", +loc + 1, message, expr); + DiagnosticDetail detail; + detail.source_location = sloc; + detail.severity = lldb::eSeverityError; + detail.message = message; + detail.rendered = rendered_msg; + m_detail = std::move(detail); +} + +llvm::Expected +DILParser::Parse(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member) { + llvm::Error error = llvm::Error::success(); + DILParser parser(dil_input_expr, lexer, frame_sp, use_dynamic, use_synthetic, + fragile_ivar, check_ptr_vs_member, error); + + ASTNodeUP node_up = parser.Run(); + + if (error) +return error; + + return node_up; +} + +DILParser::DILParser(llvm::StringRef dil_input_expr, DILLexer lexer, + std::shared_ptr frame_sp, + lldb::DynamicValueType use_dynamic, bool use_synthetic, + bool fragile_ivar, bool check_ptr_vs_member, + llvm::Error &error) +: m_ctx_scope(frame_sp), m_input_expr(dil_input_expr), + m_dil_lexer(std::move(lexer)), m_error(error), m_use_dynamic(use_dynamic), + m_use_synthetic(use_synthetic), m_fragile_ivar(fragile_ivar), + m_check_ptr_vs_member(check_ptr_vs_member) {} + +ASTNodeUP DILParser::Run() { + ASTNodeUP expr = ParseExpression(); + + Expect(Token::Kind::eof); + + return expr; +} + +// Parse an expression. +// +// expression: +//primary_expression +// +ASTNodeUP DILParser::ParseExpression() { return ParsePrimaryExpression(); } + +// Parse a primary_expression. +// +// primary_expression: +//id_expression +//"(" expression ")" +// +ASTNodeUP DILParser::ParsePrimaryExpression() { + if (CurToken().IsOneOf({Token::coloncolon, Token::identifier})) { +// Save the source location for the diagnostics message. +uint32_t loc = CurToken().GetLocation(); +auto identifier = ParseIdExpression(); + +return std::make_unique(loc, identifier); + } + + if (CurToken().Is(Token::l_paren)) { +m_dil_lexer.Advance(); +auto expr = ParseExpression(); +Expect(Token::r_paren); +m_dil_lexer.Advance(); +return expr; + } + + BailOut(llvm::formatv("Unexpected token: {0}", CurToken()), + CurToken().GetLocation(), CurToken().GetSpelling().length()); + return std::make_unique(); +} + +// Parse nested_name_specifier. +// +// nested_name_specifier: +//type_name "::" +//namespace_name "::" +//nested_name_specifier identifier "::" +// +std::string DILParser::ParseNestedNameSpecifier() { + // The first token in nested_name_specifier is always an identifier, or + // '(anonymous namespace)'. + if (CurToken().IsNot(Token::identifier) && CurToken().IsNot(Token::l_paren)) +return ""; labath wrote: Consider pattern like: ``` switch(CurToken().GetKind()) case Token::identifier: ... return something; case Token::l_paren: ... default: return ""; } ``` (the motivation is to remove duplicate checks for token type) https://github.com/llvm/llvm-project/pull/120971 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb][AIX] Support for XCOFF Sections (PR #131304)
@@ -190,8 +190,83 @@ void ObjectFileXCOFF::ParseSymtab(Symtab &lldb_symtab) {} bool ObjectFileXCOFF::IsStripped() { return false; } -void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) {} - +void ObjectFileXCOFF::CreateSections(SectionList &unified_section_list) { + + if (m_sections_up) +return; + m_sections_up = std::make_unique(); + ModuleSP module_sp(GetModule()); + if (module_sp) { +std::lock_guard guard(module_sp->GetMutex()); + +ModuleSP module_sp(GetModule()); +for (auto sIdx = m_binary->section_begin(); sIdx != m_binary->section_end(); + ++sIdx) { labath wrote: Any reason for not using `m_binary->sections64()` here? It seems to offer a much nicer way to access this data... https://github.com/llvm/llvm-project/pull/131304 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Add unary operators Dereference and AddressOf to DIL (PR #134428)
@@ -3,7 +3,9 @@ (* This is currently a subset of the final DIL Language, matching the current DIL implementation. *) -expression = primary_expression ; +expression = unary_expression ; + +unary_expression = unary_operator primary_expression ; cmtice wrote: Need to add just plain primary_expression -- we're not forcing all expressions to have unary ops -- could still be plain variable names. https://github.com/llvm/llvm-project/pull/134428 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [LLDB] Refactored CPlusPlusLanguage::MethodName to break lldb-server dependencies (PR #132274)
https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/132274 >From 40d69ed7386c3f8169b324bd3b7591a46e34ff4d Mon Sep 17 00:00:00 2001 From: Dmitry Vasilyev Date: Thu, 20 Mar 2025 21:50:51 +0400 Subject: [PATCH] [LLDB] Refactored CPlusPlusLanguage::MethodName to break lldb-server dependencies This patch addresses the issue #129543. After this patch the size of lldb-server is reduced by 9MB. Co-authored-by: @bulbazord Alex Langford --- lldb/include/lldb/Core/Mangled.h | 2 + lldb/include/lldb/Core/RichManglingContext.h | 16 +- lldb/include/lldb/Target/Language.h | 98 lldb/source/Core/CMakeLists.txt | 2 - lldb/source/Core/Mangled.cpp | 5 + lldb/source/Core/Module.cpp | 151 -- lldb/source/Core/RichManglingContext.cpp | 22 ++- .../Clang/ClangExpressionDeclMap.cpp | 9 +- lldb/source/Plugins/Language/CMakeLists.txt | 2 + .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 128 ++- .../Language/CPlusPlus/CPlusPlusLanguage.h| 58 ++- .../Plugins/Language/ObjC/ObjCLanguage.cpp| 15 ++ .../Plugins/Language/ObjC/ObjCLanguage.h | 3 + .../Plugins/SymbolFile/PDB/SymbolFilePDB.cpp | 4 +- lldb/unittests/Core/CMakeLists.txt| 1 + .../Core/RichManglingContextTest.cpp | 7 + .../CPlusPlus/CPlusPlusLanguageTest.cpp | 22 +-- 17 files changed, 286 insertions(+), 259 deletions(-) diff --git a/lldb/include/lldb/Core/Mangled.h b/lldb/include/lldb/Core/Mangled.h index 5988d919a89b8..d5b1d4ff7149a 100644 --- a/lldb/include/lldb/Core/Mangled.h +++ b/lldb/include/lldb/Core/Mangled.h @@ -246,6 +246,8 @@ class Mangled { /// for s, otherwise the enumerator for the mangling scheme detected. static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name); + static bool IsCPPMangledName(llvm::StringRef name); + /// Decode a serialized version of this object from data. /// /// \param data diff --git a/lldb/include/lldb/Core/RichManglingContext.h b/lldb/include/lldb/Core/RichManglingContext.h index 3b79924e88a9a..50ec2ae361098 100644 --- a/lldb/include/lldb/Core/RichManglingContext.h +++ b/lldb/include/lldb/Core/RichManglingContext.h @@ -12,6 +12,7 @@ #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "llvm/ADT/Any.h" @@ -67,11 +68,7 @@ class RichManglingContext { char *m_ipd_buf; size_t m_ipd_buf_size = 2048; - /// Members for PluginCxxLanguage - /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The - /// respective header is in Plugins and including it from here causes cyclic - /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. - llvm::Any m_cxx_method_parser; + std::unique_ptr m_cxx_method_parser; /// Clean up memory when using PluginCxxLanguage void ResetCxxMethodParser(); @@ -81,15 +78,6 @@ class RichManglingContext { /// Uniform handling of string buffers for ItaniumPartialDemangler. llvm::StringRef processIPDStrResult(char *ipd_res, size_t res_len); - - /// Cast the given parser to the given type. Ideally we would have a type - /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we - /// can't access CPlusPlusLanguage::MethodName from within the header. - template static ParserT *get(llvm::Any parser) { -assert(parser.has_value()); -assert(llvm::any_cast(&parser)); -return *llvm::any_cast(&parser); - } }; } // namespace lldb_private diff --git a/lldb/include/lldb/Target/Language.h b/lldb/include/lldb/Target/Language.h index b699a90aff8e4..d46969cb3b4e4 100644 --- a/lldb/include/lldb/Target/Language.h +++ b/lldb/include/lldb/Target/Language.h @@ -214,6 +214,104 @@ class Language : public PluginInterface { return std::vector(); }; + class MethodName { + public: +MethodName() {} + +MethodName(ConstString full) +: m_full(full), m_basename(), m_context(), m_arguments(), + m_qualifiers(), m_return_type(), m_scope_qualified(), m_parsed(false), + m_parse_error(false) {} + +virtual ~MethodName() {}; + +void Clear() { + m_full.Clear(); + m_basename = llvm::StringRef(); + m_context = llvm::StringRef(); + m_arguments = llvm::StringRef(); + m_qualifiers = llvm::StringRef(); + m_return_type = llvm::StringRef(); + m_scope_qualified.clear(); + m_parsed = false; + m_parse_error = false; +} + +bool IsValid() { + if (!m_parsed) +Parse(); + if (m_parse_error) +return false; + return (bool)m_full; +} + +ConstString GetFullName() const { return m_full; } + +llvm::StringRef GetBasename() { + if (!m_parsed) +Parse(); + return m_basename; +} + +llvm::StringRef GetContext() { + if (!m_parsed) +
[Lldb-commits] [lldb] [lldb-dap] Speed up TestDAP_Progress (PR #134048)
https://github.com/JDevlieghere created https://github.com/llvm/llvm-project/pull/134048 While trying to make progress on #133782, I noticed that TestDAP_Progress was taking 90 seconds to complete. This patch brings that down to 10 seocnds by making the following changes: 1. Don't call `wait_for_event` with a 15 second timeout. By the time we call this, all progress events have been emitted, which means that we're just sitting there until we hit the timeout. 2. Don't use 10 steps (= 10 seconds) for indeterminate progress. We have two indeterminate progress tests so that's 6 seconds instead of 20. 3. Don't launch the process over and over. Once we have a dap session, we can clear the progress vector and emit new progress events. >From b2e66603fe7971e54ed7c2705ce52d6cdb4d6699 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 2 Apr 2025 01:19:58 -0700 Subject: [PATCH] [lldb-dap] Speed up TestDAP_Progress While trying to make progress on #133782, I noticed that TestDAP_Progress was taking 90 seconds to complete. This patch brings that down to 10 seocnds by making the following changes: 1. Don't call `wait_for_event` with a 15 second timeout. By the time we call this, all progress events have been emitted, which means that we're just sitting there until we hit the timeout. 2. Don't use 10 steps (= 10 seconds) for indeterminate progress. We have two indeterminate progress tests so that's 6 seconds instead of 20. 3. Don't launch the process over and over. Once we have a dap session, we can clear the progress vector and emit new progress events. --- .../lldb-dap/progress/Progress_emitter.py | 10 ++-- .../lldb-dap/progress/TestDAP_Progress.py | 53 +++ 2 files changed, 12 insertions(+), 51 deletions(-) diff --git a/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py b/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py index 445d1bdf4e496..33dee33e28b23 100644 --- a/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py +++ b/lldb/test/API/tools/lldb-dap/progress/Progress_emitter.py @@ -38,8 +38,8 @@ def create_options(cls): parser.add_option( "--total", -dest="total", -help="Total items in this progress object. When this option is not specified, this will be an indeterminate progress.", +dest="total", help="Total items in this progress object. When this +option is not specified, this will be an indeterminate progress.", type="int", default=None, ) @@ -88,11 +88,11 @@ def __call__(self, debugger, command, exe_ctx, result): progress = lldb.SBProgress( "Progress tester", "Initial Detail", total, debugger ) -# Check to see if total is set to None to indicate an indeterminate progress -# then default to 10 steps. +# Check to see if total is set to None to indicate an indeterminate +# progress then default to 3 steps. with progress: if total is None: -total = 10 +total = 3 for i in range(1, total): if cmd_options.no_details: diff --git a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py index f723a2d254825..ffe3d38eb49a3 100755 --- a/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py +++ b/lldb/test/API/tools/lldb-dap/progress/TestDAP_Progress.py @@ -19,7 +19,6 @@ def verify_progress_events( expected_not_in_message=None, only_verify_first_update=False, ): -self.dap_server.wait_for_event("progressEnd", 15) self.assertTrue(len(self.dap_server.progress_events) > 0) start_found = False update_found = False @@ -45,20 +44,18 @@ def verify_progress_events( self.assertTrue(start_found) self.assertTrue(update_found) self.assertTrue(end_found) +self.dap_server.progress_events.clear() @skipIfWindows -def test_output(self): +def test(self): program = self.getBuildArtifact("a.out") self.build_and_launch(program) progress_emitter = os.path.join(os.getcwd(), "Progress_emitter.py") -source = "main.cpp" -breakpoint_ids = self.set_source_breakpoints( -source, [line_number(source, "// break here")] -) -self.continue_to_breakpoints(breakpoint_ids) self.dap_server.request_evaluate( f"`command script import {progress_emitter}", context="repl" ) + +# Test details. self.dap_server.request_evaluate( "`test-progress --total 3 --seconds 1", context="repl" ) @@ -68,19 +65,7 @@ def test_output(self): expected_not_in_message="Progress tester", ) -@skipIfWindows -def test_output_nodetails(self): -program = self.getBuildArtifact("a.out") -