From: Adrian Freihofer <[email protected]> Setting GDB's sysroot to the recipe's D (image/) directory is often not enough: D only contains "usr/lib", but the target reports merged-usr paths like "/lib/libfoo.so.0", so the sysroot lookup fails and GDB falls back to solib-search-path, resolving the library from the full image's rootfs-dbg/rootfs instead. Recipes that install libraries outside the standard libdir hit this on every rebuild, silently debugging with stale symbols from the last full image build. Confirmed against gdb-17.2 gdb/solib.c (solib_find_1()) by capturing the GDB MI trace of an attach session and cross-checking against that code.
Fix: add RecipeModified._find_elf_dirs(), which walks D and returns every directory containing an ELF file, and prepend those directories to additionalSOLibSearchPath, ahead of the rootfs-dbg/rootfs entries, in every generated launch config. Also extend the launch.json oe-selftest assertions to check that the first additionalSOLibSearchPath entry is the recipe's own image (D) directory, not rootfs-dbg. Signed-off-by: Adrian Freihofer <[email protected]> --- meta/lib/oeqa/selftest/cases/devtool.py | 6 ++++ scripts/lib/devtool/ide_sdk.py | 42 ++++++++++++++++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/meta/lib/oeqa/selftest/cases/devtool.py b/meta/lib/oeqa/selftest/cases/devtool.py index 8d68809552..7d7d228b22 100644 --- a/meta/lib/oeqa/selftest/cases/devtool.py +++ b/meta/lib/oeqa/selftest/cases/devtool.py @@ -3733,6 +3733,12 @@ class DevtoolIdeSdkGccTests(DevtoolIdeSdkTests): so_paths = config.get("additionalSOLibSearchPath", []) self.assertIn("/.debug", so_paths, f"Configuration '{config['name']}' should include debug symbol paths") self.assertIn("/rootfs-dbg/", so_paths, f"Configuration '{config['name']}' should include rootfs-dbg paths") + # The recipe's own D/usr/lib must come first, so GDB's solib-search-path + # basename fallback prefers freshly rebuilt libraries over a stale + # rootfs-dbg/rootfs copy from the last full image build. + first_so_path = so_paths.split(":", 1)[0] + self.assertIn("/image/", first_so_path, f"Configuration '{config['name']}' first SO lib search path should be the recipe's own image dir: {first_so_path}") + self.assertNotIn("rootfs-dbg", first_so_path, f"Configuration '{config['name']}' first SO lib search path should not be rootfs-dbg: {first_so_path}") # Verify source file mappings source_map = config.get("sourceFileMap", {}) diff --git a/scripts/lib/devtool/ide_sdk.py b/scripts/lib/devtool/ide_sdk.py index 8090117959..c2e7a34b7a 100755 --- a/scripts/lib/devtool/ide_sdk.py +++ b/scripts/lib/devtool/ide_sdk.py @@ -939,27 +939,53 @@ class RecipeModified: return True return False + @staticmethod + def _find_elf_dirs(root): + """Return every directory under root that contains an ELF file""" + elf_dirs = [] + for dirpath, _dirnames, filenames in os.walk(root): + for filename in filenames: + file_path = os.path.join(dirpath, filename) + if os.path.islink(file_path): + continue + try: + with open(file_path, 'rb') as elf_file: + is_elf = elf_file.read(4) == b'\x7fELF' + except OSError: + continue + if is_elf: + elf_dirs.append(dirpath) + break + return elf_dirs + def solib_search_path(self, image): - """Search for debug symbols in the rootfs and rootfs-dbg + """Search for debug symbols The debug symbols of shared libraries which are provided by other packages are grabbed from the -dbg packages in the rootfs-dbg. - But most cross debugging tools like gdb, perf, and systemtap need to find executable/library first and through it debuglink note find corresponding symbols file. Therefore the library paths from the rootfs are added as well. Note: For the devtool modified recipe compiled from the IDE, the debug - symbols are taken from the unstripped binaries in the image folder. - Also, devtool deploy-target takes the files from the image folder. - debug symbols in the image folder refer to the corresponding source files - with absolute paths of the build machine. Debug symbols found in the - rootfs-dbg are relocated and contain paths which refer to the source files - installed on the target device e.g. /usr/src/... + symbols are taken from the unstripped binaries in the image=${D} directory. + Also, devtool deploy-target takes the files from the image directory. + This recipe's own D is searched (for ELF files, wherever they are + installed) and listed first, ahead of rootfs-dbg/rootfs, so that this + recipe's freshly rebuilt libraries take precedence over any stale copy + from the last full image build. "set sysroot D" alone cannot achieve + this: the target reports merged-usr paths (e.g. "/lib/libfoo.so.0"), but + D only contains "usr/lib" (raw do_install output, no top-level "lib" + symlink), so GDB's sysroot-prefixed lookup always fails open() and it + falls back to solib-search-path's basename matching instead. This also + does not work for libraries which are not installed into the standard + libdirs. """ base_libdir = self.base_libdir.lstrip('/') libdir = self.libdir.lstrip('/') so_paths = [ + # This recipe's own rebuilt libraries/plugins, ahead of rootfs-dbg/rootfs. + *self._find_elf_dirs(self.d), # debug symbols for package_debug_split_style: debug-with-srcpkg or .debug os.path.join(image.rootfs_dbg, base_libdir, ".debug"), os.path.join(image.rootfs_dbg, libdir, ".debug"), -- 2.55.0
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#244724): https://lists.openembedded.org/g/openembedded-core/message/244724 Mute This Topic: https://lists.openembedded.org/mt/121005259/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
