我在用户空间保险丝库中添加了一个新功能(fuse_lowlevel_notify_inval_directory).libfuse.so的编译和创建完成没有错误.但是当我的应用程序尝试使用这个新函数时,链接器抛出错误:未定义引用`fuse_lowlevel_notify_inval_directory'colle2:ld返回1退出状态
当我用nm检查时
nm ../libfuse.so | grep inval
00000000000154ed T fuse_invalidate
**000000000001e142 t fuse_lowlevel_notify_inval_directory**
000000000001e26c T fuse_lowlevel_notify_inval_entry
000000000001e1cb T fuse_lowlevel_notify_inval_inode
Run Code Online (Sandbox Code Playgroud)
T/t表示符号出现在文本部分中.如果是大写,则符号为全局(外部).我怀疑这是问题所在.新添加的功能显示小写t,而其他旧功能有大写T.任何关于我可能做错的想法?
我在执行应用程序时获得了一个核心,我保存了可执行文件,核心文件和应用程序使用的共享库,/tmp以便稍后检查它们.然后我修改了库,重建了它并再次启动了可执行文件.现在,当我尝试调试核心时,gdb正在从其原始路径加载共享库,而不是从/tmp保存原始库的目录加载.
例如,原始路径是/opt/mydir/lib/libmylib.so.0.gdb正在加载这个共享库,而我希望它加载/tmp/libmylib.so.0.该应用程序还使用了一些标准库/usr/lib和/lib目录,因此我不希望这些路径被更改.只想改变/opt/mydir/lib/- > /tmp.我怎样才能做到这一点?
我有一个核心文件,其中应用程序以SIGSEGV终止.我怀疑这是因为应用程序耗尽了堆栈空间.有没有办法从核心文件中检查使用的堆栈大小?
我正在使用一个共享库,它有相当多的全局变量,几乎在所有导出函数中使用,因此库函数不是线程安全的。我的应用程序创建多个线程,每个线程动态打开该库,并且为了避免在对导出函数的并行调用之间使用任何同步,我在磁盘上以不同的名称多次复制该库,每个线程打开自己的副本。为了避免这种情况,现在我想改用 dlmopen,但我遇到了一个问题。
当我在应用程序中使用 dlopen 打开库时,该应用程序运行良好
libHandle = dlopen(ip->pathname, (RTLD_LAZY |RTLD_LOCAL|RTLD_DEEPBIND|RTLD_NODELETE));
Run Code Online (Sandbox Code Playgroud)
当我在应用程序中使用 dlmopen 时,出现错误:
ip->libHandle = dlmopen(LM_ID_NEWLM, ip->pathname,
(RTLD_LAZY |RTLD_LOCAL|RTLD_DEEPBIND|RTLD_NODELETE));
Run Code Online (Sandbox Code Playgroud)
dl错误是:
error(libfoo.so.0: undefined symbol: _ZTIN6google8protobuf11MessageLiteE)
Run Code Online (Sandbox Code Playgroud)
执行 nm 确实显示符号未定义 U _ZTIN6google8protobuf11MessageLiteE
问题 1:我想知道如何解决这个问题,以便我可以使用 dlmopen。
原因是因为当使用 LM_ID_NEWLM 时,会在 libc 中创建一个没有任何符号的新空命名空间。因此,该库应该是自包含的或与任何依赖项重新链接。
问题 2:我的主应用程序导出 libfoo 将使用的一些符号。由于在新的命名空间中打开 libfoo,主应用程序的符号对 libfoo 不可见,因此无法解析它们。有什么方法可以告诉链接器通过复制现有的基本命名空间来创建新的命名空间 NEWLM ,然后使用新创建的命名空间的 dlmopen + lmid 来打开 libfoo ,并且所有其他必需的符号都已存在?
问题 3:我可以自己映射 libfoo 的不同部分,并提供指向 libc 的映射部分的指针吗?意味着承担打开文件并将其从 libc 映射出来的工作,并让它完成符号解析的工作?这样我根本不需要调用 dlopen 并且多个文本部分的问题将得到解决。