[Lldb-commits] [lldb] 9a2e9c5 - Add tests for the other variants of BreakpointCreateBySourceRegex.

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 18 10:59:12 PDT 2021


Author: Jim Ingham
Date: 2021-10-18T10:59:04-07:00
New Revision: 9a2e9c5db692a010dd87a36907ba9d86bc54ac53

URL: https://github.com/llvm/llvm-project/commit/9a2e9c5db692a010dd87a36907ba9d86bc54ac53
DIFF: https://github.com/llvm/llvm-project/commit/9a2e9c5db692a010dd87a36907ba9d86bc54ac53.diff

LOG: Add tests for the other variants of BreakpointCreateBySourceRegex.

I added some tests for the case where the breakpoints take immediately
to the extant test case, and made a new test case for when the source
regex breakpoint will be set in a dlopen-ed library.

I also noticed when doing this that "lldbutil.run_to_source_breakpoint
can't handle the case where the breakpoint will be in a dlopen-ed
library, since it requires the breakpoint to have at least 1 location
before run.  I fixed that by adding a parameter to say whether a
before run location is expected.

Differential Revision: https://reviews.llvm.org/D111920

Added: 
    lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/Makefile
    lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/TestBreakInLoadedDylib.py
    lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/b.cpp
    lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/main.cpp

Modified: 
    lldb/packages/Python/lldbsuite/test/lldbutil.py
    lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
    lldb/test/API/functionalities/breakpoint/breakpoint_command/bktptcmd.py

Removed: 
    


################################################################################
diff  --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 20a6d28274b3d..2ab372d82b72d 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -953,7 +953,8 @@ def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
                              bkpt_module = None,
                              in_cwd = True,
                              only_one_thread = True,
-                             extra_images = None):
+                             extra_images = None,
+                             has_locations_before_run = True):
     """Start up a target, using exe_name as the executable, and run it to
        a breakpoint set by source regex bkpt_pattern.
 
@@ -964,9 +965,10 @@ def run_to_source_breakpoint(test, bkpt_pattern, source_spec,
     # Set the breakpoints
     breakpoint = target.BreakpointCreateBySourceRegex(
             bkpt_pattern, source_spec, bkpt_module)
-    test.assertTrue(breakpoint.GetNumLocations() > 0,
-        'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
-        %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
+    if has_locations_before_run:
+        test.assertTrue(breakpoint.GetNumLocations() > 0,
+                        'No locations found for source breakpoint: "%s", file: "%s", dir: "%s"'
+                        %(bkpt_pattern, source_spec.GetFilename(), source_spec.GetDirectory()))
     return run_to_breakpoint_do_run(test, target, breakpoint, launch_info,
                                     only_one_thread, extra_images)
 

diff  --git a/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/Makefile b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/Makefile
new file mode 100644
index 0000000000000..0f3fb37bdadf3
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/Makefile
@@ -0,0 +1,9 @@
+CXX_SOURCES := main.cpp
+USE_LIBDL := 1
+
+lib_b:
+	$(MAKE) -f $(MAKEFILE_RULES) \
+		DYLIB_ONLY=YES DYLIB_CXX_SOURCES=b.cpp DYLIB_NAME=lib_b
+all: lib_b
+
+include Makefile.rules

diff  --git a/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/TestBreakInLoadedDylib.py b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/TestBreakInLoadedDylib.py
new file mode 100644
index 0000000000000..88fcfc4a3353c
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/TestBreakInLoadedDylib.py
@@ -0,0 +1,62 @@
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestBreakInLoadedDylib(TestBase):
+    """ Test that we can set a source regex breakpoint that will take in
+    a dlopened library that hasn't loaded when we set the breakpoint."""
+
+    mydir = TestBase.compute_mydir(__file__)
+    NO_DEBUG_INFO_TESTCASE = True
+
+    @skipIfRemote
+    def common_setup(self):
+        self.build()
+        ctx = self.platformContext
+        self.main_spec = lldb.SBFileSpec("main.cpp")
+        self.b_spec = lldb.SBFileSpec("b.cpp")
+        self.lib_shortname = 'lib_b'
+        self.lib_fullname = ctx.shlib_prefix + self.lib_shortname + '.' + ctx.shlib_extension
+        self.lib_spec = lldb.SBFileSpec(self.lib_fullname)
+        
+    def test_break_in_dlopen_dylib_using_lldbutils(self):
+        self.common_setup()
+        lldbutil.run_to_source_breakpoint(self, "Break here in dylib", self.b_spec,
+                                          bkpt_module=self.lib_fullname,
+                                          extra_images = [self.lib_shortname],
+                                          has_locations_before_run = False)
+
+    @skipIfRemote
+    def test_break_in_dlopen_dylib_using_target(self):
+        self.common_setup()
+
+        target, process, _, _ = lldbutil.run_to_source_breakpoint(self, "Break here before we dlopen", self.main_spec,
+                                                            extra_images = [self.lib_shortname])
+        
+        # Now set some breakpoints that won't take till the library is loaded:
+        # This one is currently how lldbutils does it but test here in case that changes:
+        bkpt1 = target.BreakpointCreateBySourceRegex("Break here in dylib", self.b_spec, self.lib_fullname)
+        self.assertEqual(bkpt1.GetNumLocations(), 0, "Library isn't loaded yet.")
+        # Try the file list API as well.  Put in some bogus entries too, to make sure those
+        # don't trip us up:
+                                               
+        files_list = lldb.SBFileSpecList()
+        files_list.Append(self.b_spec)
+        files_list.Append(self.main_spec)
+        files_list.Append(lldb.SBFileSpec("I_bet_nobody_has_this_file.cpp"))
+
+        modules_list = lldb.SBFileSpecList()
+        modules_list.Append(self.lib_spec)
+        modules_list.Append(lldb.SBFileSpec("libI_bet_not_this_one_either.dylib"))
+
+        bkpt2 = target.BreakpointCreateBySourceRegex("Break here in dylib", modules_list, files_list)
+        self.assertEqual(bkpt2.GetNumLocations(), 0, "Library isn't loaded yet")
+
+        lldbutil.continue_to_breakpoint(process, bkpt1)
+        self.assertEqual(bkpt1.GetHitCount(), 1, "Hit breakpoint 1")
+        self.assertEqual(bkpt2.GetHitCount(), 1, "Hit breakpoint 2")
+
+        
+
+        

diff  --git a/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/b.cpp b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/b.cpp
new file mode 100644
index 0000000000000..5bfb3104910ba
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/b.cpp
@@ -0,0 +1,3 @@
+extern "C" int LLDB_DYLIB_EXPORT b_function() {
+  return 500; // Break here in dylib
+}

diff  --git a/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/main.cpp b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/main.cpp
new file mode 100644
index 0000000000000..3b00c6eb250f4
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/break_in_loaded_dylib/main.cpp
@@ -0,0 +1,15 @@
+#include "dylib.h"
+#include <cassert>
+#include <cstdio>
+#include <thread>
+#include <chrono>
+
+int main(int argc, char* argv[]) {
+  // Break here before we dlopen the 'liblib_b.so' shared library.
+  void* dylib_handle = dylib_open("lib_b"); 
+  assert(dylib_handle && "dlopen failed");
+  void (*func_handle)() = (void (*)()) dylib_get_symbol(dylib_handle, "b_function");
+  assert(func_handle && "dlsym failed");
+  func_handle();
+  return 0;
+}

diff  --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
index b5ff89a6fd060..35e19c888355f 100644
--- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
+++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommandsFromPython.py
@@ -54,6 +54,17 @@ def do_set_python_command_from_python(self):
             "Set break point at this line.", self.main_source_spec)
         self.assertTrue(fancier_bkpt, VALID_BREAKPOINT)
 
+        # Also test the list version of this:
+        file_list = lldb.SBFileSpecList()
+        file_list.Append(self.main_source_spec)
+        module_list = lldb.SBFileSpecList()
+        module_list.Append(self.target.GetExecutable())
+        
+        list_bkpt = self.target.BreakpointCreateBySourceRegex(
+            "Set break point at this line.", module_list, file_list)
+        self.assertTrue(list_bkpt, VALID_BREAKPOINT)
+
+        
         not_so_fancy_bkpt = self.target.BreakpointCreateBySourceRegex(
             "Set break point at this line.", self.main_source_spec)
         self.assertTrue(not_so_fancy_bkpt, VALID_BREAKPOINT)
@@ -114,13 +125,21 @@ def do_set_python_command_from_python(self):
         error = not_so_fancy_bkpt.SetScriptCallbackFunction("bktptcmd.empty_extra_args", empty_args)
         self.assertTrue(error.Success(), "Failed to add callback %s"%(error.GetCString()))
 
+        # Do list breakpoint like fancy:
+        stream.Clear()
+        stream.Print('{"side_effect" : "I come from list input"}')
+        extra_args.SetFromJSON(stream)
+        error = list_bkpt.SetScriptCallbackFunction("bktptcmd.a_list_function", extra_args)
+        self.assertTrue(error.Success(), "Failed to add callback %s"%(error.GetCString()))
+        
         # Clear out canary variables
         side_effect.bktptcmd = None
         side_effect.callback = None
         side_effect.fancy    = None
         side_effect.fancier  = None
         side_effect.not_so_fancy = None
-
+        side_effect.a_list_function = None
+        
         # Now launch the process, and do not stop at entry point.
         self.process = self.target.LaunchSimple(
             None, None, self.get_process_working_directory())
@@ -133,11 +152,13 @@ def do_set_python_command_from_python(self):
         self.assertEquals(len(threads), 1, "Stopped at inner breakpoint.")
         self.thread = threads[0]
 
+        print("* Num Locations: {0} ; Hit Count {1}".format(list_bkpt.GetNumLocations(), list_bkpt.GetHitCount()))
         self.assertEquals("callback was here", side_effect.callback)
         self.assertEquals("function was here", side_effect.bktptcmd)
         self.assertEquals("I am fancy", side_effect.fancy)
         self.assertEquals("I am fancier", side_effect.fancier)
         self.assertEquals("Not so fancy", side_effect.not_so_fancy)
+        self.assertEquals("I come from list input", side_effect.from_list)
 
     def do_bad_args_to_python_command(self):
         error = lldb.SBError()

diff  --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/bktptcmd.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/bktptcmd.py
index e839de57fb7a5..d635ae45c7c80 100644
--- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/bktptcmd.py
+++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/bktptcmd.py
@@ -17,6 +17,12 @@ def a_third_function(frame, bp_loc, extra_args, dict):
     se_string = se_value.GetStringValue(100)
     side_effect.fancier = se_string
 
+def a_list_function(frame, bp_loc, extra_args, dict):
+    se_value = extra_args.GetValueForKey("side_effect")
+    se_string = se_value.GetStringValue(100)
+    side_effect.from_list = se_string
+
+    
 def empty_extra_args(frame, bp_loc, extra_args, dict):
     if extra_args.IsValid():
         side_effect.not_so_fancy = "Extra args should not be valid"


        


More information about the lldb-commits mailing list