[MDEV-16525] MyRocks linking fails with: Undefined reference to `ZDICT_trainFromBuffer' Created: 2018-06-19  Updated: 2022-03-25  Resolved: 2018-06-20

Status: Closed
Project: MariaDB Server
Component/s: Compiling, Storage Engine - RocksDB
Affects Version/s: 10.2, 10.3
Fix Version/s: 10.2.16

Type: Bug Priority: Blocker
Reporter: Sergei Petrunia Assignee: Vicențiu Ciorbaru
Resolution: Fixed Votes: 1
Labels: None
Environment:

Debian Stretch


Issue Links:
Relates
relates to MDEV-28011 Debian autobake cleanup to remove out... Closed

 Description   

https://buildbot.askmonty.org/buildbot/builders/kvm-deb-stretch-amd64/builds/4213/steps/compile/logs/stdio

librocksdblib.a(compaction_job.cc.o): In function `rocksdb::ZSTD_TrainDictionary(std::__cxx11::basic_string
<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<unsigned long,
 std::allocator<unsigned long> > const&, unsigned long)':
./builddir/storage/rocksdb/./storage/rocksdb/rocksdb/util/compression.h:812: undefined reference to `ZDICT_trainFromBuffer'
./builddir/storage/rocksdb/./storage/rocksdb/rocksdb/util/compression.h:813: undefined reference to `ZDICT_isError'
collect2: error: ld returned 1 exit status
storage/rocksdb/CMakeFiles/sst_dump.dir/build.make:98: recipe for target 'storage/rocksdb/sst_dump' failed

It actually attempts to link with libzstd:

/usr/bin/x86_64-linux-gnu-g++   -g -O2 
-fdebug-prefix-map=/home/buildbot/buildbot/build/mariadb-10.2.16=. 
-specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security 
-pie -fPIC -Wl,-z,relro,-z,now -fstack-protector --param=ssp-buffer-size=4 -fno-rtti -O3 -g -static-libgcc 
-fno-omit-frame-pointer -fno-strict-aliasing -Wno-uninitialized -D_FORTIFY_SOURCE=2 -DDBUG_OFF
  -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now 
CMakeFiles/sst_dump.dir/rocksdb/tools/sst_dump.cc.o  
-o sst_dump  -lpthread librocksdblib.a -lsnappy -lzstd -lz -lpthread 

but fails for some reason



 Comments   
Comment by Sergei Petrunia [ 2018-06-19 ]

On my machine (Ubuntu Vivid, ZStandard is not available as package and so it is manually installed into /usr/local) , a similar linking command succeeds:

/usr/bin/c++    -pie -fPIC -Wl,-z,relro,-z,now -fstack-protector --param=ssp-buffer-size=4 
-fPIC -fno-rtti -g -DENABLED_DEBUG_SYNC -ggdb3 -DSAFE_MUTEX -DSAFEMALLOC 
-Wall -Wextra -Wformat-security -Wno-init-self -Wno-unused-parameter -Woverloaded-virtual
 -Wnon-virtual-dtor -Wvla -Wwrite-strings    CMakeFiles/sst_dump.dir/rocksdb/tools/sst_dump.cc.o  
-o sst_dump  -lpthread librocksdblib.a -llz4 -lsnappy /usr/local/lib/libzstd.so -lz -lpthread -Wl,-rpath,/usr/local/lib: 

Comment by Sergei Petrunia [ 2018-06-19 ]

Went through CMakeLists.txt files with wlad and checked that ZStandard is added correctly as a library:

MYSQL_ADD_EXECUTABLE(sst_dump rocksdb/tools/sst_dump.cc COMPONENT rocksdb-engine)
TARGET_LINK_LIBRARIES(sst_dump rocksdblib)

...

storage/rocksdb/build_rocksdb.cmake:380:target_link_libraries(rocksdblib ${THIRDPARTY_LIBS} ${SYSTEM_LIBS})

...

if(ZSTD_FOUND AND (NOT WITH_ROCKSDB_ZSTD STREQUAL "OFF"))
  add_definitions(-DZSTD)
  include_directories(${ZSTD_INCLUDE_DIR})
  list(APPEND THIRDPARTY_LIBS ${ZSTD_LIBRARY})
endif()

Comment by Sergei Petrunia [ 2018-06-19 ]

An interesting observation: ZDICT_trainFromBuffer is not present in libzstd.so on Debian Stretch:

buildbot@debian-9-stretch-amd64:~$ objdump -T /usr/lib/x86_64-linux-gnu/libzstd.so | grep ZDICT_trainFromBuffer
buildbot@debian-9-stretch-amd64:~$ 

It is present in the static library:

buildbot@debian-9-stretch-amd64:~$ nm /usr/lib/x86_64-linux-gnu/libzstd.a | grep ZDICT_trainFromBuffer
0000000000002b30 T ZDICT_trainFromBuffer
...

It is also present in /usr/include.

Comment by Sergei Petrunia [ 2018-06-19 ]

On my machine, ZDICT_trainFromBuffer IS present in the .so file:

psergey@psergey-desktop:~/dev-git/10.3-r3/storage/rocksdb$ objdump -T /usr/local/lib/libzstd.so | grep ZDICT_trainFromBuffer
000000000007e7f0 g    DF .text  0000000000000205  Base        ZDICT_trainFromBuffer_legacy
000000000007ea00 g    DF .text  0000000000000070  Base        ZDICT_trainFromBuffer
0000000000073230 g    DF .text  000000000000040f  Base        ZDICT_trainFromBuffer_cover

Comment by Sergei Petrunia [ 2018-06-19 ]

To check if this is a peculiarity of our Build Host, I've spun up an EC2 instance from {{debian-stretch-hvm-x86_64-gp2-2017-06-21-52542 }}.

admin@ip-172-31-17-107:~$ sudo apt-get install libzstd-dev  libzstd1
...
Get:1 http://cdn-aws.deb.debian.org/debian stretch/main amd64 libzstd1 amd64 1.1.2-1 [193 kB]
Get:2 http://cdn-aws.deb.debian.org/debian stretch/main amd64 libzstd-dev amd64 1.1.2-1 [221 kB]

admin@ip-172-31-17-107:~$ objdump -T  /usr/lib/x86_64-linux-gnu/libzstd.so | grep ZDICT_trainFromBuffer
admin@ip-172-31-17-107:~$

Not present in .so

admin@ip-172-31-17-107:~$ nm  /usr/lib/x86_64-linux-gnu/libzstd.a | grep ZDICT_trainFromBuffer
0000000000002b30 T ZDICT_trainFromBuffer
0000000000002920 T ZDICT_trainFromBuffer_advanced
0000000000001a90 T ZDICT_trainFromBuffer_unsafe

Present in .a.

Comment by Sergei Petrunia [ 2018-06-19 ]

I don't see any bugs about this against the debian package: https://bugs.debian.org/cgi-bin/pkgreport.cgi?package=zstd.

To check further, I've tried installing a newer RocksDB from stretch-backports as described here: https://backports.debian.org/Instructions/

admin@ip-172-31-17-107:~$ sudo apt-get -t stretch-backports install "libzstd1" 
...
Get:1 http://ftp.debian.org/debian stretch-backports/main amd64 libzstd-dev amd64 1.3.3+dfsg-1~bpo9+1 [231 kB]
Get:2 http://ftp.debian.org/debian stretch-backports/main amd64 libzstd1 amd64 1.3.3+dfsg-1~bpo9+1 [188 kB]

and after that both .a and .so have the function:

admin@ip-172-31-17-107:~$ nm  /usr/lib/x86_64-linux-gnu/libzstd.a | grep ZDICT_trainFromBuffer
0000000000001110 T ZDICT_trainFromBuffer_cover
00000000000026b0 T ZDICT_trainFromBuffer
00000000000025a0 T ZDICT_trainFromBuffer_legacy
0000000000001990 T ZDICT_trainFromBuffer_unsafe_legacy

admin@ip-172-31-17-107:~$ objdump -T  /usr/lib/x86_64-linux-gnu/libzstd.so | grep ZDICT_trainFromBuffer
00000000000537b0 g    DF .text  000000000000010c  Base        ZDICT_trainFromBuffer_legacy
000000000004a790 g    DF .text  0000000000000328  Base        ZDICT_trainFromBuffer_cover
00000000000538c0 g    DF .text  0000000000000070  Base        ZDICT_trainFromBuffer

Comment by Sergei Petrunia [ 2018-06-19 ]

cvicentiu otto any thoughts? Should this be reported as a bug against Debian?

The only solution that I see right now is:

  • Disable linking against libzstd on Debian Stretch. (We cannot link against a package from -Backports, can we ?)

How do we achieve the above? Remove the libzstd-dev package from the Debian Stretch builder?

Comment by Sergei Petrunia [ 2018-06-19 ]

Thanks to wlad for taking part in the above investigation

Comment by Otto Kekäläinen [ 2018-06-19 ]

You can file a bug against Debian and try to persuade the maintainer/release manager to push this backported version into a stable release update. In the mean time probably needs to be disabled for Debian Stretch in debian/autobake-deb.sh that checks if version 1.3.3 or newer is available and if not, it will simply sed out the library from debian/control.

Comment by Sergei Golubchik [ 2018-06-19 ]

Right. It turns out that stretch has libzstd1-1.1.2-1. And the visibility of ZDICT_trainFromBuffer was changed in this commit — note how it changed

#  define ZSTDLIB_API 

to

#  define ZDICTLIB_VISIBILITY __attribute__ ((visibility ("default"))) 
...
#  define ZDICTLIB_API ZDICTLIB_VISIBILITY 

And that commit is present in tags starting from v1.1.3.

The proper fix our side is to only use libzstd if it's usable, where "usable" in this context means "exports ZDICT_trainFromBuffer function"

Generated at Thu Feb 08 08:29:33 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.