Linux 此dlsym调用遇到segfault(当调用方.so与目标.so相同时)

Linux 此dlsym调用遇到segfault(当调用方.so与目标.so相同时),linux,segmentation-fault,dlsym,Linux,Segmentation Fault,Dlsym,首先,问题是: Thread 2 "lexe.exe" received signal SIGSEGV, Segmentation fault. [Switching to Thread 0x7ffff2c89700 (LWP 17367)] do_lookup_x (undef_name=undef_name@entry=0x7fffeb893ad9 "algoLenI", new_hash=new_hash@entry=1920857680, old_

首先,问题是:

Thread 2 "lexe.exe" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff2c89700 (LWP 17367)]
do_lookup_x (undef_name=undef_name@entry=0x7fffeb893ad9 "algoLenI", new_hash=new_hash@entry=1920857680, old_hash=old_hash@entry=0x7ffff2c88460, ref=0x0, result=result@entry=0x7ffff2c88470, 
    scope=0x1800029030008080, i=0, version=0x0, flags=2, skip=0x0, type_class=0, undef_map=0x7ffff2c8a000) at dl-lookup.c:339
339 dl-lookup.c: No such file or directory.
(gdb) bt
#0  do_lookup_x (undef_name=undef_name@entry=0x7fffeb893ad9 "algoLenI", new_hash=new_hash@entry=1920857680, old_hash=old_hash@entry=0x7ffff2c88460, ref=0x0, result=result@entry=0x7ffff2c88470, 
    scope=0x1800029030008080, i=0, version=0x0, flags=2, skip=0x0, type_class=0, undef_map=0x7ffff2c8a000) at dl-lookup.c:339
#1  0x00007ffff7de023f in _dl_lookup_symbol_x (undef_name=0x7fffeb893ad9 "algoLenI", undef_map=0x7ffff2c8a000, ref=0x7ffff2c88528, symbol_scope=0x7ffff2c8a388, version=0x0, type_class=0, flags=2, 
    skip_map=<optimized out>) at dl-lookup.c:813
#2  0x00007ffff698bfe6 in do_sym (flags=<optimized out>, vers=0x0, who=0x7ffff2db36e9 <loadLibFunc2+248>, name=0x7fffeb893ad9 "algoLenI", handle=0x7ffff2c8a000) at dl-sym.c:151
#3  _dl_sym (handle=0x7ffff2c8a000, name=0x7fffeb893ad9 "algoLenI", who=0x7ffff2db36e9 <loadLibFunc2+248>) at dl-sym.c:254
#4  0x00007ffff6c170e4 in dlsym_doit (a=a@entry=0x7ffff2c88770) at dlsym.c:50
#5  0x00007ffff698c51f in __GI__dl_catch_exception (exception=exception@entry=0x7ffff2c88700, operate=0x7ffff6c170d0 <dlsym_doit>, args=0x7ffff2c88770) at dl-error-skeleton.c:196
#6  0x00007ffff698c5af in __GI__dl_catch_error (objname=0x603000000020, errstring=0x603000000028, mallocedp=0x603000000018, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:215
#7  0x00007ffff6c17745 in _dlerror_run (operate=operate@entry=0x7ffff6c170d0 <dlsym_doit>, args=args@entry=0x7ffff2c88770) at dlerror.c:162
#8  0x00007ffff6c17166 in __dlsym (handle=<optimized out>, name=0x7fffeb893ad9 "algoLenI") at dlsym.c:70
#9  0x00007ffff2db36e9 in loadLibFunc2 (T=0x7ffff30ff064, PVLib=0x7ffff2c8a000, FuncName=0x7fffeb893ad9 "algoLenI", Check=0 '\000') at ../loadLib/loadLib.c:206


void* loadLibFunc2(void* T, void* PVLib, char* FuncName, bool Check) {
    // ... checked PVLib not null
    void* Res = dlsym(PVLib, FuncName);
    // ... further code that is not reached
}
看起来dlsym具有正确的输入:

(gdb) x/8xb PVLib
0x7ffff6e04000: 0x7f    0x45    0x4c    0x46    0x02    0x01    0x01    0x00
这看起来像是图书馆的开始

(gdb) x/8xb (char*)PVLib+0x919a7
0x7ffff6e959a7 <algoLenI>:  0x55    0x48    0x89    0xe5    0x48    0x83    0xec    0x10
(gdb)x/8xb(char*)PVLib+0x919a7
0x7ffff6e959a7:0x55 0x48 0x89 0xe5 0x48 0x83 0xec 0x10
这看起来像是algoLenI的开始,GDB甚至识别了它

dlsym会因为主程序也有algoLenI而感到困惑吗

(gdb) p algoLenI
$4 = {int32 (void *, charC *)} 0x555555566e81 <algoLenI>
(gdb) x/8xb 0x555555566e81
0x555555566e81 <algoLenI>:  0x55    0x48    0x89    0xe5    0x48    0x83    0xec    0x10
(gdb)p algoLenI
$4={int32(void*,charC*)}0x55566e81
(gdb)x/8xb 0x55566E81
0x5555566E81:0x55 0x48 0x89 0xe5 0x48 0x83 0xec 0x10

原因可能是dlsym的调用方已经是来自同一个.so的代码。因此:加载程序可执行文件加载.so,然后.so中的一些代码也间接需要dlsym。这应该不是问题,因为dlsym似乎有正确的参数(见上文)。

问题是,在某些情况下,指向库的指针在其他地方被取消引用

库指针不应该指向这样的内容(对应于文件的开头)

但指向dlopen返回的不透明句柄。间接方式让我们找到了与文件内容相对应的内容,这只是“简洁”:不透明句柄以指向此操作系统上前者的指针开始

(gdb) p algoLenI
$4 = {int32 (void *, charC *)} 0x555555566e81 <algoLenI>
(gdb) x/8xb 0x555555566e81
0x555555566e81 <algoLenI>:  0x55    0x48    0x89    0xe5    0x48    0x83    0xec    0x10
0x7f    0x45    0x4c    0x46    0x02    0x01    0x01    0x00