LD_DEBUG环境变量 (2012)

Hacker News Top 工具

摘要

解释如何在Linux上使用LD_DEBUG环境变量来调试共享库加载问题,包含示例和相关工具。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/06/10 00:22

# LD_DEBUG 环境变量 来源:https://bnikolic.co.uk/blog/linux-ld-debug.html *2012年4月23日首次发布,2019年9月10日更新(添加问题排查工具链接),2019年10月18日更新(迁移至 Jekyll),2023年4月3日更新(添加其他工具链接)* 开发使用大量共享(动态)加载库的大型系统时,有时会遇到一些令人沮丧且难以诊断的错误。这些错误通常源于系统上存在多个不同版本的库,而加载的是“错误”版本,而非开发者想要的版本。 > ***注意***您可能还会发现我的在线工具(用于诊断 Linux 链接器问题)很有用:http://linkdemo.carabinerweb.s3-website-us-east-1.amazonaws.com/ 它以专家系统实现。撰写此文时正在扩展,但可能已经有用。 过去,我经常使用 `strace` 命令(man strace (http://linux.die.net/man/1/strace))来有效调试这些问题,通过检查哪些库被访问。然而,有一种更高效但可能不太为人所知的调试共享库加载问题的方法:`LD_DEBUG` 环境变量。 如果设置了 `LD_DEBUG` 变量,Linux 动态链接器将输出调试信息,这些信息可以非常快速地解决大多数加载问题。要查看可用选项,只需用 `help` 值运行任何程序,例如: `` LD_DEBUG=help cat Valid options for the LD_DEBUG environment variable are: libs display library search paths reloc display relocation processing files display progress for input file symbols display symbol table processing bindings display information about symbol binding versions display version dependencies all all previous options combined statistics display relocation statistics unused determined unused DSOs help display this help message and exit To direct the debugging output into a file instead of standard output a filename can be specified using the LD_DEBUG_OUTPUT environment variable. `` > ***注意***还有许多其它有用的工具可以处理链接问题:1. `strace` (https://linux.die.net/man/1/strace) 程序提供所有系统调用的洞察,包括搜索、打开动态库 2. `ldd` (https://linux.die.net/man/1/ldd) 程序解析动态库依赖 3. `objdump -x YOURFILE | grep NEEDED` 命令列出程序或库中需要哪些其它库的记录 4. `patchelf` (https://github.com/NixOS/patchelf) 程序可以轻松更改 ELF 可执行文件的 `rpath`,从而改变内建搜索顺序 5. `LD_PRELOAD` (https://bnikolic.co.uk/blog/hpc-ldpreload-speedoptimisation) 环境变量可以轻松替换动态库。需要进一步帮助?凭借 20 多年的经验,我们独具优势——请联系我们:[email protected] > ***注意***此变量仅 Linux 可用。在 MS Windows 上,可以通过启用 *“Show Loader Snaps”* (https://abitofscotland.wordpress.com/2019/12/20/dll-load-failure/) 来获取类似信息,使用 `gflags.exe` 程序启用该功能,然后使用 `windbg` 查看日志。例如:1. 安装包含 `gflags` 和 `windbg` 的 Windows SDK:`winget install Microsoft.WindowsSDK.10.0.19041` (或从 Microsoft 网站下载 (https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools)) 2. 为可执行文件启用 ShowLoaderSnaps。例如,在 Powershell 中为 `notepad.exe` 启用:`&"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe" /i notepad.exe +sls` 3. 在 WinDbg 应用下执行 `notepad.exe`。将显示详细的 DLL 加载日志 以下是我笔记本电脑上的运行示例: `` LD_DEBUG=all cat 28504: 28504: file=libc.so.6 [0]; needed by cat [0] 28504: find library=libc.so.6 [0]; searching 28504: search path=/home/bnikolic/s/lib/tls/x86_64:/home/bnikolic/s/lib/tls:/home/bnikolic/s/lib/x86_64:/home/bnikolic/s/lib:tls/x86_64:tls:x86_64::/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/tls/x86_64:/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/tls:/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/x86_64:/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib (LD_LIBRARY_PATH) 28504: trying file=/home/bnikolic/s/lib/tls/x86_64/libc.so.6 28504: trying file=/home/bnikolic/s/lib/tls/libc.so.6 28504: trying file=/home/bnikolic/s/lib/x86_64/libc.so.6 28504: trying file=/home/bnikolic/s/lib/libc.so.6 28504: trying file=tls/x86_64/libc.so.6 28504: trying file=tls/libc.so.6 28504: trying file=x86_64/libc.so.6 28504: trying file=libc.so.6 28504: trying file=/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/tls/x86_64/libc.so.6 28504: trying file=/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/tls/libc.so.6 28504: trying file=/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/x86_64/libc.so.6 28504: trying file=/home/bnikolic/d/p/R-2.14.1bin/lib/R/lib/libc.so.6 28504: search cache=/etc/ld.so.cache 28504: trying file=/lib/x86_64-linux-gnu/libc.so.6 28504: 28504: file=libc.so.6 [0]; generating link map 28504: dynamic: 0x00007fc38e525b40 base: 0x00007fc38e18c000 size: 0x00000000003a0368 28504: entry: 0x00007fc38e1ad420 phdr: 0x00007fc38e18c040 phnum: 10 28504: 28504: checking for version `GLIBC_2.4' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file cat [0] 28504: checking for version `GLIBC_2.3' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file cat [0] 28504: checking for version `GLIBC_2.3.4' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file cat [0] 28504: checking for version `GLIBC_2.2.5' in file /lib/x86_64-linux-gnu/libc.so.6 [0] required by file cat [0] 28504: checking for version `GLIBC_2.3' in file /lib64/ld-linux-x86-64.so.2 [0] required by file /lib/x86_64-linux-gnu/libc.so.6 [0] 28504: checking for version `GLIBC_PRIVATE' in file /lib64/ld-linux-x86-64.so.2 [0] required by file /lib/x86_64-linux-gnu/libc.so.6 [0] 28504: 28504: relocation processing: /lib/x86_64-linux-gnu/libc.so.6 (lazy) 28504: symbol=_res; lookup in file=cat [0] 28504: symbol=_res; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `_res' [GLIBC_2.2.5] 28504: symbol=_IO_file_close; lookup in file=cat [0] 28504: symbol=_IO_file_close; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `_IO_file_close' [GLIBC_2.2.5] 28504: symbol=stderr; lookup in file=cat [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to cat [0]: normal symbol `stderr' [GLIBC_2.2.5] 28504: symbol=error_one_per_line; lookup in file=cat [0] 28504: symbol=error_one_per_line; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `error_one_per_line' [GLIBC_2.2.5] 28504: symbol=__malloc_initialize_hook; lookup in file=cat [0] 28504: symbol=__malloc_initialize_hook; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__malloc_initialize_hook' [GLIBC_2.2.5] 28504: symbol=__morecore; lookup in file=cat [0] 28504: symbol=__morecore; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__morecore' [GLIBC_2.2.5] 28504: symbol=__key_encryptsession_pk_LOCAL; lookup in file=cat [0] 28504: symbol=__key_encryptsession_pk_LOCAL; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__key_encryptsession_pk_LOCAL' [GLIBC_2.2.5] 28504: symbol=__progname_full; lookup in file=cat [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to cat [0]: normal symbol `__progname_full' [GLIBC_2.2.5] 28504: symbol=__ctype32_tolower; lookup in file=cat [0] 28504: symbol=__ctype32_tolower; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__ctype32_tolower' [GLIBC_2.2.5] 28504: symbol=__key_gendes_LOCAL; lookup in file=cat [0] 28504: symbol=__key_gendes_LOCAL; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__key_gendes_LOCAL' [GLIBC_2.2.5] 28504: symbol=_environ; lookup in file=cat [0] 28504: symbol=_environ; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `_environ' [GLIBC_2.2.5] 28504: symbol=_rtld_global; lookup in file=cat [0] 28504: symbol=_rtld_global; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: symbol=_rtld_global; lookup in file=/lib64/ld-linux-x86-64.so.2 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol `_rtld_global' [GLIBC_PRIVATE] 28504: symbol=__progname; lookup in file=cat [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to cat [0]: normal symbol `__progname' [GLIBC_2.2.5] 28504: symbol=argp_err_exit_status; lookup in file=cat [0] 28504: symbol=argp_err_exit_status; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `argp_err_exit_status' [GLIBC_2.2.5] 28504: symbol=mallwatch; lookup in file=cat [0] 28504: symbol=mallwatch; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `mallwatch' [GLIBC_2.2.5] 28504: symbol=__rcmd_errstr; lookup in file=cat [0] 28504: symbol=__rcmd_errstr; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__rcmd_errstr' [GLIBC_2.2.5] 28504: symbol=svcauthdes_stats; lookup in file=cat [0] 28504: symbol=svcauthdes_stats; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `svcauthdes_stats' [GLIBC_2.2.5] 28504: symbol=__libc_enable_secure; lookup in file=cat [0] 28504: symbol=__libc_enable_secure; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: symbol=__libc_enable_secure; lookup in file=/lib64/ld-linux-x86-64.so.2 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol `__libc_enable_secure' [GLIBC_PRIVATE] 28504: symbol=_res_hconf; lookup in file=cat [0] 28504: symbol=_res_hconf; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `_res_hconf' [GLIBC_2.2.5] 28504: symbol=malloc; lookup in file=cat [0] 28504: symbol=malloc; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `malloc' [GLIBC_2.2.5] 28504: symbol=getdate_err; lookup in file=cat [0] 28504: symbol=getdate_err; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `getdate_err' [GLIBC_2.2.5] 28504: symbol=__tzname; lookup in file=cat [0] 28504: symbol=__tzname; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__tzname' [GLIBC_2.2.5] 28504: symbol=__timezone; lookup in file=cat [0] 28504: symbol=__timezone; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__timezone' [GLIBC_2.2.5] 28504: symbol=_rtld_global_ro; lookup in file=cat [0] 28504: symbol=_rtld_global_ro; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: symbol=_rtld_global_ro; lookup in file=/lib64/ld-linux-x86-64.so.2 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib64/ld-linux-x86-64.so.2 [0]: normal symbol `_rtld_global_ro' [GLIBC_PRIVATE] 28504: symbol=optarg; lookup in file=cat [0] 28504: symbol=optarg; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `optarg' [GLIBC_2.2.5] 28504: symbol=__ctype_tolower; lookup in file=cat [0] 28504: symbol=__ctype_tolower; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__ctype_tolower' [GLIBC_2.2.5] 28504: symbol=__ctype_toupper; lookup in file=cat [0] 28504: symbol=__ctype_toupper; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__ctype_toupper' [GLIBC_2.2.5] 28504: symbol=svc_max_pollfd; lookup in file=cat [0] 28504: symbol=svc_max_pollfd; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `svc_max_pollfd' [GLIBC_2.2.5] 28504: symbol=__ctype_b; lookup in file=cat [0] 28504: symbol=__ctype_b; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__ctype_b' [GLIBC_2.2.5] 28504: symbol=argp_program_version_hook; lookup in file=cat [0] 28504: symbol=argp_program_version_hook; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `argp_program_version_hook' [GLIBC_2.2.5] 28504: symbol=__after_morecore_hook; lookup in file=cat [0] 28504: symbol=__after_morecore_hook; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__after_morecore_hook' [GLIBC_2.2.5] 28504: symbol=__environ; lookup in file=cat [0] 28504: symbol=__environ; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__environ' [GLIBC_2.2.5] 28504: symbol=__ctype32_b; lookup in file=cat [0] 28504: symbol=__ctype32_b; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__ctype32_b' [GLIBC_2.2.5] 28504: symbol=__curbrk; lookup in file=cat [0] 28504: symbol=__curbrk; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `__curbrk' [GLIBC_2.2.5] 28504: symbol=argp_program_version; lookup in file=cat [0] 28504: symbol=argp_program_version; lookup in file=/lib/x86_64-linux-gnu/libc.so.6 [0] 28504: binding file /lib/x86_64-linux-gnu/libc.so.6 [0] to /lib/x86_64-linux-gnu/libc.so.6 [0]: normal symbol `argp_program_version' [GLIBC_2.2.5] 28504: symbol=__d

相似文章

在dsymutil中采用并行DWARF链接器

Hacker News Top

苹果的dsymutil工具用于将DWARF调试信息链接到自包含的捆绑包中,现在正在采用并行DWARF链接器来解决类型去重中的单线程瓶颈,尽管由于输出并非二进制完全相同而在验证方面面临挑战。

精准调试基准:你的模型在调试还是在重写?

Hugging Face Daily Papers

# 论文页面 - 精准调试基准:你的模型在调试还是在重写? 来源:[https://huggingface.co/papers/2604.17338](https://huggingface.co/papers/2604.17338) ## 摘要 前沿大模型在测试通过率上表现优异,但在调试任务中的精准度却很低,暴露出功能正确与精准定位缺陷之间的鸿沟。与代码补全不同,调试需定位错误并做针对性修改。我们观察到,前沿大模型在调试时往往重写出正确却过度修改的代码。

被低估的内置功能:Grand Unified Debugger

Lobsters Hottest

本文重点介绍了Emacs内置的Grand Unified Debugger(GUD)的功能,强调了其多调试器支持和图形化GDB界面,包括通过点击边缘设置断点以及单步执行代码等功能。

模拟器调试:Area 5150 的 Lake Effect

Lobsters Hottest

本文详细介绍了在MartyPC模拟器上调试Area5150演示中“Lake”效应的过程,解释了需要特定标题hack的原因,以及通过总线嗅探和动态时钟实现周期精确CGA模拟的后续修复方法。