在 MacOS 上,我有一组我无法控制的
python
二进制文件(即我无法使用 LDFLAGS='-undefined error'
构建它们)。
在某些 MacOS 主机/体系结构(即某些 ARM Mac,但不是全部;某些 x86 Mac,但不是全部)上,在 Python 中执行某些操作会失败,并显示
dyld[some_pid]: missing symbol called
。
如何找出哪个库文件导致了问题,以及缺少哪个符号(按名称)?
使用以下环境显示
dyld
的诊断输出:
DYLD_PRINT_LIBRARIES=1
DYLD_PRINT_APIS=1
DYLD_PRINT_WARNINGS=1
这会导致失败的操作在崩溃之前发出看似 成功
dyld
的操作。但诊断输出还不够;例如,它通常看起来像这样:
dyld[91757]: dyld_image_path_containing_address(0x10a7ab000) => '/path/to/python/lib/lib.macosx-10.15-x86_64-3.7/_csv.cpython-37m-darwin.so'
dyld[91757]: _dyld_is_memory_immutable(0x10a7ab000, 28) => 0
dyld[91757]: dlopen(_csv.cpython-37m-darwin.so) => 0x210fbb0c0
dyld[91757]: dlsym(0x210fbb0c0, "PyInit__csv")
dyld[91757]: dlsym("PyInit__csv") => 0x10a7abbc0
dyld[91757]: missing symbol called
在该示例中,
nm
报告_csv.cpython-37m-darwin.so
可以解析名为PyInit__csv
的符号。所以看起来(我认为)missing symbol called
错误在不同的符号上失败了,但我不知道如何确定是哪个符号。
最直接的方法是使用 MallocStackLogging 环境变量和 lldb:
# Run Python with stack logging enabled
export MallocStackLogging=1
lldb python your_script.py
# In lldb:
(lldb) b dyld_fatal_error
(lldb) r
# When it breaks:
(lldb) thread backtrace all
(lldb) image list -b
另一种方法是将 dyld 的内置跟踪与 DYLD_PRINT_RPATHS 结合使用:
DYLD_PRINT_RPATHS=1 \
DYLD_PRINT_SEARCHING=1 \
DYLD_PRINT_BINDINGS=1 \
python your_script.py
DYLD_PRINT_SEARCHING 标志尤其可以帮助显示 dyld 在崩溃之前尝试解析哪些符号。
您还可以尝试使用 gdb 而不是 lldb 运行,有时会提供更详细的符号解析信息:
gdb --args python your_script.py
(gdb) set env DYLD_PRINT_BINDINGS 1
(gdb) r