diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index bd0bfb06ec..38bd3301cf 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -4390,6 +4390,28 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests):
         self.assertIn('rust-lang.rust-analyzer', extensions['recommendations'])
         self.assertIn('ms-vscode.cpptools', extensions['recommendations'])
 
+    def test_code_cargo_lldb_configuration(self):
+        recipe_name = "cargo-example"
+        self._check_workspace()
+        self._write_bb_config()
+        tempdir = self._devtool_ide_sdk_recipe(recipe_name, "Cargo.toml", None)
+        runCmd('devtool ide-sdk %s oe-selftest-image --ide=code '
+               '--target root@localhost --no-host-check' % recipe_name,
+               output_log=self._cmd_logger)
+
+        with open(os.path.join(tempdir, '.vscode', 'extensions.json')) as extensions_file:
+            extensions = json.load(extensions_file)
+        with open(os.path.join(tempdir, '.vscode', 'launch.json')) as launch_file:
+            launch = json.load(launch_file)['configurations'][0]
+        with open(os.path.join(tempdir, '.vscode', 'tasks.json')) as tasks_file:
+            tasks = json.load(tasks_file)['tasks']
+
+        self.assertIn('vadimcn.vscode-lldb', extensions['recommendations'])
+        self.assertEqual(launch['type'], 'lldb')
+        server_task = next(
+            task for task in tasks if task['label'] == launch['preLaunchTask'])
+        self.assertIn('lldb-server platform --server', server_task['args'][-1])
+
     def test_code_cargo_build_task(self):
         recipe_name = "cargo-example"
         self._check_workspace()
diff --git a/scripts/lib/devtool/ide_plugins/ide_code.py b/scripts/lib/devtool/ide_plugins/ide_code.py
index 089016c639..e18c6a703d 100644
--- a/scripts/lib/devtool/ide_plugins/ide_code.py
+++ b/scripts/lib/devtool/ide_plugins/ide_code.py
@@ -320,6 +320,7 @@ class IdeVSCode(IdeBase):
             recommendations += [
                 "rust-lang.rust-analyzer",
                 "ms-vscode.cpptools",
+                "vadimcn.vscode-lldb"
             ]
         # clangd (matched to the recipe's real cross compiler via
         # compile_commands.json) replaces cpptools as the IntelliSense provider
@@ -1023,7 +1024,7 @@ class IdeVSCode(IdeBase):
         self.vscode_extensions(modified_recipe)
         self.vscode_c_cpp_properties(modified_recipe, image_recipe)
         if args.target:
-            if modified_recipe.toolchain == 'clang':
+            if modified_recipe.uses_lldb:
                 self.initialize_cross_debug_configs(
                     image_recipe, modified_recipe, LldbServerConfigVSCode)
             else:
diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py
index 21229f5970..44429e80b0 100755
--- a/scripts/lib/devtool/ide_sdk.py
+++ b/scripts/lib/devtool/ide_sdk.py
@@ -433,11 +433,11 @@ class RecipeImage:
         resulting bbappend content actually differs from what was on disk
         when initialize() ran, False if it is left exactly as it was.
         """
-        wants_gdbserver = any(
-            r.wants_gdbserver and r.toolchain != 'clang'
-            for r in recipes_modified)
         wants_lldb_server = any(
-            r.wants_gdbserver and r.toolchain == 'clang'
+            r.wants_gdbserver and r.uses_lldb
+            for r in recipes_modified)
+        wants_gdbserver = any(
+            r.wants_gdbserver and not r.uses_lldb
             for r in recipes_modified)
 
         # Only add what the base configuration (e.g. local.conf) does not
@@ -1150,6 +1150,14 @@ class RecipeModified:
         self.recipe_id = self.bpn + "-" + self.package_arch
         self.recipe_id_pretty = self.bpn + ": " + self.package_arch
 
+    @property
+    def uses_lldb(self):
+        # VS Code's Rust debugging guide recommends CodeLLDB:
+        # https://code.visualstudio.com/docs/languages/rust#_debugging
+        # ide-sdk supports Rust debugging only through CodeLLDB; cppdbg/GDB
+        # does not resolve Rust function breakpoints from the VS Code UI.
+        return self.toolchain == 'clang' or self.build_tool is BuildTool.CARGO
+
     @property
     def cargo_config_path(self):
         return os.path.join(self.ide_sdk_dir, 'cargo-config.toml')
@@ -2032,20 +2040,21 @@ def ide_setup(args, config, basepath, workspace):
                 bootstrap_tasks += recipe_modified.bootstrap_tasks
                 recipes_modified.append(recipe_modified)
 
-                # Key by (arch, toolchain) so recipes with different toolchains
-                # targeting the same arch each get the right debugger.
+                # Key by (arch, debugger) so recipes sharing an architecture
+                # but using different debugger backends each get the right one.
+                debugger = 'lldb' if recipe_modified.uses_lldb else 'gdb'
                 debugger_key = (recipe_modified.target_arch,
-                                recipe_modified.toolchain or '')
+                                debugger)
                 if debugger_key not in debuggers:
                     target_device = TargetDevice(args)
-                    if recipe_modified.toolchain == 'clang':
-                        debugger = RecipeLldbNative(args, target_device)
+                    if recipe_modified.uses_lldb:
+                        debugger_config = RecipeLldbNative(args, target_device)
                     else:
-                        debugger = RecipeGdbCross(
+                        debugger_config = RecipeGdbCross(
                             args, recipe_modified.target_arch, target_device)
-                    debugger.initialize(config, workspace, tinfoil)
-                    bootstrap_tasks += debugger.bootstrap_tasks
-                    debuggers[debugger_key] = debugger
+                    debugger_config.initialize(config, workspace, tinfoil)
+                    bootstrap_tasks += debugger_config.bootstrap_tasks
+                    debuggers[debugger_key] = debugger_config
                 recipe_modified.debugger_cross = debuggers[debugger_key]
 
     finally:
