[root@localhost bin]# ldd /usr/local/bin/memcached linux-gate.so.1 => (0x00c8d000) libevent-2.0.so.5 => not found librt.so.1 => /lib/librt.so.1 (0x00720000) libpthread.so.0 => /lib/libpthread.so.0 (0x006fc000) libc.so.6 => /lib/libc.so.6 (0x00564000) /lib/ld-linux.so.2 (0x0053e000)
發現依賴的 libevent-2.0.so.5 => not found 沒有找到。 查看 libevent 如何尋找依賴:
[root@localhost bin]# LD_DEBUG=libs ./memcached -v 10071: find library=libevent-2.0.so.5 [0]; searching 10071: search cache=/etc/ld.so.cache 10071: search path=/lib/tls/i686/sse2:/lib/tls/i686:/lib/tls/sse2:/lib/tls:/lib/i686/sse2:/lib/i686:/lib/sse2:/lib:/usr/lib/tls/i686/sse2:/usr/lib/tls/i686:/usr/lib/tls/sse2:/usr/lib/tls:/usr/lib/i686/sse2:/usr/lib/i686:/usr/lib/sse2:/usr/lib (system search path) 10071: trying file=/lib/tls/i686/sse2/libevent-2.0.so.5 10071: trying file=/lib/tls/i686/libevent-2.0.so.5 10071: trying file=/lib/tls/sse2/libevent-2.0.so.5 10071: trying file=/lib/tls/libevent-2.0.so.5 10071: trying file=/lib/i686/sse2/libevent-2.0.so.5 10071: trying file=/lib/i686/libevent-2.0.so.5 10071: trying file=/lib/sse2/libevent-2.0.so.5 10071: trying file=/lib/libevent-2.0.so.5 10071: trying file=/usr/lib/tls/i686/sse2/libevent-2.0.so.5 10071: trying file=/usr/lib/tls/i686/libevent-2.0.so.5 10071: trying file=/usr/lib/tls/sse2/libevent-2.0.so.5 10071: trying file=/usr/lib/tls/libevent-2.0.so.5 10071: trying file=/usr/lib/i686/sse2/libevent-2.0.so.5 10071: trying file=/usr/lib/i686/libevent-2.0.so.5 10071: trying file=/usr/lib/sse2/libevent-2.0.so.5 10071: trying file=/usr/lib/libevent-2.0.so.5
我們看到: search path=/lib/tls/i686/sse2:/lib/tls/i686:/lib/tls/sse2:/lib/tls:/lib/i686/sse2: /lib/i686:/lib/sse2:/lib:/usr/lib/tls/i686/sse2:/usr/lib/tls/i686: /usr/lib/tls/sse2:/usr/lib/tls:/usr/lib/i686/sse2:/usr/lib/i686:/usr/lib/sse2:/usr/lib (system search path) 系統尋找 lib 的路徑,中沒有包含:/usr/local/lib/ 所以找到了原因,解決方法就很簡單了。也有多種方法。 1) 做一個軟連接到上面的隨便一個 search path 中的目錄都是可以的: [root@localhost bin]# ln -s /usr/local/lib/libevent.so /usr/lib/libevent-2.0.so.5 驗證是否已經解決:
[root@localhost bin]# memcached -help memcached 1.4.24 -p <num> TCP port number to listen on (default: 11211) -U <num> UDP port number to listen on (default: 11211, 0 is off) -s <file> UNIX socket path to listen on (disables network support) -A enable ascii "shutdown" command -a <mask> access mask for UNIX socket, in octal (default: 0700) -l <addr> interface to listen on (default: INADDR_ANY, all addresses) <addr> may be specified as host:port. If you don't specify a port number, the value you specified with -p or -U is used. You may specify multiple addresses separated by comma or by using -l multiple times -d run as a daemon -r maximize core file limit -u <username> assume identity of <username> (only when run as root) -m <num> max memory to use for items in megabytes (default: 64 MB) -M return error on memory exhausted (rather than removing items) -c <num> max simultaneous connections (default: 1024) -k lock down all paged memory. Note that there is a limit on how much memory you may lock. Trying to allocate more than that would fail, so be sure you set the limit correctly for the user you started the daemon with (not for -u <username> user; under sh this is done with 'ulimit -S -l NUM_KB'). -v verbose (print errors/warnings while in event loop) -vv very verbose (also print client commands/reponses) -vvv extremely verbose (also print internal state transitions) -h print this help and exit -i print memcached and libevent license -V print version and exit -P <file> save PID in <file>, only used with -d option -f <factor> chunk size growth factor (default: 1.25) -n <bytes> minimum space allocated for key+value+flags (default: 48) -L Try to use large memory pages (if available). Increasing the memory page size could reduce the number of TLB misses and improve the performance. In order to get large pages from the OS, memcached will allocate the total item-cache in one large chunk. -D <char> Use <char> as the delimiter between key prefixes and IDs. This is used for per-prefix stats reporting. The default is ":" (colon). If this option is specified, stats collection is turned on automatically; if not, then it may be turned on by sending the "stats detail on" command to the server. -t <num> number of threads to use (default: 4) -R Maximum number of requests per event, limits the number of requests process for a given connection to prevent starvation (default: 20) -C Disable use of CAS -b Set the backlog queue limit (default: 1024) -B Binding protocol - one of ascii, binary, or auto (default) -I Override the size of each slab page. Adjusts max item size (default: 1mb, min: 1k, max: 128m) -F Disable flush_all command -o Comma separated list of extended or experimental options - (EXPERIMENTAL) maxconns_fast: immediately close new connections if over maxconns limit - hashpower: An integer multiplier for how large the hash table should be. Can be grown at runtime if not big enough. Set this based on "STAT hash_power_level" before a restart. - tail_repair_time: Time in seconds that indicates how long to wait before forcefully taking over the LRU tail item whose refcount has leaked. Disabled by default; dangerous option. - hash_algorithm: The hash table algorithm default is jenkins hash. options: jenkins, murmur3 - lru_crawler: Enable LRU Crawler background thread - lru_crawler_sleep: Microseconds to sleep between items default is 100. - lru_crawler_tocrawl: Max items to crawl per slab per run default is 0 (unlimited) - lru_maintainer: Enable new LRU system + background thread - hot_lru_pct: Pct of slab memory to reserve for hot lru. (requires lru_maintainer) - warm_lru_pct: Pct of slab memory to reserve for warm lru. (requires lru_maintainer) - expirezero_does_not_evict: Items set to not expire, will not evict. (requires lru_maintainer)
我們看到沒有報錯了。 2) 在編譯libevent的時候,指定相關目錄:
[root@localhost libevent]# ./configure --help `configure' configures this package to adapt to many kinds of systems. Usage: ./configure [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print `checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for `--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or `..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-gcc-warnings enable verbose warnings with GCC --disable-thread-support disable support for threading --disable-malloc-replacement disable support for replacing the memory mgt functions --disable-openssl disable support for openssl encryption --disable-debug-mode disable support for running in debug mode --disable-libevent-install, disable installation of libevent --disable-libevent-regress, skip regress in make check --enable-function-sections, make static library allow smaller binaries with --gc-sections --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a nonstandard directory <lib dir> LIBS libraries to pass to the linker, e.g. -l<library> CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, `make install' will install all the files in `/usr/local/bin', `/usr/local/lib' etc. You can specify an installation prefix other than `/usr/local' using `--prefix', for instance `--prefix=$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include]
所以我們可以如此的在configure時指定路徑: [root@localhost libevent]# ./configure --libdir=/usr/lib 3) 修改環境變量 LD_LIBRARY_PATH,將/usr/local/lib 包含進去。但是該方法一般不推薦這樣做(但是有一種變通的做法,具體參見總結中的 3>)。 --------------------------------------------------------------------------------------------------------- 總結: 1. 和共享庫相關的一些錯誤如何處理: 1> LD_DEBUG 命令: LD_DEBUG 是 glibc 中的 loader 為了方便自身調試而設置的一個環境變量。通過設置這個環境變量,可以方便的看到 loader 的加載過程。
[root@localhost libevent]# LD_DEBUG=help ls Valid options for the LD_DEBUG environment variable are: libs display library search paths reloc display relocation processing files display progress for input file symbols display symbol table processing bindings display information about symbol binding versions display version dependencies all all previous options combined statistics display relocation statistics unused determined unused DSOs help display this help message and exit To direct the debugging output into a file instead of standard output a filename can be specified using the LD_DEBUG_OUTPUT environment variable.
上面列出了 LD_DEBUG 所有的選項,上面我們就使用了 LD_DEBUG=libs 。使用該命令可以獲取很多有用的信息。 2> ldd - print shared library dependencies 打印輸出依賴庫 3> LD_LIBRARY_PATH, /etc/ld.so.conf.d,ldconfig 因為連接器會到目錄 /etc/ld.so.conf.d 下面去尋找 配置了 共享庫 的目錄,所以根據這個原理,我們可以為 /usr/local/lib 專門建立一個配置文件, 加入到連接器尋找 共享庫 的目錄列表中:
[root@localhost ld.so.conf.d]# pwd /etc/ld.so.conf.d [root@localhost ld.so.conf.d]# ls kernel-2.6.32-504.el6.i686.conf mysql-i386.conf qt-i386.conf xulrunner-32.conf [root@localhost ld.so.conf.d]# echo "/usr/local/lib" > usr_local_lib.conf [root@localhost ld.so.conf.d]# ll total 20 -r--r--r--. 1 root root 324 Oct 15 2014 kernel-2.6.32-504.el6.i686.conf -rw-r--r--. 1 root root 15 Feb 13 2014 mysql-i386.conf -rw-r--r--. 1 root root 20 Sep 24 2011 qt-i386.conf -rw-r--r--. 1 root root 15 Sep 13 08:51 usr_local_lib.conf -rw-r--r--. 1 root root 19 Oct 30 2013 xulrunner-32.conf [root@localhost ld.so.conf.d]# cat usr_local_lib.conf /usr/local/lib [root@localhost ld.so.conf.d]# ldconfig
這樣以後 /usr/local/lib 中的共享庫就會被連接器尋找到,注意修改連接器相關的配置之後,一定要用 ldconfig 命令更新一下,不然還是找不到。 2. 如何尋找文件,庫等: whereis - locate the binary, source, and manual page files for a command updatedb - update a database for locate locate - find files by name find 命令 find - search for files in a directory hierarchy 示例: whereis libevent, updatedb, locate libevent,
find / -name libevent.* [root@localhost bin]# find /usr/local -name libevent.* /usr/local/redis-3.0.3/deps/hiredis/adapters/libevent.h /usr/local/src/libevent/libevent.pc.in /usr/local/src/libevent/libevent.pc /usr/local/lib/libevent.la /usr/local/lib/libevent.a /usr/local/lib/pkgconfig/libevent.pc /usr/local/lib/libevent.so [root@localhost bin]# find / -name libevent.so /usr/local/lib/libevent.so [root@localhost bin]# find / -name libevent.so* /usr/local/lib/libevent.so
find 命令 第一個參數是查找的路徑 /usr/local 第二個參數是要查找的文件名的表達式,可以使用正則表達式來表示查找的文件名。 find 還有一個常見的用法:對找到的文件執行某個命令: find . -name \*.lo -o -name \*.o | xargs rm -f (xargs - build and execute command lines from standard input) 3. configure 之前一定要 configure --help 查看配置選項。