This revision was automatically updated to reflect the committed changes.
Closed by commit rG9cb227f561f4: Stop emitting a breakpoint for each location 
in a breakpoint when responding to… (authored by clayborg).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73665/new/

https://reviews.llvm.org/D73665

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
  lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
  lldb/test/API/tools/lldb-vscode/breakpoint-events/Makefile
  
lldb/test/API/tools/lldb-vscode/breakpoint-events/TestVSCode_breakpointEvents.py
  lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.cpp
  lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.h
  lldb/test/API/tools/lldb-vscode/breakpoint-events/main.cpp
  lldb/tools/lldb-vscode/BreakpointBase.cpp
  lldb/tools/lldb-vscode/BreakpointBase.h
  lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp
  lldb/tools/lldb-vscode/FunctionBreakpoint.cpp
  lldb/tools/lldb-vscode/JSONUtils.cpp
  lldb/tools/lldb-vscode/JSONUtils.h
  lldb/tools/lldb-vscode/LLDBUtils.cpp
  lldb/tools/lldb-vscode/LLDBUtils.h
  lldb/tools/lldb-vscode/SourceBreakpoint.cpp
  lldb/tools/lldb-vscode/lldb-vscode.cpp

Index: lldb/tools/lldb-vscode/lldb-vscode.cpp
===================================================================
--- lldb/tools/lldb-vscode/lldb-vscode.cpp
+++ lldb/tools/lldb-vscode/lldb-vscode.cpp
@@ -379,27 +379,20 @@
         if (event_mask & lldb::SBTarget::eBroadcastBitBreakpointChanged) {
           auto event_type =
               lldb::SBBreakpoint::GetBreakpointEventTypeFromEvent(event);
-          const auto num_locs =
-              lldb::SBBreakpoint::GetNumBreakpointLocationsFromEvent(event);
           auto bp = lldb::SBBreakpoint::GetBreakpointFromEvent(event);
-          bool added = event_type & lldb::eBreakpointEventTypeLocationsAdded;
-          bool removed =
-              event_type & lldb::eBreakpointEventTypeLocationsRemoved;
-          if (added || removed) {
-            for (size_t i = 0; i < num_locs; ++i) {
-              auto bp_loc =
-                  lldb::SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(
-                      event, i);
-              auto bp_event = CreateEventObject("breakpoint");
-              llvm::json::Object body;
-              body.try_emplace("breakpoint", CreateBreakpoint(bp_loc));
-              if (added)
-                body.try_emplace("reason", "new");
-              else
-                body.try_emplace("reason", "removed");
-              bp_event.try_emplace("body", std::move(body));
-              g_vsc.SendJSON(llvm::json::Value(std::move(bp_event)));
-            }
+          // If the breakpoint was originated from the IDE, it will have the
+          // BreakpointBase::GetBreakpointLabel() label attached. Regardless
+          // of wether the locations were added or removed, the breakpoint
+          // ins't going away, so we the reason is always "changed".
+          if ((event_type & lldb::eBreakpointEventTypeLocationsAdded ||
+               event_type & lldb::eBreakpointEventTypeLocationsRemoved) &&
+              bp.MatchesName(BreakpointBase::GetBreakpointLabel())) {
+            auto bp_event = CreateEventObject("breakpoint");
+            llvm::json::Object body;
+            body.try_emplace("breakpoint", CreateBreakpoint(bp));
+            body.try_emplace("reason", "changed");
+            bp_event.try_emplace("body", std::move(body));
+            g_vsc.SendJSON(llvm::json::Value(std::move(bp_event)));
           }
         }
       } else if (event.BroadcasterMatchesRef(g_vsc.broadcaster)) {
Index: lldb/tools/lldb-vscode/SourceBreakpoint.cpp
===================================================================
--- lldb/tools/lldb-vscode/SourceBreakpoint.cpp
+++ lldb/tools/lldb-vscode/SourceBreakpoint.cpp
@@ -17,6 +17,9 @@
 
 void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) {
   bp = g_vsc.target.BreakpointCreateByLocation(source_path.str().c_str(), line);
+  // 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())
Index: lldb/tools/lldb-vscode/LLDBUtils.h
===================================================================
--- lldb/tools/lldb-vscode/LLDBUtils.h
+++ lldb/tools/lldb-vscode/LLDBUtils.h
@@ -106,46 +106,6 @@
 ///     The LLDB frame index ID.
 uint32_t GetLLDBFrameID(uint64_t dap_frame_id);
 
-/// Given a LLDB breakpoint, make a breakpoint ID that is unique to a
-/// specific breakpoint and breakpoint location.
-///
-/// VSCode requires a Breakpoint "id" to be unique, so we use the
-/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the
-/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits.
-///
-/// \param[in] bp_loc
-///     The LLDB break point location.
-///
-/// \return
-///     A unique integer that allows us to easily find the right
-///     stack frame within a thread on subsequent VS code requests.
-int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc);
-
-/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint ID.
-///
-/// VSCode requires a Breakpoint "id" to be unique, so we use the
-/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the
-/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits.
-///
-/// \param[in] dap_breakpoint_id
-///     The VSCode breakpoint ID to convert to an LLDB breakpoint ID.
-///
-/// \return
-///     The LLDB breakpoint ID.
-uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id);
-
-/// Given a VSCode breakpoint ID, convert to a LLDB breakpoint location ID.
-///
-/// VSCode requires a Breakpoint "id" to be unique, so we use the
-/// breakpoint ID in the lower BREAKPOINT_ID_SHIFT bits and the
-/// breakpoint location ID in the upper BREAKPOINT_ID_SHIFT bits.
-///
-/// \param[in] dap_breakpoint_id
-///     The VSCode frame ID to convert to a breakpoint location ID.
-///
-/// \return
-///     The LLDB breakpoint location ID.
-uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id);
 } // namespace lldb_vscode
 
 #endif
Index: lldb/tools/lldb-vscode/LLDBUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/LLDBUtils.cpp
+++ lldb/tools/lldb-vscode/LLDBUtils.cpp
@@ -79,19 +79,4 @@
                    frame.GetFrameID());
 }
 
-static uint32_t constexpr BREAKPOINT_ID_SHIFT = 22;
-
-uint32_t GetLLDBBreakpointID(uint64_t dap_breakpoint_id) {
-  return dap_breakpoint_id >> BREAKPOINT_ID_SHIFT;
-}
-
-uint32_t GetLLDBBreakpointLocationID(uint64_t dap_breakpoint_id) {
-  return dap_breakpoint_id & ((1u << BREAKPOINT_ID_SHIFT) - 1);
-}
-
-int64_t MakeVSCodeBreakpointID(lldb::SBBreakpointLocation &bp_loc) {
-  return (int64_t)(bp_loc.GetBreakpoint().GetID() << BREAKPOINT_ID_SHIFT |
-                   bp_loc.GetID());
-}
-
 } // namespace lldb_vscode
Index: lldb/tools/lldb-vscode/JSONUtils.h
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.h
+++ lldb/tools/lldb-vscode/JSONUtils.h
@@ -199,13 +199,13 @@
 /// Converts breakpoint location to a Visual Studio Code "Breakpoint"
 /// JSON object and appends it to the \a breakpoints array.
 ///
-/// \param[in] bp_loc
-///     A LLDB breakpoint location object to convert into a JSON value
+/// \param[in] bp
+///     A LLDB breakpoint object to convert into a JSON value
 ///
 /// \return
 ///     A "Breakpoint" JSON object with that follows the formal JSON
 ///     definition outlined by Microsoft.
-llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc);
+llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp);
 
 /// Create a "Event" JSON object using \a event_name as the event name
 ///
Index: lldb/tools/lldb-vscode/JSONUtils.cpp
===================================================================
--- lldb/tools/lldb-vscode/JSONUtils.cpp
+++ lldb/tools/lldb-vscode/JSONUtils.cpp
@@ -281,16 +281,33 @@
 //   },
 //   "required": [ "verified" ]
 // }
-llvm::json::Value CreateBreakpoint(lldb::SBBreakpointLocation &bp_loc) {
+llvm::json::Value CreateBreakpoint(lldb::SBBreakpoint &bp) {
   // Each breakpoint location is treated as a separate breakpoint for VS code.
   // They don't have the notion of a single breakpoint with multiple locations.
   llvm::json::Object object;
-  if (!bp_loc.IsValid())
+  if (!bp.IsValid())
     return llvm::json::Value(std::move(object));
 
-  object.try_emplace("verified", true);
-  const auto vs_id = MakeVSCodeBreakpointID(bp_loc);
-  object.try_emplace("id", vs_id);
+  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()) {
     auto line_entry = bp_addr.GetLineEntry();
@@ -303,15 +320,7 @@
 }
 
 void AppendBreakpoint(lldb::SBBreakpoint &bp, llvm::json::Array &breakpoints) {
-  if (!bp.IsValid())
-    return;
-  const auto num_locations = bp.GetNumLocations();
-  if (num_locations == 0)
-    return;
-  for (size_t i = 0; i < num_locations; ++i) {
-    auto bp_loc = bp.GetLocationAtIndex(i);
-    breakpoints.emplace_back(CreateBreakpoint(bp_loc));
-  }
+  breakpoints.emplace_back(CreateBreakpoint(bp));
 }
 
 // "Event": {
@@ -741,6 +750,12 @@
       EmplaceSafeString(body, "description", exc_bp->label);
     } else {
       body.try_emplace("reason", "breakpoint");
+      char desc_str[64];
+      uint64_t bp_id = thread.GetStopReasonDataAtIndex(0);
+      uint64_t bp_loc_id = thread.GetStopReasonDataAtIndex(1);
+      snprintf(desc_str, sizeof(desc_str), "breakpoint %" PRIu64 ".%" PRIu64,
+               bp_id, bp_loc_id);
+      EmplaceSafeString(body, "description", desc_str);
     }
   } break;
   case lldb::eStopReasonWatchpoint:
@@ -870,4 +885,3 @@
 }
 
 } // namespace lldb_vscode
-
Index: lldb/tools/lldb-vscode/FunctionBreakpoint.cpp
===================================================================
--- lldb/tools/lldb-vscode/FunctionBreakpoint.cpp
+++ lldb/tools/lldb-vscode/FunctionBreakpoint.cpp
@@ -18,6 +18,9 @@
   if (functionName.empty())
     return;
   bp = g_vsc.target.BreakpointCreateByName(functionName.c_str());
+  // 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())
Index: lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp
===================================================================
--- lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp
+++ lldb/tools/lldb-vscode/ExceptionBreakpoint.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ExceptionBreakpoint.h"
+#include "BreakpointBase.h"
 #include "VSCode.h"
 
 namespace lldb_vscode {
@@ -18,6 +19,9 @@
   bool throw_value = filter.find("_throw") != std::string::npos;
   bp = g_vsc.target.BreakpointCreateForException(language, catch_value,
                                                  throw_value);
+  // See comments in BreakpointBase::GetBreakpointLabel() for details of why
+  // we add a label to our breakpoints.
+  bp.AddName(BreakpointBase::GetBreakpointLabel());
 }
 
 void ExceptionBreakpoint::ClearBreakpoint() {
@@ -28,4 +32,3 @@
 }
 
 } // namespace lldb_vscode
-
Index: lldb/tools/lldb-vscode/BreakpointBase.h
===================================================================
--- lldb/tools/lldb-vscode/BreakpointBase.h
+++ lldb/tools/lldb-vscode/BreakpointBase.h
@@ -15,7 +15,7 @@
 #include <string>
 
 namespace lldb_vscode {
-  
+
 struct BreakpointBase {
 
   // An optional expression for conditional breakpoints.
@@ -36,6 +36,7 @@
   void SetCondition();
   void SetHitCondition();
   void UpdateBreakpoint(const BreakpointBase &request_bp);
+  static const char *GetBreakpointLabel();
 };
 
 } // namespace lldb_vscode
Index: lldb/tools/lldb-vscode/BreakpointBase.cpp
===================================================================
--- lldb/tools/lldb-vscode/BreakpointBase.cpp
+++ lldb/tools/lldb-vscode/BreakpointBase.cpp
@@ -18,7 +18,7 @@
 
 void BreakpointBase::SetCondition() { bp.SetCondition(condition.c_str()); }
 
-void BreakpointBase::SetHitCondition() {  
+void BreakpointBase::SetHitCondition() {
   uint64_t hitCount = 0;
   if (llvm::to_integer(hitCondition, hitCount))
     bp.SetIgnoreCount(hitCount - 1);
@@ -34,3 +34,19 @@
     SetHitCondition();
   }
 }
+
+const char *BreakpointBase::GetBreakpointLabel() {
+  // Breakpoints in LLDB can have names added to them which are kind of like
+  // labels or categories. All breakpoints that are set through the IDE UI get
+  // sent through the various VS code DAP set*Breakpoint packets, and these
+  // breakpoints will be labeled with this name so if breakpoint update events
+  // come in for breakpoints that the IDE doesn't know about, like if a
+  // breakpoint is set manually using the debugger console, we won't report any
+  // updates on them and confused the IDE. This function gets called by all of
+  // the breakpoint classes after they set breakpoints to mark a breakpoint as
+  // a UI breakpoint. We can later check a lldb::SBBreakpoint object that comes
+  // in via LLDB breakpoint changed events and check the breakpoint by calling
+  // "bool lldb::SBBreakpoint::MatchesName(const char *)" to check if a
+  // breakpoint in one of the UI breakpoints that we should report changes for.
+  return "vscode";
+}
Index: lldb/test/API/tools/lldb-vscode/breakpoint-events/main.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/breakpoint-events/main.cpp
@@ -0,0 +1,7 @@
+
+#include "foo.h"
+
+int main(int argc, char const *argv[]) {
+  int f = foo(argc);
+  return 0; // main breakpoint 1
+}
Index: lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.h
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.h
@@ -0,0 +1,2 @@
+
+int foo(int);
Index: lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.cpp
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/breakpoint-events/foo.cpp
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+static void unique_function_name() {
+  puts(__PRETTY_FUNCTION__); // foo breakpoint 2
+}
+
+int foo(int x) {
+  // foo breakpoint 1
+  unique_function_name();
+  return x+42;
+}
Index: lldb/test/API/tools/lldb-vscode/breakpoint-events/TestVSCode_breakpointEvents.py
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/breakpoint-events/TestVSCode_breakpointEvents.py
@@ -0,0 +1,121 @@
+"""
+Test lldb-vscode setBreakpoints request
+"""
+
+
+import unittest2
+import vscode
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import lldbvscode_testcase
+import os
+
+
+class TestVSCode_breakpointEvents(lldbvscode_testcase.VSCodeTestCaseBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIfWindows
+    def test_breakpoint_events(self):
+        '''
+            This test sets a breakpoint in a shared library and runs and stops
+            at the entry point of a program. When we stop at the entry point,
+            the shared library won't be loaded yet. At this point the
+            breakpoint should set itself, but not be verified because no
+            locations are resolved. We will then continue and expect to get a
+            breakpoint event that informs us that the breakpoint in the shared
+            library is "changed" and the correct line number should be
+            supplied. We also set a breakpoint using a LLDB command using the
+            "preRunCommands" when launching our program. Any breapoints set via
+            the command interpreter should not be have breakpoint events sent
+            back to VS Code as the UI isn't able to add new breakpoints to
+            their UI. Code has been added that tags breakpoints set from VS Code
+            DAP packets so we know the IDE knows about them. If VS Code is ever
+            able to register breakpoints that aren't initially set in the GUI,
+            then we will need to revise this.
+        '''
+        main_source_basename = 'main.cpp'
+        main_source_path = os.path.join(os.getcwd(), main_source_basename)
+        foo_source_basename = 'foo.cpp'
+        foo_source_path = os.path.join(os.getcwd(), foo_source_basename)
+        main_bp_line = line_number('main.cpp', 'main breakpoint 1')
+        foo_bp1_line = line_number('foo.cpp', 'foo breakpoint 1')
+        foo_bp2_line = line_number('foo.cpp', 'foo breakpoint 2')
+
+        # Visual Studio Code Debug Adaptors have no way to specify the file
+        # without launching or attaching to a process, so we must start a
+        # process in order to be able to set breakpoints.
+        program = self.getBuildArtifact("a.out")
+
+        # Set a breakpoint after creating the target by running a command line
+        # command. It will eventually resolve and cause a breakpoint changed
+        # event to be sent to lldb-vscode. We want to make sure we don't send a
+        # breakpoint any breakpoints that were set from the command line.
+        # Breakpoints that are set via the VS code DAP packets will be
+        # registered and marked with a special keyword to ensure we deliver
+        # breakpoint events for these breakpoints but not for ones that are not
+        # set via the command interpreter.
+        bp_command = 'breakpoint set --file foo.cpp --line %u' % (foo_bp2_line)
+        self.build_and_launch(program, stopOnEntry=True,
+                              preRunCommands=[bp_command])
+        main_bp_id = 0
+        foo_bp_id = 0
+        # Set breakoints and verify that they got set correctly
+        vscode_breakpoint_ids = []
+        response = self.vscode.request_setBreakpoints(main_source_path,
+                                                      [main_bp_line])
+        if response:
+            breakpoints = response['body']['breakpoints']
+            for breakpoint in breakpoints:
+                main_bp_id = breakpoint['id']
+                vscode_breakpoint_ids.append("%i" % (main_bp_id))
+                # line = breakpoint['line']
+                self.assertTrue(breakpoint['verified'],
+                                "expect main breakpoint to be verified")
+
+        response = self.vscode.request_setBreakpoints(foo_source_path,
+                                                      [foo_bp1_line])
+        if response:
+            breakpoints = response['body']['breakpoints']
+            for breakpoint in breakpoints:
+                foo_bp_id = breakpoint['id']
+                vscode_breakpoint_ids.append("%i" % (foo_bp_id))
+                self.assertFalse(breakpoint['verified'],
+                                 "expect foo breakpoint to not be verified")
+
+        # Get the stop at the entry point
+        self.continue_to_next_stop()
+
+        # We are now stopped at the entry point to the program. Shared
+        # libraries are not loaded yet (at least on macOS they aren't) and any
+        # breakpoints set in foo.cpp should not be resolved.
+        self.assertTrue(len(self.vscode.breakpoint_events) == 0,
+                        "no breakpoint events when stopped at entry point")
+
+        # Continue to the breakpoint
+        self.continue_to_breakpoints(vscode_breakpoint_ids)
+
+        # Make sure we only get an event for the breakpoint we set via a call
+        # to self.vscode.request_setBreakpoints(...), not the breakpoint
+        # we set with with a LLDB command in preRunCommands.
+        self.assertTrue(len(self.vscode.breakpoint_events) == 1,
+                        "make sure we got a breakpoint event")
+        event = self.vscode.breakpoint_events[0]
+        # Verify the details of the breakpoint changed notification.
+        body = event['body']
+        self.assertTrue(body['reason'] == 'changed',
+                "breakpoint event is says breakpoint is changed")
+        breakpoint = body['breakpoint']
+        self.assertTrue(breakpoint['verified'] == True,
+                "breakpoint event is says it is verified")
+        self.assertTrue(breakpoint['id'] == foo_bp_id,
+                "breakpoint event is for breakpoint %i" % (foo_bp_id))
+        self.assertTrue('line' in breakpoint and breakpoint['line'] > 0,
+                "breakpoint event is has a line number")
+        self.assertTrue("foo.cpp" in breakpoint['source']['path'],
+                "breakpoint event path contains foo.cpp")
+
+        output = self.get_console() # REMOVE PRIOR TO CHECKIN
+        with open("/tmp/b", "w") as f:
+            f.write(output)
Index: lldb/test/API/tools/lldb-vscode/breakpoint-events/Makefile
===================================================================
--- /dev/null
+++ lldb/test/API/tools/lldb-vscode/breakpoint-events/Makefile
@@ -0,0 +1,4 @@
+DYLIB_NAME := unlikely_name
+DYLIB_CXX_SOURCES := foo.cpp
+CXX_SOURCES := main.cpp
+include Makefile.rules
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/vscode.py
@@ -111,6 +111,7 @@
         self.exit_status = None
         self.initialize_body = None
         self.thread_stop_reasons = {}
+        self.breakpoint_events = []
         self.sequence = 1
         self.threads = None
         self.recv_thread.start()
@@ -186,7 +187,7 @@
                     self.output[category] = output
                 self.output_condition.notify()
                 self.output_condition.release()
-                # no need to add 'output' packets to our packets list
+                # no need to add 'output' event packets to our packets list
                 return keepGoing
             elif event == 'process':
                 # When a new process is attached or launched, remember the
@@ -200,6 +201,13 @@
                 self._process_stopped()
                 tid = body['threadId']
                 self.thread_stop_reasons[tid] = body
+            elif event == 'breakpoint':
+                # Breakpoint events come in when a breakpoint has locations
+                # added or removed. Keep track of them so we can look for them
+                # in tests.
+                self.breakpoint_events.append(packet)
+                # no need to add 'breakpoint' event packets to our packets list
+                return keepGoing
         elif packet_type == 'response':
             if packet['command'] == 'disconnect':
                 keepGoing = False
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-vscode/lldbvscode_testcase.py
@@ -22,8 +22,7 @@
     def set_source_breakpoints(self, source_path, lines, condition=None,
                                hitCondition=None):
         '''Sets source breakpoints and returns an array of strings containing
-           the breakpoint location IDs ("1.1", "1.2") for each breakpoint
-           that was set.
+           the breakpoint IDs ("1", "2") for each breakpoint that was set.
         '''
         response = self.vscode.request_setBreakpoints(
             source_path, lines, condition=condition, hitCondition=hitCondition)
@@ -32,17 +31,14 @@
         breakpoints = response['body']['breakpoints']
         breakpoint_ids = []
         for breakpoint in breakpoints:
-            response_id = breakpoint['id']
-            bp_id = response_id >> 32
-            bp_loc_id = response_id & 0xffffffff
-            breakpoint_ids.append('%i.%i' % (bp_id, bp_loc_id))
+            breakpoint_ids.append('%i' % (breakpoint['id']))
         return breakpoint_ids
 
     def set_function_breakpoints(self, functions, condition=None,
                                  hitCondition=None):
         '''Sets breakpoints by function name given an array of function names
-           and returns an array of strings containing the breakpoint location
-           IDs ("1.1", "1.2") for each breakpoint that was set.
+           and returns an array of strings containing the breakpoint IDs
+           ("1", "2") for each breakpoint that was set.
         '''
         response = self.vscode.request_setFunctionBreakpoints(
             functions, condition=condition, hitCondition=hitCondition)
@@ -51,18 +47,15 @@
         breakpoints = response['body']['breakpoints']
         breakpoint_ids = []
         for breakpoint in breakpoints:
-            response_id = breakpoint['id']
-            bp_id = response_id >> 32
-            bp_loc_id = response_id & 0xffffffff
-            breakpoint_ids.append('%i.%i' % (bp_id, bp_loc_id))
+            breakpoint_ids.append('%i' % (breakpoint['id']))
         return breakpoint_ids
 
     def verify_breakpoint_hit(self, breakpoint_ids):
         '''Wait for the process we are debugging to stop, and verify we hit
            any breakpoint location in the "breakpoint_ids" array.
-           "breakpoint_ids" should be a list of breakpoint location ID strings
-           (["1.1", "2.1"]). The return value from
-           self.set_source_breakpoints() can be passed to this function'''
+           "breakpoint_ids" should be a list of breakpoint ID strings
+           (["1", "2"]). The return value from self.set_source_breakpoints()
+           or self.set_function_breakpoints() can be passed to this function'''
         stopped_events = self.vscode.wait_for_stopped()
         for stopped_event in stopped_events:
             if 'body' in stopped_event:
@@ -73,14 +66,21 @@
                     continue
                 if 'description' not in body:
                     continue
-                # Description is "breakpoint 1.1", so look for any location id
-                # ("1.1") in the description field as verification that one of
-                # the breakpoint locations was hit
+                # Descriptions for breakpoints will be in the form
+                # "breakpoint 1.1", so look for any description that matches
+                # ("breakpoint 1.") in the description field as verification
+                # that one of the breakpoint locations was hit. VSCode doesn't
+                # allow breakpoints to have multiple locations, but LLDB does.
+                # So when looking at the description we just want to make sure
+                # the right breakpoint matches and not worry about the actual
+                # location.
                 description = body['description']
+                print("description: %s" % (description))
                 for breakpoint_id in breakpoint_ids:
-                    if breakpoint_id in description:
-                        return True
-        return False
+                    match_desc = 'breakpoint %s.' % (breakpoint_id)
+                    if match_desc in description:
+                        return
+        self.assertTrue(False, "breakpoint not hit")
 
     def verify_exception_breakpoint_hit(self, filter_label):
         '''Wait for the process we are debugging to stop, and verify the stop
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to