Solved QSslSocket segmentation fault on static build
-
@Hasan-Vaez I build a static version of Qt and then I build a static version of my application.
I'm using opensource version. -
@jsulm By building my application with
-static
I obtain a static build without dynamic link.
The ldd output is as expected:not a dynamic executable
-
@Luca As I know, in Qt open source, you can not link Libs as static.
This is one one the L(GPL) limitation.
Check this link: https://www.qt.io/download -
@Hasan-Vaez For personal use it's not true.
But the point it's not the license but the segmentation fault. -
@Hasan-Vaez said in QSslSocket segmentation fault on static build:
As I know, in Qt open source, you can not link Libs as static.
That's wrong.
You can statically link Qt libs as long as you comply with GPL. -
Hi,
But did you also linked to a static build of OpenSSL ?
-
Hi,
I suppose yes because ldd tells me it's not a dynamic executable.Also conseders that building with "-static" only use all static version of library. Otherwise it doesn't build.
-
No, the -static builds Qt statically, however if the dependencies (libssl for example) are dynamic, then they will stay that way although Qt itself is static.
-
@SGaist I probably explained me wrong...
I also built my application with -static and the executable doesn't require external dynamic library. -
Then can you show the stack trace you get ?
-
@luca said in QSslSocket segmentation fault on static build:
I also built my application with -static and the executable doesn't require external dynamic library.
Unless you ship a static distribution of OpenSSL, which I find rather unlikely, then your application will still depend on it, just as @jsulm pointed out. Run
ldd
and you're going to see what the loader needs. -
-
Please run
readelf -l <appname>
and post the output here. -
@kshegunov This is the output:
Elf file type is EXEC (Executable file) Entry point 0x4036a0 There are 6 program headers, starting at offset 64 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 0x0000000000bdeee8 0x0000000000bdeee8 R E 0x200000 LOAD 0x0000000000bdfdd0 0x00000000011dfdd0 0x00000000011dfdd0 0x000000000009543c 0x00000000000ad298 RW 0x200000 NOTE 0x0000000000000190 0x0000000000400190 0x0000000000400190 0x0000000000000044 0x0000000000000044 R 0x4 TLS 0x0000000000bdfdd0 0x00000000011dfdd0 0x00000000011dfdd0 0x0000000000000070 0x00000000000000c8 R 0x8 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 0x10 GNU_RELRO 0x0000000000bdfdd0 0x00000000011dfdd0 0x00000000011dfdd0 0x000000000001f230 0x000000000001f230 R 0x1 Section to Segment mapping: Segment Sections... 00 .note.ABI-tag .note.gnu.build-id .rela.plt .init .plt .text __libc_freeres_fn __libc_thread_freeres_fn .fini .rodata .qtversion .qtmetadata .stapsdt.base __libc_subfreeres __libc_IO_vtables __libc_atexit __libc_thread_subfreeres .eh_frame .gcc_except_table 01 .tdata .preinit_array .init_array .fini_array .jcr .data.rel.ro .got .got.plt .data .bss __libc_freeres_ptrs 02 .note.ABI-tag .note.gnu.build-id 03 .tdata .tbss 04 05 .tdata .preinit_array .init_array .fini_array .jcr .data.rel.ro .got
-
This file doesn't contain an interpreter section (also the reason why
ldd
fails). If it has dependencies on any shared libraries (in theLOAD
sections) it will fail to load them. Could you also run:readelf -d <appname>
to see what's going on there?Also it could be useful to provide the compile and link lines you have when building the binary for the system in question.
-
@kshegunov
The output of readelf -d is:There is no dynamic section in this file.
The linker string is:
-static -lcrypto -lssl -L/opt/qt563-static/lib -L/opt/qt563-static/plugins/sqldrivers -lqsqlite -lqsqlmysql -lmariadbclient -lQt5Sql -L/opt/qt563-static/plugins/bearer -lqconnmanbearer -lqgenericbearer -lqnmbearer -lQt5Network -lQt5DBus -lQt5Core -lz -lqtpcre -lm -ldl -lrt -lpthread
I just rebuilt and I noted a warning at the end of the build:
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(client_plugin.c.o): In function `mysql_load_plugin_v': (.text+0x4f3): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /opt/qt563-static/lib/libQt5Core.a(qfilesystemengine_unix.o): In function `QFileSystemEngine::resolveGroupName(unsigned int)': qfilesystemengine_unix.cpp:(.text+0x9fd): warning: Using 'getgrgid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(mf_pack.c.o): In function `unpack_dirname': (.text+0x842): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(libmysql.c.o): In function `read_user_name': (.text+0x2368): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(mf_pack.c.o): In function `unpack_dirname': (.text+0x855): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /opt/qt563-static/lib/libQt5Core.a(qfilesystemengine_unix.o): In function `QFileSystemEngine::resolveUserName(unsigned int)': qfilesystemengine_unix.cpp:(.text+0x6c5): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(client.c.o): In function `mysql_real_connect': (.text+0x524f): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libmariadbclient.a(libmysql.c.o): In function `mysql_server_init': (.text+0x2117): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
could it be the reason of the segmentation fault on some Linux servers?
-
I think now I understand what's going on and why this happens. Your build is rather odd, but in short it goes like this:
You have linked not only the static libraries, but have required a static linkage(!), which means that when you build the application the linker will go to the libraries your application depends on, see what's the address of each of methods you use and write it down directly into the binary (that's why you get the warnings as well).Usually one depends on the loader ("dynamic linker" on linux) to do the symbol resolution just after the application starts (before
main()
, however this is not the case here, there's no interpreter for the binary. The main implication is that if the binary layout of any one of the libraries you need has the changed, then you'd call an invalid address from the application thus the process will gloriously crash.Now, my advice is to do the usual linking, as it's much less error prone in that particular regard. Remove
LIBS += -static
and rebuild. Then you should be able to inspect the binary withldd
and you should also see the interpreter being included in the ELF header. What you'd expect is to see afterwards fromreadelf -l
for file type is "Elf file type is DYN (Shared object file)" andldd
should provide you with the list of dependencies. (You can still link the static Qt build, as you do now, if you so desire, this is not impeded). -
@kshegunov
Thanks for the explaination.
I understand what you said but I need a completely static build to avoid publishing all required libs on my server.By googling again I found a parameter to pass to configure when compiling static Qt:
-openssl-linked
This tells Qt to link directly to openssl instead of using dlopen (internally). This could be the reason for segfault when executing:
new QSslSocket(this);
Now I'm rebuilding Qt. At the end I'll try again to see if it solves the problem.
I'll keep you updated. -
@luca said in QSslSocket segmentation fault on static build:
I need a completely static build to avoid publishing all required libs on my server.
Then you need to provide the static binaries for all the libraries you use, which will include openssl ...
The fact that you've said you want static application, does not remove the need to satisfy the dependencies. As @jsulm wrote before - even if you compile Qt statically, given that Qt depends on openssl, means one of the two things:- you provide an openssl static build, so Qt will incorporate the archive directly into the binary
or
- you don't provide a static openssl build and then Qt depends on the dynamic library, which translates to your application (after linking) depending on the same dynamic library.
And this applies to every dependency of Qt, your application or any external library you use, not only to openssl.
-
@kshegunov
My Debian distro already has both version (static and shared) for all the library I need.I finally solved by building the static version of Qt using -openssl-linked in the configure command.
Without that parameter it compile static version of Qt but it load openssl library at runtime with dlopen().
That's the cause of the segfault when creating QSslSocket object.Thanks all for help!