可选动态库技术问询:Linux/跨平台实现与代码问题排查
关于可选动态库的跨平台实现疑问(结合Intel ITT API场景)
我在做可执行文件性能分析时使用Intel VTune性能分析器,了解到ITT API库可用于启停性能分析,核心函数为__itt_resume()和__itt_pause()。该库是可选动态库:未加载ITT运行时库时,这些函数会自动变为空操作(noop)。
我的疑问(先聚焦Linux平台)
- 进程是启动时检查依赖动态库是否加载,还是运行时调用库中符号(或首个符号)时才检查(即懒初始化)?我明确Windows平台是启动时检查,会弹出“找不到XXX.dll”的提示,但不确定Linux的行为。另外我的测试示例中,即使
some_process.c未定义目标符号,编译执行也完全正常。 - 如何在Linux平台实现这种可选动态库机制?我查看ITT的代码后发现关键宏定义如下,它通过函数指针包裹调用逻辑,指针为NULL时直接做空操作:
#define ITTNOTIFY_VOID(n) (!ITTNOTIFY_NAME(n)) ? (void)0 : ITTNOTIFY_NAME(n)
- 如何跨平台(Windows、Mac、Linux)实现该机制?
我的测试示例(运行不符合预期)
我编写了最简测试代码,但结果不符合预期:加载库时未调用my_api_hello_impl(),未链接库时访问extern符号api_hello_ptr也未崩溃。
示例代码
my_api.c
#include "my_api.h" #include <stdio.h> void(*api_hello_ptr)(); void api_hello_impl() { printf("Hello\n"); } __attribute__((constructor)) static void init() { printf("linked\n"); api_hello_ptr = api_hello_impl; }
my_api.h
#pragma once extern void(*api_hello_ptr)(); inline void api_hello() { if(api_hello_ptr) api_hello_ptr(); }
some_process.c
#include "my_api.h" int main() { // 未链接时应为空操作 api_hello(); }
Makefile
# my_api未链接到some_process some_process: some_process.c my_api.h $(CC) -o $@ $< my_api.so: my_api.c my_api.h $(CC) -shared -fPIC -o $@ $< test_linked: some_process my_api.so LD_PRELOAD="$(shell pwd)/my_api.so" ./some_process test_unlinked: some_process my_api.so ./some_process .PHONY: test_linked test_unlinked
运行输出
$ make test_linked LD_PRELOAD="/tmp/tmp.EkrQbILrNg/my_api.so" ./some_process linked $ make test_unlinked ./some_process
内容的提问来源于stack exchange,提问作者rafoo
相关产品推荐
相关产品推荐

