原來跑的好好的進程,重啟後沒跑多少就掛掉了,奇怪了。經過跟蹤,原來是加載了一個
C/C++ library靜態庫(Static Libraries)、共享庫(shared Libraries)和動態加載庫(ynamically loaded DL libraries)。
靜態庫在程序編譯時會被連接到可執行程序中,程序運行時將不再需要該靜態庫。
共享庫在程序編譯時並不會被連接到可執行程序中,而是在可執行程序啟動時被載入內存的,因此在程序運行時還需要動態庫存在。
動態加載庫在可執行程序執行的任何時候可以被加載。 DL libraries aren't really a different kind of library format (both static and shared libraries can be used as DL libraries。
創建方法:
ar rcs libmy_library.a file1.o file2.o
soname: version number
library
realname: soname
linkername: 以
ldconfig
有如下的指向關系
soname -> realname
linkername -> realname
例子如下所示:
soname ----> /usr/lib/libreadline.so.3 -> /usr/lib/libreadline.so.3.0
realname ----> /usr/lib/libreadline.so.3.0
linkername ----> /usr/lib/libreadline.so -> /usr/lib/libreadline.so.3
所以一般的情況是
linkername -> soname -> realname
當執行一個。/etc/ld.so.preload 文件當中指示那些預加載的,優先級高於一般,為了提高加載效率,不用每次執行一個程序都去搜索,便有了文件,每次有新的。
4.3.1 LD_LIBRARY_PATH
LD_LIBRARY_PATH程序加載運行期間查找動態鏈接庫時指定除了系統默認路徑之外的其他路徑,注意,
export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH
4.3.2 LIBRARY_PATH
LIBRARY_PATH程序編譯期間查找動態鏈接庫時指定查找共享庫的路徑,例如,指定
export LIBRARY_PATH=LIBDIR1:LIBDIR2:$LIBRARY_PATH
4.3.3 LD_PRELOAD
這個變量的作用類似於/etc/ld.so.preload
4.3.4 LD_DEBUG=files/libs/bindings/versions/help
通過這個變量的設置會顯示
為了讓動態鏈接庫為系統所共享,還需運行動態鏈接庫的管理命令--ldconfig.
ldconfig命令的用途,主要是在默認搜尋目錄(/lib和/usr/lib)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,搜索出可共享的動態鏈接庫(格式如前介紹,lib*.so*),進而創建出動態裝入程序(ld.so)所需的連接和緩存文件.緩存文件默認為/etc/ld.so.cache,此文件保存已排好序的動態鏈接庫名字列表。
ldconfig通常在系統啟動時運行,而當用戶安裝了一個新的動態鏈接庫時,就需要手工運行這個命令。
ldd:首先,設置某個變量,,然後,執行這個程序。
gcc -fPIC -g -c -Wall a.c
gcc -fPIC -g -c -Wall b.c
gcc -shared -Wl,-soname,libmystuff.so.1 \
-o libmystuff.so.1.0.1 a.o b.o -lc
-fPIC與-fpic比較,fPIC編譯的文件比較大,和平台無關,fpic編譯的比較小,和平台有關。不用使用-fomit-frame-pointer這個編譯參數除非你不得不這樣。雖然使用了這個參數獲得的函數庫仍然可以使用,但是這使得調試程序幾乎 沒有用,無法跟蹤調試。需要使用“-Wl,-export-dynamic”這個選項參數。通常,動態函數庫的符號表裡面包含了這些動態的對象的符號。 這個選項在創建ELF格式的文件時候,會將所有的符號加入到動態符號表中。可以參考ld的幫助獲得更詳細的說明。如果在linux可以用``-rdynamic'' 代替``-Wl,export-dynamic''。
在開發過程中,想修改一個庫,但該庫也用於許多其他程序, 你不希望其他程序使用修改的庫,只讓一個特定的應用程序測試,一個鏈接選項:`rpath'
-Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)
使用動態加載庫:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main(int argc, char **argv) {
void *handle;
double (*cosine)(double);
char *error;
handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);
if (!handle) {
fputs (dlerror(), stderr);
exit(1);
}
cosine = dlsym(handle, "cos");
if ((error = dlerror()) != NULL) {
fputs(error, stderr);
exit(1);
}
printf ("%f\n", (*cosine)(2.0));
dlclose(handle);
}
編譯命令為:
gcc -o foo foo.c -ldl
http://tldp.org/HOWTO/Program-Library-HOWTO/