[fpc-pascal] access violation somehow related to dlopen'ing libssl
Seth Grover
sethdgrover at gmail.com
Fri Jul 2 17:11:32 CEST 2010
Greetings once again! I've run into a little bit of a strange problem
that I'm hoping someone here will be able to help me figure out.
I'm using, as I suspect some of you may be, the excellent synapse
project (http://ararat.cz/synapse). I have a simple 64-bit project
which consists only of:
========================================================
program syna64test;
{$mode objfpc}{$H+}
uses
ssl_openssl;
begin
end.
========================================================
Admittedly, to get this to compile I had to remove the "libc"
dependency from synapse's ssl_openssl_lib.pas, but I can't see how
that would be a problem since it's not used by anything in that unit
and compiles fine without it.
So, as you can see, this program doesn't do anything except call
ssl_openssl's initialization code, which ends up in a function called
InitSSLInterface in ssl_openssl_lib.pas, which attempts to dlopen
libssl and libcrypt and then call GetProcedureAddress for various
openssl functions. Pretty standard stuff. And, of course, since libssl
isn't linked directly, ldd displays something like this:
========================================================
$ ldd syna64test
linux-vdso.so.1 => (0x00007fff56bff000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fc599613000)
libc.so.6 => /lib/libc.so.6 (0x00007fc599291000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc59983c000)
========================================================
However, the problem I run into is if my program is linked against
something else that also depends on libssl. For a simple example, if I
attempt to also link against libssh2.so like this (I actually do have
a .pas header file for libssh2, but for the sake of simplicity in this
example I'll simply use LINKLIB):
========================================================
program syna64test;
{$mode objfpc}{$H+}
{$LINKLIB ssh2}
uses
ssl_openssl;
begin
end.
========================================================
Now ldd shows:
========================================================
$ ldd syna64test
linux-vdso.so.1 => (0x00007fffe2bd0000)
libssh2.so.1 => /usr/lib/libssh2.so.1 (0x00007fdb393f0000)
libdl.so.2 => /lib/libdl.so.2 (0x00007fdb391ec000)
libssl.so.0.9.8 => /lib/libssl.so.0.9.8 (0x00007fdb38f9b000)
libcrypto.so.0.9.8 => /lib/libcrypto.so.0.9.8 (0x00007fdb38c0b000)
libz.so.1 => /lib/libz.so.1 (0x00007fdb389f4000)
libc.so.6 => /lib/libc.so.6 (0x00007fdb38671000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdb3963a000)
========================================================
When I run the program, I get:
========================================================
$ ./syna64test
An unhandled exception occurred at $00007F5DBE8026D5 :
EAccessViolation : Access violation
$00007F5DBE8026D5
$00007F5DBD97AF66
$00007F5DBE3D00C4
An unhandled exception occurred at $00007F5DBE80D3C1 :
EAccessViolation : Access violation
$00007F5DBE80D3C1
========================================================
When I run it in gdb, it crashes calling GetProcedureAddress with the
dlopen'ed handle:
========================================================
$ gdb ./syna64test
...
Reading symbols from
/media/truecrypt1/tlacuache/devel/seth/trunk/syna64test/bin/syna64test...done.
(gdb) r
Starting program:
/media/truecrypt1/tlacuache/devel/seth/trunk/syna64test/bin/syna64test
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7de66d5 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0 0x00007ffff7de66d5 in ?? () from /lib64/ld-linux-x86-64.so.2
#1 0x00007ffff6f5ef66 in ?? () from /lib/libc.so.6
#2 0x00007ffff79b40c4 in ?? () from /lib/libdl.so.2
#3 0x00007ffff7dea9c6 in ?? () from /lib64/ld-linux-x86-64.so.2
#4 0x00007ffff79b42ac in ?? () from /lib/libdl.so.2
#5 0x00007ffff79b407a in dlsym () from /lib/libdl.so.2
#6 0x0000000000499963 in
DYNLIBS_GETPROCEDUREADDRESS$INT64$ANSISTRING$$POINTER ()
#7 0x0000000000493acd in GETPROCADDRESS (MODULE=-134393856,
PROC=0x6bfcf8 "SSL_get_error") at src/synafpc.pas:106
#8 0x0000000000487beb in GETPROCADDR (MODULE=-134393856,
PROCNAME=0x6bfcf8 "SSL_get_error") at src/ssl_openssl_lib.pas:1688
#9 0x0000000000487cec in INITSSLINTERFACE () at src/ssl_openssl_lib.pas:1715
#10 0x0000000000433d41 in SSL_OPENSSL_init () at src/ssl_openssl.pas:818
#11 0x000000000042478e in fpc_initializeunits ()
#12 0x0000000000000000 in ?? ()
(gdb) info reg
rax 0xfffffffff7fd5388 -134392952
rbx 0x7f44c24c94e941a0 9170668375404790176
rcx 0x7ffff7fe92dd 140737354044125
rdx 0x433ee85ef9908c1f 4845565743708802079
rsi 0xfffffffff7fd5000 -134393856
rdi 0x7ffff7fe92d0 140737354044112
rbp 0x7fffffffdc50 0x7fffffffdc50
rsp 0x7fffffffdb30 0x7fffffffdb30
r8 0xffffffff 4294967295
r9 0x0 0
r10 0x7fffffffdb00 140737488345856
r11 0x7ffff6f5f360 140737336701792
r12 0x0 0
r13 0x7fffffffdd10 140737488346384
r14 0xfffffffff7fd5000 -134393856
r15 0xf9908c1f 4186999839
rip 0x7ffff7de66d5 0x7ffff7de66d5
eflags 0x10246 [ PF ZF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) info shared
>From To Syms Read Shared Object Library
0x00007ffff7ddcaf0 0x00007ffff7df5814 Yes (*) /lib64/ld-linux-x86-64.so.2
0x00007ffff7bbc2b0 0x00007ffff7bd3ad8 Yes (*) /usr/lib/libssh2.so.1
0x00007ffff79b3de0 0x00007ffff79b49c8 Yes (*) /lib/libdl.so.2
0x00007ffff7776c10 0x00007ffff77a25b8 Yes (*) /lib/libssl.so.0.9.8
0x00007ffff743d040 0x00007ffff74f82e8 Yes (*) /lib/libcrypto.so.0.9.8
0x00007ffff71be260 0x00007ffff71cad38 Yes (*) /lib/libz.so.1
0x00007ffff6e588c0 0x00007ffff6f69f5c Yes (*) /lib/libc.so.6
(*): Shared library is missing debugging information.
========================================================
The odd thing is, if I compile this program for i386, it runs fine. In
that case:
========================================================
$ ldd ./syna64test
linux-gate.so.1 => (0xf77d8000)
libssh2.so.1 => /usr/lib32/libssh2.so.1 (0xf778f000)
libdl.so.2 => /lib32/libdl.so.2 (0xf778a000)
libgcrypt.so.11 => /lib32/libgcrypt.so.11 (0xf7717000)
libz.so.1 => /usr/lib32/libz.so.1 (0xf7702000)
libc.so.6 => /lib32/libc.so.6 (0xf75a8000)
/lib/ld-linux.so.2 (0xf77d9000)
libgpg-error.so.0 => /lib32/libgpg-error.so.0 (0xf75a3000)
$ ./syna64test
$
========================================================
So, for some reason, when building for x86_64, the combination of my
program linking against a .so which has a libssl dependency, combined
with synapse's ssl_openssl_lib attempting to dlopen and then call
GetProcedureAddress for a procedure in libssl causes things to blow
up.
Any suggestions?
Thanks,
-SG
--
This email is fiction. Any resemblance to actual events
or persons living or dead is purely coincidental.
Seth Grover
sethdgrover[at]gmail[dot]com
More information about the fpc-pascal
mailing list