Skip to content

Conversation

@charles-zablit
Copy link
Contributor

@charles-zablit charles-zablit commented Dec 2, 2025

This patch converts the jit-loader_rtdyld_elf.test test from a Shell test to an API test.

This test is timing out in CI on Windows and the hang cannot be reproduced at desk. Converting it to an API test would allow us to instrument it better in order to trace the failure.

@llvmbot
Copy link
Member

llvmbot commented Dec 2, 2025

@llvm/pr-subscribers-platform-windows

@llvm/pr-subscribers-lldb

Author: Charles Zablit (charles-zablit)

Changes

This patch converts the jit-loader_rtdyld_elf.test test from a Shell test to an API test.

This test is timing out in CI on Windows and the hang cannot be reproduced at desk. Converting it to an API test would allow us to instrument it better in order to trace the failure.


Full diff: https://github.com/llvm/llvm-project/pull/170333.diff

4 Files Affected:

  • (added) lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/Makefile (+14)
  • (added) lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/TestJitBreakPoint.py (+53)
  • (renamed) lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/jitbp.cpp ()
  • (removed) lldb/test/Shell/Breakpoint/jit-loader_rtdyld_elf.test (-22)
diff --git a/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/Makefile b/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/Makefile
new file mode 100644
index 0000000000000..51a6bfc5fee67
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/Makefile
@@ -0,0 +1,14 @@
+CXX_SOURCES := jitbp.cpp
+
+include Makefile.rules
+
+# Build LLVM IR that lli will JIT.
+# Matches the commands from the shell test.
+jitbp.ll: jitbp.cpp
+	$(CXX) -g -S -emit-llvm --target=x86_64-unknown-unknown-elf \
+	      -o $@ $<
+
+all: jitbp.ll
+
+clean::
+	rm -f jitbp.ll
diff --git a/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/TestJitBreakPoint.py b/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/TestJitBreakPoint.py
new file mode 100644
index 0000000000000..1a4b16f03f474
--- /dev/null
+++ b/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/TestJitBreakPoint.py
@@ -0,0 +1,53 @@
+"""
+Test that pending breakpoints resolve for JITted code with mcjit and rtdyld.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestJitBreakpoint(TestBase):
+    def setUp(self):
+        TestBase.setUp(self)
+        self.ll = self.getBuildArtifact("jitbp.ll")
+
+    @skipUnlessArch("x86_64")
+    @expectedFailureAll(oslist=["windows"])
+    def test_jit_breakpoints(self):
+        self.build()
+        self.do_test("--jit-kind=mcjit")
+        self.do_test("--jit-linker=rtdyld")
+
+    def do_test(self, jit_flag: str):
+        self.dbg.SetAsync(False)
+
+        self.dbg.HandleCommand("settings set plugin.jit-loader.gdb.enable on")
+
+        lli_path = lldbutil.which("lli")
+        self.assertIsNotNone(lli_path, "Could not find lli executable")
+        target = self.dbg.CreateTarget(lli_path)
+        self.assertTrue(target.IsValid())
+
+        bp = target.BreakpointCreateByName("jitbp")
+        self.assertTrue(bp.IsValid())
+        self.assertEqual(bp.GetNumLocations(), 0, "Expected a pending breakpoint")
+
+        launch_info = target.GetLaunchInfo()
+        launch_info.SetArguments([jit_flag, self.ll], True)
+
+        error = lldb.SBError()
+        process = target.Launch(launch_info, error)
+        self.assertTrue(process.IsValid())
+        self.assertTrue(error.Success(), error.GetCString())
+
+        self.assertEqual(process.GetState(), lldb.eStateStopped)
+
+        thread = process.GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+        self.assertIn("jitbp", frame.GetFunctionName())
+
+        self.assertGreaterEqual(
+            bp.GetNumLocations(), 1, "Breakpoint must be resolved after JIT loads code"
+        )
diff --git a/lldb/test/Shell/Breakpoint/Inputs/jitbp.cpp b/lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/jitbp.cpp
similarity index 100%
rename from lldb/test/Shell/Breakpoint/Inputs/jitbp.cpp
rename to lldb/test/API/functionalities/breakpoint/jit_loader_rtdyld_elf/jitbp.cpp
diff --git a/lldb/test/Shell/Breakpoint/jit-loader_rtdyld_elf.test b/lldb/test/Shell/Breakpoint/jit-loader_rtdyld_elf.test
deleted file mode 100644
index ae9402a519494..0000000000000
--- a/lldb/test/Shell/Breakpoint/jit-loader_rtdyld_elf.test
+++ /dev/null
@@ -1,22 +0,0 @@
-# REQUIRES: target-x86_64
-# XFAIL: system-windows
-
-# RuntimeDyld can be used to link and load emitted code for both, MCJIT and Orc.
-#
-# RUN: %clangxx -g -S -emit-llvm --target=x86_64-unknown-unknown-elf \
-# RUN:          -o %t.ll %p/Inputs/jitbp.cpp
-#
-# RUN: %lldb -b -o 'settings set plugin.jit-loader.gdb.enable on' -o 'b jitbp' \
-# RUN:          -o 'run --jit-kind=mcjit %t.ll' lli | FileCheck %s
-#
-# RUN: %lldb -b -o 'settings set plugin.jit-loader.gdb.enable on' -o 'b jitbp' \
-# RUN:          -o 'run --jit-linker=rtdyld %t.ll' lli | FileCheck %s
-
-# CHECK: Breakpoint 1: no locations (pending).
-# CHECK: (lldb) run {{.*}}
-# CHECK: Process {{.*}} launched: {{.*}}
-# CHECK: Process {{.*}} stopped
-# CHECK: JIT(0x{{.*}})`jitbp() at jitbp.cpp:1:15
-# CHECK: -> 1    int jitbp() { return 0; }
-# CHECK:                       ^
-# CHECK:    2    int main() { return jitbp(); }

@github-actions
Copy link

github-actions bot commented Dec 2, 2025

🐧 Linux x64 Test Results

  • 33215 tests passed
  • 507 tests skipped

✅ The build succeeded and all tests passed.

@charles-zablit charles-zablit force-pushed the charles-zablit/lldb/convert-shell-test-to-api-test branch from 77c1872 to 29ee61c Compare December 3, 2025 13:06
@github-actions
Copy link

github-actions bot commented Dec 3, 2025

✅ With the latest revision this PR passed the Python code formatter.

@charles-zablit charles-zablit force-pushed the charles-zablit/lldb/convert-shell-test-to-api-test branch 2 times, most recently from c83a241 to 344dfcc Compare December 3, 2025 13:31
@charles-zablit charles-zablit force-pushed the charles-zablit/lldb/convert-shell-test-to-api-test branch from 344dfcc to 07ecfc8 Compare December 3, 2025 14:47
TestBase.setUp(self)
self.ll = self.getBuildArtifact("jitbp.ll")

@skipUnlessArch("x86_64")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll also need a decorator that checks that the compiler is clang (and not, e.g., gcc) since we use the -emit-llvm flag.

class TestJitBreakpoint(TestBase):
def setUp(self):
TestBase.setUp(self)
self.ll = self.getBuildArtifact("jitbp.ll")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you make this a local variable below, you can remove the entire setUp function.

from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *

import shutil
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe sinking this into the function below makes test discovery marginally faster?

error = lldb.SBError()
process = target.Launch(launch_info, error)
self.assertTrue(process.IsValid())
self.assertTrue(error.Success(), error.GetCString())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a good reason why we can't use any of the lldbutil helper functions that launch a program and check for breakpoints here?


lldb_dir = os.path.dirname(lldbtest_config.lldbExec)
lli_path = shutil.which("lli", path=lldb_dir)
self.assertTrue(os.path.exists(lli_path), "lli not found")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to fail in out-of-tree builds?
Do we have a way to get the LLVM BINDIR here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants