diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py
index ef13eaa09a..3b80d6a4a8 100644
--- a/meta/lib/oeqa/selftest/cases/devtool.py
+++ b/meta/lib/oeqa/selftest/cases/devtool.py
@@ -4363,6 +4363,41 @@ class DevtoolIdeSdkRustTests(DevtoolIdeSdkTests):
         self.assertNotIn('rust-analyzer.cargo.extraEnv', settings)
         self.assertIn('rust-lang.rust-analyzer', extensions['recommendations'])
 
+    def test_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 --ide=none '
+               '--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')
+
+        scripts_dir = self._workspace_scripts_dir(recipe_name)
+        scripts = os.listdir(scripts_dir)
+        self.assertTrue(any(name.startswith('lldb_server_') for name in scripts))
+        self.assertFalse(any(name.startswith('gdbserver_') for name in scripts))
+        self._verify_install_script_code(tempdir, recipe_name)
+        cargo_config = os.path.join(
+            self.workspacedir, 'ide-sdk', recipe_name, 'cargo-config.toml')
+        self.assertExists(
+            cargo_config, 'Cargo config was not generated for --ide=none')
+        target_dbgsrc_dir = get_bb_var('TARGET_DBGSRC_DIR', recipe_name)
+        self.assertEqual(
+            launch['sourceMap'][target_dbgsrc_dir], os.path.realpath(tempdir))
+        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 cb54948ce1..a7bb3221e0 100644
--- a/scripts/lib/devtool/ide_plugins/ide_code.py
+++ b/scripts/lib/devtool/ide_plugins/ide_code.py
@@ -315,7 +315,10 @@ class IdeVSCode(IdeBase):
     def vscode_extensions(self, modified_recipe):
         recommendations = []
         if modified_recipe.build_tool is BuildTool.CARGO:
-            recommendations.append("rust-lang.rust-analyzer")
+            recommendations += [
+                "rust-lang.rust-analyzer",
+                "vadimcn.vscode-lldb"
+            ]
         # clangd (matched to the recipe's real cross compiler via
         # compile_commands.json) replaces cpptools as the IntelliSense provider
         # when selected via IDE_SDK_INTELLISENSE (defaults to clangd for the
@@ -1003,7 +1006,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_plugins/ide_none.py b/scripts/lib/devtool/ide_plugins/ide_none.py
index eba576bfdb..d2f66ade8d 100644
--- a/scripts/lib/devtool/ide_plugins/ide_none.py
+++ b/scripts/lib/devtool/ide_plugins/ide_none.py
@@ -306,13 +306,13 @@ class IdeNone(IdeBase):
 
         - Execute the do_install task
         - Execute devtool deploy-target
-        - Generate a gdbinit file per executable
+        - Generate debugger configuration for each executable
         - Generate the oe-scripts sym-link
         """
         script_path = modified_recipe.gen_install_deploy_script(args, image_recipe.nfs_deploy_dir)
         logger.info("Created: %s" % script_path)
 
-        if modified_recipe.toolchain == 'clang':
+        if modified_recipe.uses_lldb:
             self.initialize_cross_debug_configs(
                 image_recipe, modified_recipe, LldbServerConfigNone)
         else:
diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py
index 98e39703e7..0ce2a7780e 100755
--- a/scripts/lib/devtool/ide_sdk.py
+++ b/scripts/lib/devtool/ide_sdk.py
@@ -406,11 +406,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
@@ -1158,6 +1158,16 @@ 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 because
+        # GDB does not fully understand Rust's LLVM-generated function layout
+        # and name mangling.
+        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')
@@ -2048,20 +2058,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:
