From bfd9427e915903e99e60c2a705bd10b698a3cadf Mon Sep 17 00:00:00 2001 From: jimingham Date: Wed, 8 Oct 2025 13:01:20 -0700 Subject: [PATCH 1/4] Make SBBreakpoint/SBBreakpointLocation.SetCondition(nullptr) work again. (#162370) The addition of the StopCondition in the lldb_private layer meant that clearing a breakpoint condition with: sb_break.SetCondition(nullptr); now crashes. Also, GetCondition for an empty condition used to return a nullptr, but now it returns "". This patch fixes that crash and makes the SB GetCondition always return nullptr for an empty condition. (cherry picked from commit f3e2c20a23b11fbe1149e5d2e3631109af6d3238) --- lldb/source/API/SBBreakpoint.cpp | 11 ++- lldb/source/API/SBBreakpointLocation.cpp | 11 ++- lldb/unittests/API/CMakeLists.txt | 1 + .../API/SBBreakpointClearConditionTest.cpp | 69 +++++++++++++++++++ lldb/unittests/Breakpoint/CMakeLists.txt | 6 +- 5 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 lldb/unittests/API/SBBreakpointClearConditionTest.cpp diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp index 07c0a2ea907ba..23dba462478c9 100644 --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -275,7 +275,11 @@ void SBBreakpoint::SetCondition(const char *condition) { if (bkpt_sp) { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); - bkpt_sp->SetCondition(StopCondition(condition)); + // Treat a null pointer as resetting the condition. + if (!condition) + bkpt_sp->SetCondition(StopCondition()); + else + bkpt_sp->SetCondition(StopCondition(condition)); } } @@ -288,7 +292,10 @@ const char *SBBreakpoint::GetCondition() { std::lock_guard guard( bkpt_sp->GetTarget().GetAPIMutex()); - return ConstString(bkpt_sp->GetCondition().GetText()).GetCString(); + StopCondition cond = bkpt_sp->GetCondition(); + if (!cond) + return nullptr; + return ConstString(cond.GetText()).GetCString(); } void SBBreakpoint::SetAutoContinue(bool auto_continue) { diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp index e786435c4f8af..2feaa5c805a15 100644 --- a/lldb/source/API/SBBreakpointLocation.cpp +++ b/lldb/source/API/SBBreakpointLocation.cpp @@ -160,7 +160,11 @@ void SBBreakpointLocation::SetCondition(const char *condition) { if (loc_sp) { std::lock_guard guard( loc_sp->GetTarget().GetAPIMutex()); - loc_sp->SetCondition(StopCondition(condition)); + // Treat a nullptr as clearing the condition + if (!condition) + loc_sp->SetCondition(StopCondition()); + else + loc_sp->SetCondition(StopCondition(condition)); } } @@ -173,7 +177,10 @@ const char *SBBreakpointLocation::GetCondition() { std::lock_guard guard( loc_sp->GetTarget().GetAPIMutex()); - return ConstString(loc_sp->GetCondition().GetText()).GetCString(); + StopCondition cond = loc_sp->GetCondition(); + if (!cond) + return nullptr; + return ConstString(cond.GetText()).GetCString(); } void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { diff --git a/lldb/unittests/API/CMakeLists.txt b/lldb/unittests/API/CMakeLists.txt index 06ac49244176c..1ced3b119f87f 100644 --- a/lldb/unittests/API/CMakeLists.txt +++ b/lldb/unittests/API/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(APITests SBCommandInterpreterTest.cpp SBLineEntryTest.cpp SBMutexTest.cpp + SBBreakpointClearConditionTest.cpp LINK_LIBS liblldb diff --git a/lldb/unittests/API/SBBreakpointClearConditionTest.cpp b/lldb/unittests/API/SBBreakpointClearConditionTest.cpp new file mode 100644 index 0000000000000..993f7f90d97c0 --- /dev/null +++ b/lldb/unittests/API/SBBreakpointClearConditionTest.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// Use the umbrella header for -Wdocumentation. +#include "lldb/API/LLDB.h" + +#include "TestingSupport/SubsystemRAII.h" +#include "lldb/API/SBBreakpoint.h" +#include "lldb/API/SBBreakpointLocation.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBTarget.h" +#include "gtest/gtest.h" +#include +#include + +using namespace lldb_private; +using namespace lldb; + +class BreakpointClearConditionTest : public ::testing::Test { +public: + void SetUp() override { + m_sb_debugger = SBDebugger::Create(/*source_init_files=*/false); + }; + + void TearDown() override { SBDebugger::Destroy(m_sb_debugger); } + SBDebugger m_sb_debugger; + SubsystemRAII subsystems; +}; + +template void test_condition(T sb_object) { + const char *in_cond_str = "Here is a condition"; + sb_object.SetCondition(in_cond_str); + // Make sure we set the condition correctly: + const char *out_cond_str = sb_object.GetCondition(); + EXPECT_STREQ(in_cond_str, out_cond_str); + // Now unset it by passing in nullptr and make sure that works: + const char *empty_tokens[2] = {nullptr, ""}; + for (auto token : empty_tokens) { + sb_object.SetCondition(token); + out_cond_str = sb_object.GetCondition(); + // And make sure an unset condition returns nullptr: + EXPECT_EQ(nullptr, out_cond_str); + } +} + +TEST_F(BreakpointClearConditionTest, BreakpointClearConditionTest) { + // Create target + SBTarget sb_target; + SBError error; + sb_target = + m_sb_debugger.CreateTarget("", "x86_64-apple-macosx-", "remote-macosx", + /*add_dependent=*/false, error); + + EXPECT_EQ(sb_target.IsValid(), true); + + // Create breakpoint + SBBreakpoint sb_breakpoint = sb_target.BreakpointCreateByAddress(0xDEADBEEF); + test_condition(sb_breakpoint); + + // Address breakpoints always have one location, so we can also use this + // to test the location: + SBBreakpointLocation sb_loc = sb_breakpoint.GetLocationAtIndex(0); + EXPECT_EQ(sb_loc.IsValid(), true); + test_condition(sb_loc); +} diff --git a/lldb/unittests/Breakpoint/CMakeLists.txt b/lldb/unittests/Breakpoint/CMakeLists.txt index 3c234a4fea29a..3e4161313cd9d 100644 --- a/lldb/unittests/Breakpoint/CMakeLists.txt +++ b/lldb/unittests/Breakpoint/CMakeLists.txt @@ -1,10 +1,14 @@ -add_lldb_unittest(LLDBBreakpointTests +add_lldb_unittest(LLDBBreakpointTests BreakpointIDTest.cpp WatchpointAlgorithmsTests.cpp LINK_COMPONENTS Support LINK_LIBS + liblldb lldbBreakpoint lldbCore + LLVMTestingSupport + lldbUtilityHelpers + lldbPluginPlatformMacOSX ) From 766873b0d857eaa9a825f649e6bf1c2ce3f14eda Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 8 Oct 2025 12:55:26 -0700 Subject: [PATCH 2/4] [lldb] Enforce that only the LLDB API unit tests can link liblldb (#162384) Enforce that only specific tests can link liblldb. All the other unit tests statically link the private libraries. Linking both the static libraries and liblldb results in duplicated symbols. Fixes #162378 (cherry picked from commit 02572c6e9bbb60916ce471cbfec339b68a2121e2) --- lldb/unittests/API/CMakeLists.txt | 2 ++ lldb/unittests/CMakeLists.txt | 6 +++++- lldb/unittests/DAP/CMakeLists.txt | 2 ++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/API/CMakeLists.txt b/lldb/unittests/API/CMakeLists.txt index 1ced3b119f87f..27fe335b9d54f 100644 --- a/lldb/unittests/API/CMakeLists.txt +++ b/lldb/unittests/API/CMakeLists.txt @@ -4,6 +4,8 @@ add_lldb_unittest(APITests SBMutexTest.cpp SBBreakpointClearConditionTest.cpp + SBAPITEST + LINK_LIBS liblldb ) diff --git a/lldb/unittests/CMakeLists.txt b/lldb/unittests/CMakeLists.txt index 48fcfc40b73ab..2177430b81d07 100644 --- a/lldb/unittests/CMakeLists.txt +++ b/lldb/unittests/CMakeLists.txt @@ -12,7 +12,7 @@ endif() function(add_lldb_unittest test_name) cmake_parse_arguments(ARG - "" + "SBAPITEST" "" "LINK_LIBS;LINK_COMPONENTS" ${ARGN}) @@ -21,6 +21,10 @@ function(add_lldb_unittest test_name) message(FATAL_ERROR "Unit test name must end with 'Tests' for lit to find it.") endif() + if ("liblldb" IN_LIST ARG_LINK_LIBS AND NOT ARG_SBAPITEST) + message(FATAL_ERROR "The ${test_name} are not allowed to link liblldb.") + endif() + list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) add_unittest(LLDBUnitTests diff --git a/lldb/unittests/DAP/CMakeLists.txt b/lldb/unittests/DAP/CMakeLists.txt index 156cd625546bd..cc68989f07974 100644 --- a/lldb/unittests/DAP/CMakeLists.txt +++ b/lldb/unittests/DAP/CMakeLists.txt @@ -11,6 +11,8 @@ add_lldb_unittest(DAPTests TestBase.cpp VariablesTest.cpp + SBAPITEST + LINK_COMPONENTS Support LINK_LIBS From becc950bb8d613f462d698e552c08d8f1f36e524 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 8 Oct 2025 12:55:42 -0700 Subject: [PATCH 3/4] [lldb] Add a blurb about not including private headers (#162404) Add a blurb about not including private headers in the API tests. (cherry picked from commit 9527f9338f9d116b6eaf5771b961ed0210119326) --- lldb/unittests/API/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/unittests/API/CMakeLists.txt b/lldb/unittests/API/CMakeLists.txt index 27fe335b9d54f..b86054fb353f7 100644 --- a/lldb/unittests/API/CMakeLists.txt +++ b/lldb/unittests/API/CMakeLists.txt @@ -11,7 +11,8 @@ add_lldb_unittest(APITests ) # Build with -Wdocumentation. This relies on the tests including all the API -# headers through API/LLDB.h. +# headers through API/LLDB.h. It also means that the API tests cannot include +# private headers. check_cxx_compiler_flag("-Wdocumentation" CXX_SUPPORTS_DOCUMENTATION) if (CXX_SUPPORTS_DOCUMENTATION) From ad8cd3812192d77a15e93c77a46459c517afc387 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere Date: Wed, 8 Oct 2025 13:59:51 -0700 Subject: [PATCH 4/4] [lldb] Remove unnecessary LINK_LIBS in LLDBBreakpointTests (NFC) (cherry picked from commit 1395d4315bf49be64817b79e3863d183bb28c3e1) --- lldb/unittests/Breakpoint/CMakeLists.txt | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lldb/unittests/Breakpoint/CMakeLists.txt b/lldb/unittests/Breakpoint/CMakeLists.txt index 3e4161313cd9d..dec2265a725a5 100644 --- a/lldb/unittests/Breakpoint/CMakeLists.txt +++ b/lldb/unittests/Breakpoint/CMakeLists.txt @@ -1,14 +1,10 @@ -add_lldb_unittest(LLDBBreakpointTests - BreakpointIDTest.cpp - WatchpointAlgorithmsTests.cpp - - LINK_COMPONENTS - Support - LINK_LIBS - liblldb - lldbBreakpoint - lldbCore - LLVMTestingSupport - lldbUtilityHelpers - lldbPluginPlatformMacOSX - ) +add_lldb_unittest(LLDBBreakpointTests + BreakpointIDTest.cpp + WatchpointAlgorithmsTests.cpp + + LINK_COMPONENTS + Support + LINK_LIBS + lldbBreakpoint + lldbCore + )