LINUX.ORG.RU

dlopen: Segmentation fault


0

0

у меня есть библиотека, которую использует СУБД Cache в своей работе. Использует удачно. Это so файл.

Вот смотрите, сами:

user$ /tmp/1 $ ldd /usr/local/mca/servers/mca/lib/libccallin.so
libpm.so.0 => /usr/local/mca/servers/mca/lib/libpm.so.0 (0x00002b6cbb3ef000)
libcache.so => /opt/cache2007/bin/libcache.so (0x00002b6cbb52e000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b6cbbaad000)
libm.so.6 => /lib64/tls/libm.so.6 (0x00002b6cbbc9e000)
libc.so.6 => /lib64/tls/libc.so.6 (0x00002b6cbbe24000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b6cbc058000)
libshared.so => /usr/local/mca/libs/binreloc/lib/libshared.so (0x00002b6cbc164000)
libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00002b6cbc267000)
libZThread-2.3.so.2 => /usr/local/mca/libs/zthread/lib/libZThread-2.3.so.2 (0x00002b6cbc475000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b6cbc5bf000)
librt.so.1 => /lib64/tls/librt.so.1 (0x00002b6cbc6c2000)
/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
libpthread.so.0 => /lib64/tls/libpthread.so.0 (0x00002b6cbc7dc000)
libz.so.1 => /usr/lib64/libz.so.1 (0x00002b6cbc8f2000)
user$ /tmp/1 $ cat 1.c

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main (int argc, char *argv[]) {
int han;

han = dlopen("/usr/local/mca/servers/mca/lib/libccallin.so", RTLD_LAZY);
if (!han) {
printf("Error: %s\n", dlerror());
}

printf("Done\n");

exit(0);

}
user$ /tmp/1 $ gcc -g 1.c -o 1 -ldl && ./1
1.c: In function `main':
1.c:9: warning: assignment makes integer from pointer without a cast
Segmentation fault
user$ /tmp/1 $

user$ /tmp/1 $ gdb ./1
GNU gdb Red Hat Linux (6.3.0.0-1.132.EL4rh)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu"...Using host libthread_db library "/lib64/tls/libthread_db.so.1".

(gdb) r
Starting program: /tmp/1/1
[Thread debugging using libthread_db enabled]
[New Thread 47175520534080 (LWP 27253)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 47175520534080 (LWP 27253)]
0x0000003620a0aafe in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0 0x0000003620a0aafe in _dl_catch_error () from /lib64/ld-linux-x86-64.so.2
#1 0x0000003620cf85f2 in _dl_open () from /lib64/tls/libc.so.6
Previous frame inner to this frame (corrupt stack?)
(gdb)



я так понимаю, в этой библиотеке создаеться поток, который и вызывает SIGSEGV ?
только я не понимаю, как может вызваться функция в этой библиотеке, если RTLD_LAZY не делает этого.

может кто-то дать комментарий ?


через указаный мною код, все библиотеки, в которых нуждалась первичная библиотека, были успешно загружены.
чесно, не понимаю...

nial
() автор топика

За такое руки надо отрывать. Ты пишешь 8ми байтный указатель в 4х байтную переменную.

Reset ★★★★★
()
Ответ на: комментарий от Reset

segfault не из за этого. То, что он пишет, просто отбрасывает верхние 4 байта. Руки конечно отрывать надо.

anonymous
()
Ответ на: комментарий от Reset

спасибо за совет - я не часто пишу под х64. однако измение int на long действительно не помогло.

Я просто суть не могу понять - почему может быть sigsegv.

nial
() автор топика
Ответ на: комментарий от nial

>однако измение int на long действительно не помогло.

А что, просто написать "void * han" религия не позволяет??? В чем смысл засовывать указатель в целочисленную переменную?

Посмотри, с какими ключами компилируется СУБД Cache (если есть возможность), может надо указать -fPIC. ИМХО, _init вызывается всегда, независимо от RTLD_LAZY. Может надо указать RTLD_NOW и посмотреть на сообщение об ошибке...

mky ★★★★★
()

dlclose() ещё забыл. (или просто не неписал)

php-coder ★★★★★
()

Так посмотрите, как объявлена функия dlopen:

void *dlopen(const char *filename, int flag);

Функция возвращает УКАЗАТЕЛЬ.

andreyu ★★★★★
()
Ответ на: комментарий от mky

user$ /tmp/1 $ cat 1.c

#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

int main (int argc, char *argv[]) {
        void * handle;
        handle = dlopen("/usr/local/mca/servers/mca/lib/libccallin.so", RTLD_NOW);
        if (!handle) {
                printf("Error: %s\n", dlerror());
                exit(1);
        }
        printf("Done\n");
        exit(0);
}
user$ /tmp/1 $ gcc -g -fPIC -ldl 1.c -o 1
user$ /tmp/1 $ ./1
Error: /usr/local/mca/servers/mca/lib/libccallin.so: undefined symbol: iniparser_load
user$ /tmp/1 $ 

мне интересно понять, собственно, почему вылетает.
void *, int, long - можно вообще без проверки, просто написать
dlopen("/usr/local/mca/servers/mca/lib/libccallin.so", RTLD_LAZY);
и будет достаточно чтобы сделать SIGSEGV.

я, блин, сути не пойму. не понимаю, почему вылетает.

Допустим, не все символы резольвятся в библиотеке. Ладно, но почему же вылетает прога, в которой сказано Only resolve symbols as the code that references them is executed, не пойму.

nial
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.