[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
https://github.com/ZequanWu created https://github.com/llvm/llvm-project/pull/81541 This implements functionality to handle `DataBreakpointInfo` request and `SetDataBreakpoints` request. It doesn't handle the case when `name` is an expression, see Todo comment for details. This is based on top of https://github.com/llvm/llvm-project/pull/80753. >From 40fca279bc2939870f5491e36b03742b567a8ab0 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Mon, 12 Feb 2024 16:36:08 -0500 Subject: [PATCH 1/2] [lldb-dap][NFC] Add Breakpoint struct to share common logic. --- lldb/tools/lldb-dap/Breakpoint.cpp| 76 + lldb/tools/lldb-dap/Breakpoint.h | 33 ++ lldb/tools/lldb-dap/BreakpointBase.cpp| 299 + lldb/tools/lldb-dap/BreakpointBase.h | 33 +- lldb/tools/lldb-dap/CMakeLists.txt| 1 + lldb/tools/lldb-dap/FunctionBreakpoint.cpp| 12 +- lldb/tools/lldb-dap/FunctionBreakpoint.h | 4 +- lldb/tools/lldb-dap/JSONUtils.cpp | 46 +-- lldb/tools/lldb-dap/JSONUtils.h | 5 +- lldb/tools/lldb-dap/SourceBreakpoint.cpp | 304 +- lldb/tools/lldb-dap/SourceBreakpoint.h| 30 +- lldb/tools/lldb-dap/lldb-dap.cpp | 17 +- .../gn/secondary/lldb/tools/lldb-dap/BUILD.gn | 1 + 13 files changed, 459 insertions(+), 402 deletions(-) create mode 100644 lldb/tools/lldb-dap/Breakpoint.cpp create mode 100644 lldb/tools/lldb-dap/Breakpoint.h diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp new file mode 100644 index 00..0c33d4b114d760 --- /dev/null +++ b/lldb/tools/lldb-dap/Breakpoint.cpp @@ -0,0 +1,76 @@ +//===-- Breakpoint.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 "Breakpoint.h" +#include "DAP.h" +#include "JSONUtils.h" +#include "llvm/ADT/StringExtras.h" + +using namespace lldb_dap; + +void Breakpoint::SetCondition() { bp.SetCondition(condition.c_str()); } + +void Breakpoint::SetHitCondition() { + uint64_t hitCount = 0; + if (llvm::to_integer(hitCondition, hitCount)) +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()) +return; + object.try_emplace("verified", bp.GetNumResolvedLocations() > 0); + object.try_emplace("id", 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 + // other source file and line breakpoints in the same file. + + // Below we search for the first resolved location in a breakpoint and report + // 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(); + for (size_t i = 0; i < num_locs; ++i) { +bp_loc = 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); + auto bp_addr = bp_loc.GetAddress(); + + if (bp_addr.IsValid()) { +std::string formatted_addr = +"0x" + llvm::utohexstr(bp_addr.GetLoadAddress(g_dap.target)); +object.try_emplace("instructionReference", formatted_addr); +auto line_entry = bp_addr.GetLineEntry(); +const auto line = line_entry.GetLine(); +if (line != UINT32_MAX) + object.try_emplace("line", line); +const auto column = line_entry.GetColumn(); +if (column != 0) + object.try_emplace("column", column); +object.try_emplace("source", CreateSource(line_entry)); + } +} + +bool Breakpoint::MatchesName(const char *name) { return bp.MatchesName(name); } + +void Breakpoint::SetBreakpoint() { + // See comments in BreakpointBase::GetBreakpointLabel() for details of why + // we add a label to our breakpoints. + bp.AddName(GetBreakpointLabel()); + if (!condition.empty()) +SetCondition(); + if (!hitCondition.empty()) +SetHitCondition(); +} diff --git a/lldb/tools/lldb-dap/Breakpoint.h b/lldb/tools/lldb-dap/Breakpoint.h new file mode 100644 index 00..47a9d9c59ae2b7 --- /dev/null +++ b/lldb/tools/lldb-dap/Breakpoint.h @@ -0,0 +1,33 @@ +//===-- Breakpoint.h *- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
llvmbot wrote: @llvm/pr-subscribers-lldb Author: Zequan Wu (ZequanWu) Changes This implements functionality to handle `DataBreakpointInfo` request and `SetDataBreakpoints` request. It doesn't handle the case when `name` is an expression, see Todo comment for details. This is based on top of https://github.com/llvm/llvm-project/pull/80753. --- Patch is 62.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81541.diff 20 Files Affected: - (modified) lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py (+37) - (added) lldb/test/API/tools/lldb-dap/databreakpoint/Makefile (+3) - (added) lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py (+100) - (added) lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp (+17) - (added) lldb/tools/lldb-dap/Breakpoint.cpp (+76) - (added) lldb/tools/lldb-dap/Breakpoint.h (+33) - (modified) lldb/tools/lldb-dap/BreakpointBase.cpp (+1-298) - (modified) lldb/tools/lldb-dap/BreakpointBase.h (+6-27) - (modified) lldb/tools/lldb-dap/CMakeLists.txt (+2) - (modified) lldb/tools/lldb-dap/DAPForward.h (+2) - (modified) lldb/tools/lldb-dap/FunctionBreakpoint.cpp (+2-10) - (modified) lldb/tools/lldb-dap/FunctionBreakpoint.h (+2-2) - (modified) lldb/tools/lldb-dap/JSONUtils.cpp (+3-43) - (modified) lldb/tools/lldb-dap/JSONUtils.h (+3-2) - (modified) lldb/tools/lldb-dap/SourceBreakpoint.cpp (+295-9) - (modified) lldb/tools/lldb-dap/SourceBreakpoint.h (+27-3) - (added) lldb/tools/lldb-dap/Watchpoint.cpp (+48) - (added) lldb/tools/lldb-dap/Watchpoint.h (+34) - (modified) lldb/tools/lldb-dap/lldb-dap.cpp (+258-8) - (modified) llvm/utils/gn/secondary/lldb/tools/lldb-dap/BUILD.gn (+2) ``diff 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 bb863bb8719176..2d48cfbd819366 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 @@ -501,6 +501,17 @@ def get_local_variable_value(self, name, frameIndex=0, threadId=None): return variable["value"] return None +def get_local_variable_child(self, name, child_name, frameIndex=0, threadId=None): +local = self.get_local_variable(name, frameIndex, threadId) +if local["variablesReference"] == 0: +return None +children = self.request_variables(local["variablesReference"])[ +"body"]["variables"] +for child in children: +if child["name"] == child_name: +return child +return None + def replay_packets(self, replay_file_path): f = open(replay_file_path, "r") mode = "invalid" @@ -895,6 +906,32 @@ def request_setFunctionBreakpoints(self, names, condition=None, hitCondition=Non } return self.send_recv(command_dict) +def request_dataBreakpointInfo(self, variablesReference, name): +args_dict = {"variablesReference": variablesReference, "name": name} +command_dict = { +"command": "dataBreakpointInfo", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + +def request_setDataBreakpoint(self, dataBreakpoints): +"""dataBreakpoints is a list of dictionary with following fields: +{ +dataId: (address in hex)/(size in bytes) +accessType: read/write/readWrite +[condition]: string +[hitCondition]: string +} +""" +args_dict = {"breakpoints": dataBreakpoints} +command_dict = { +"command": "setDataBreakpoints", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_compileUnits(self, moduleId): args_dict = {"moduleId": moduleId} command_dict = { diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile b/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py new file mode 100644 index 00..a13b4399a02f18 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py @@ -0,0 +1,100 @@ +""" +Test lldb-dap dataBreakpointInfo and setDataBreakpoints requests +""" + + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbdap_testcase + + +class TestDAP_setDataBreakpoints(lldbdap_testcase.DAPTestCaseBase): +def setUp(self): +lldbdap_
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
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 41ea02261224446dadb1b1561d70137699255518...2743af56220630f55a0c5bc0a7a13806c817aaad lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py `` View the diff from darker here. ``diff --- packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 2024-02-12 21:42:09.00 + +++ packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py 2024-02-12 21:54:33.674990 + @@ -503,17 +503,18 @@ def get_local_variable_child(self, name, child_name, frameIndex=0, threadId=None): local = self.get_local_variable(name, frameIndex, threadId) if local["variablesReference"] == 0: return None -children = self.request_variables(local["variablesReference"])[ -"body"]["variables"] +children = self.request_variables(local["variablesReference"])["body"][ +"variables" +] for child in children: if child["name"] == child_name: return child return None - + def replay_packets(self, replay_file_path): f = open(replay_file_path, "r") mode = "invalid" set_sequence = False command_dict = None --- test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py 2024-02-12 21:42:09.00 + +++ test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py 2024-02-12 21:54:33.758542 + @@ -14,42 +14,33 @@ self.accessTypes = ["read", "write", "readWrite"] @skipIfWindows @skipIfRemote def test_functionality(self): -"""Tests setting data breakpoints. -""" +"""Tests setting data breakpoints.""" program = self.getBuildArtifact("a.out") self.build_and_launch(program) source = "main.cpp" -first_loop_break_line = line_number( -source, "// first loop breakpoint") -breakpoint_ids = self.set_source_breakpoints( -source, [first_loop_break_line]) +first_loop_break_line = line_number(source, "// first loop breakpoint") +breakpoint_ids = self.set_source_breakpoints(source, [first_loop_break_line]) self.continue_to_breakpoints(breakpoint_ids) self.dap_server.get_local_variables() # Test write watchpoints on x, arr[2] response_x = self.dap_server.request_dataBreakpointInfo(1, "x") arr = self.dap_server.get_local_variable("arr") response_arr_2 = self.dap_server.request_dataBreakpointInfo( -arr["variablesReference"], "[2]") +arr["variablesReference"], "[2]" +) # Test response from dataBreakpointInfo request. self.assertEquals(response_x["body"]["dataId"].split("/")[1], "4") self.assertEquals(response_x["body"]["accessTypes"], self.accessTypes) self.assertEquals(response_arr_2["body"]["dataId"].split("/")[1], "1") -self.assertEquals(response_arr_2["body"] - ["accessTypes"], self.accessTypes) +self.assertEquals(response_arr_2["body"]["accessTypes"], self.accessTypes) dataBreakpoints = [ -{ -"dataId": response_x["body"]["dataId"], -"accessType": "write" -}, -{ -"dataId": response_arr_2["body"]["dataId"], -"accessType": "write" -} +{"dataId": response_x["body"]["dataId"], "accessType": "write"}, +{"dataId": response_arr_2["body"]["dataId"], "accessType": "write"}, ] self.dap_server.request_setDataBreakpoint(dataBreakpoints) self.dap_server.request_continue() self.dap_server.wait_for_stopped() @@ -65,20 +56,18 @@ self.assertEquals(arr_2["value"], "'z'") self.assertEquals(i_val, "2") self.dap_server.request_setDataBreakpoint([]) # Test hit condition -second_loop_break_line = line_number( -source, "// second loop breakpoint") -breakpoint_ids = self.set_source_breakpoints( -source, [second_loop_break_line]) +second_loop_break_line = line_number(source, "// second loop breakpoint") +breakpoint_ids = self.set_source_breakpoints(source, [second_loop_break_line]) self.continue_to_breakpoints(breakpoint_ids) dataBreakpoints = [ { "dataId": response_x["body"]["dataId"], "accessType": "write", -"hitCondition": "2" +"hitCondition": "2", } ] self.dap_server.request_setDataBreakpoint(dataBreakpoints) self.dap_server.request_continue()
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
https://github.com/walter-erquinigo edited https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
https://github.com/walter-erquinigo commented: This looks great overall! Could you split this PR into two? One with the refactoring and another one with the new features? That would make reviewing easier https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
@@ -895,6 +906,32 @@ def request_setFunctionBreakpoints(self, names, condition=None, hitCondition=Non } return self.send_recv(command_dict) +def request_dataBreakpointInfo(self, variablesReference, name): +args_dict = {"variablesReference": variablesReference, "name": name} +command_dict = { +"command": "dataBreakpointInfo", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + +def request_setDataBreakpoint(self, dataBreakpoints): +"""dataBreakpoints is a list of dictionary with following fields: walter-erquinigo wrote: `list of dictionary` sounds very weird. Did you mean something else? https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
ZequanWu wrote: > This looks great overall! Could you split this PR into two? One with the > refactoring and another one with the new features? That would make reviewing > easier Yes, I already split it out: https://github.com/llvm/llvm-project/pull/80753 is the refactor pr. I'll rebase this one once that is merged. https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
walter-erquinigo wrote: just ping me when this PR is rebased https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
https://github.com/ZequanWu updated https://github.com/llvm/llvm-project/pull/81541 >From a2d28693da09a569b49bc39a4743e302b2479d87 Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Tue, 13 Feb 2024 11:55:33 -0500 Subject: [PATCH] [lldb-dap] Add support for data breakpoint. This implements functionality to handle DataBreakpointInfo request and SetDataBreakpoints request. It doesn't handle the case when name is an expression, see Todo comment for details. --- .../test/tools/lldb-dap/dap_server.py | 38 +++ .../tools/lldb-dap/databreakpoint/Makefile| 3 + .../TestDAP_setDataBreakpoints.py | 88 +++ .../tools/lldb-dap/databreakpoint/main.cpp| 17 ++ lldb/tools/lldb-dap/CMakeLists.txt| 1 + lldb/tools/lldb-dap/DAPForward.h | 2 + lldb/tools/lldb-dap/Watchpoint.cpp| 48 lldb/tools/lldb-dap/Watchpoint.h | 34 +++ lldb/tools/lldb-dap/lldb-dap.cpp | 249 ++ .../gn/secondary/lldb/tools/lldb-dap/BUILD.gn | 1 + 10 files changed, 481 insertions(+) create mode 100644 lldb/test/API/tools/lldb-dap/databreakpoint/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py create mode 100644 lldb/test/API/tools/lldb-dap/databreakpoint/main.cpp create mode 100644 lldb/tools/lldb-dap/Watchpoint.cpp create mode 100644 lldb/tools/lldb-dap/Watchpoint.h 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 bb863bb8719176..8c192d21461cc9 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 @@ -501,6 +501,18 @@ def get_local_variable_value(self, name, frameIndex=0, threadId=None): return variable["value"] return None +def get_local_variable_child(self, name, child_name, frameIndex=0, threadId=None): +local = self.get_local_variable(name, frameIndex, threadId) +if local["variablesReference"] == 0: +return None +children = self.request_variables(local["variablesReference"])["body"][ +"variables" +] +for child in children: +if child["name"] == child_name: +return child +return None + def replay_packets(self, replay_file_path): f = open(replay_file_path, "r") mode = "invalid" @@ -895,6 +907,32 @@ def request_setFunctionBreakpoints(self, names, condition=None, hitCondition=Non } return self.send_recv(command_dict) +def request_dataBreakpointInfo(self, variablesReference, name): +args_dict = {"variablesReference": variablesReference, "name": name} +command_dict = { +"command": "dataBreakpointInfo", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + +def request_setDataBreakpoint(self, dataBreakpoints): +"""dataBreakpoints is a list of dictionary with following fields: +{ +dataId: (address in hex)/(size in bytes) +accessType: read/write/readWrite +[condition]: string +[hitCondition]: string +} +""" +args_dict = {"breakpoints": dataBreakpoints} +command_dict = { +"command": "setDataBreakpoints", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + def request_compileUnits(self, moduleId): args_dict = {"moduleId": moduleId} command_dict = { diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile b/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile new file mode 100644 index 00..8b20bcb050 --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/databreakpoint/Makefile @@ -0,0 +1,3 @@ +CXX_SOURCES := main.cpp + +include Makefile.rules diff --git a/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py new file mode 100644 index 00..0de2d5fb3075ac --- /dev/null +++ b/lldb/test/API/tools/lldb-dap/databreakpoint/TestDAP_setDataBreakpoints.py @@ -0,0 +1,88 @@ +""" +Test lldb-dap dataBreakpointInfo and setDataBreakpoints requests +""" + +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +import lldbdap_testcase + + +class TestDAP_setDataBreakpoints(lldbdap_testcase.DAPTestCaseBase): +def setUp(self): +lldbdap_testcase.DAPTestCaseBase.setUp(self) +self.accessTypes = ["read", "write", "readWrite"] + +@skipIfWindows +@skipIfRemote +def test_functionality(self): +"""Tests setting data breakpoints.""" +program = self.getBuildArtifact("a.out") +self.build_and_launch(program) +sour
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
ZequanWu wrote: > just ping me when this PR is rebased Rebased. https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [llvm] [WIP][lldb-dap] Add support for data breakpoint. (PR #81541)
@@ -895,6 +906,32 @@ def request_setFunctionBreakpoints(self, names, condition=None, hitCondition=Non } return self.send_recv(command_dict) +def request_dataBreakpointInfo(self, variablesReference, name): +args_dict = {"variablesReference": variablesReference, "name": name} +command_dict = { +"command": "dataBreakpointInfo", +"type": "request", +"arguments": args_dict, +} +return self.send_recv(command_dict) + +def request_setDataBreakpoint(self, dataBreakpoints): +"""dataBreakpoints is a list of dictionary with following fields: ZequanWu wrote: `dataBreakpoints` is a list of the dataBreakpoint which has following format: ``` { dataId: (address in hex)/(size in bytes) accessType: read/write/readWrite [condition]: string [hitCondition]: string } ``` https://github.com/llvm/llvm-project/pull/81541 ___ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits