2013-10-11 30 views
10

我有一個hello world程序。在共享庫的構建選項中添加「-rpath,/ usr/lib」導致段錯誤

#include <stdio.h> 
#include <stdlib.h> 

int main() 
{ 
    printf("hello world! \n"); 
    return 0; 
} 

我在連鎖相方案的構建,以鏈接到庫libmicroxml.so

添加-lmicroxml當我啓動我的程序,我得到一個分段錯誤。分段故障與libmicroxml.so的負載有關。我helleo世界程序執行後strace的位置:

strace ./test 
execve("./test", ["./test"], [/* 11 vars */]) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777de000 
stat("/etc/ld.so.cache", 0x7f944760) = -1 ENOENT (No such file or directory) 
open("/lib/libmicroxml.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) 
open("/lib/libmicroxml.so.1", O_RDONLY) = -1 ENOENT (No such file or directory) 
open("/usr/lib/libmicroxml.so.1", O_RDONLY) = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=4129, ...}) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0\4p\0\0\0004"..., 4096) = 4096 
old_mmap(NULL, 69632, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x777b3000 
old_mmap(0x777b3000, 1572, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x777b3000 
old_mmap(0x777c3000, 1648, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x777c3000 
close(3)        = 0 
munmap(0x777dd000, 4096)    = 0 
open("/lib/libgcc_s.so.1", O_RDONLY) = 3 
fstat(3, {st_mode=S_IFREG|0644, st_size=78232, ...}) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0006\320\0\0\0004"..., 4096) = 4096 
old_mmap(NULL, 147456, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7778f000 
old_mmap(0x7778f000, 76928, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x7778f000 
old_mmap(0x777b2000, 408, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x13000) = 0x777b2000 
close(3)        = 0 
munmap(0x777dd000, 4096)    = 0 
open("/lib/libc.so.0", O_RDONLY)  = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=413076, ...}) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0\253`\0\0\0004"..., 4096) = 4096 
old_mmap(NULL, 503808, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x77714000 
old_mmap(0x77714000, 405592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x77714000 
old_mmap(0x77787000, 7572, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x63000) = 0x77787000 
old_mmap(0x77789000, 21036, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x77789000 
close(3)        = 0 
munmap(0x777dd000, 4096)    = 0 
open("/usr/lib/libgcc_s.so.1", O_RDONLY) = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=169712, ...}) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0\307\220\0\0\0004"..., 4096) = 4096 
old_mmap(NULL, 237568, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x776da000 
old_mmap(0x776da000, 169036, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x776da000 
old_mmap(0x77713000, 1776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x29000) = 0x77713000 
close(3)        = 0 
munmap(0x777dd000, 4096)    = 0 
open("/usr/lib/libc.so.0", O_RDONLY) = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=425968, ...}) = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
read(3, "\177ELF\1\2\1\0\0\0\0\0\0\0\0\0\0\3\0\10\0\0\0\1\0\0\267`\0\0\0004"..., 4096) = 4096 
old_mmap(NULL, 516096, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7765c000 
old_mmap(0x7765c000, 418924, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0x7765c000 
old_mmap(0x776d2000, 8176, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x66000) = 0x776d2000 
old_mmap(0x776d4000, 21784, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x776d4000 
close(3)        = 0 
munmap(0x777dd000, 4096)    = 0 
open("/lib/libc.so.0", O_RDONLY)  = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=413076, ...}) = 0 
close(3)        = 0 
stat("/lib/ld-uClibc.so.0", {st_mode=S_IFREG|0755, st_size=28976, ...}) = 0 
open("/lib/libc.so.0", O_RDONLY)  = 3 
fstat(3, {st_mode=S_IFREG|0755, st_size=413076, ...}) = 0 
close(3)        = 0 
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x4000000, -1, 0) = 0x777dd000 
set_thread_area(0x777e4440)    = 0 
mprotect(0x77787000, 4096, PROT_READ) = 0 
mprotect(0x776d2000, 4096, PROT_READ) = 0 
mprotect(0x777da000, 4096, PROT_READ) = 0 
--- SIGSEGV (Segmentation fault) @ 0 (0) --- 
+++ killed by SIGSEGV +++ 
Segmentation fault 

在libmicroxml庫的建立,我發現他們使用DSOFLAGS=-Wl,-soname,libmicroxml.so.1,-rpath,/usr/lib -shared -fPIC庫的構建(在連鎖相)。

我刪除從選項中-rpath,/usr/lib所以新的DSOFLAGS=-Wl,-soname,libmicroxml.so.1 -shared -fPIC

然後我重建庫,然後我推出了Hello World程序和分段錯誤消失

我米,mips_gcc-4.6-linaro_uClibc-0.9.33.2

這個問題的建築是不是我的舊的gcc mips_gcc-4.3.3+cs_uClibc-0.9.30.1

任何一個可以解釋爲何轉載去除聯動選項-rpath,/usr/lib修復庫的負載段錯誤?

+1

'''main'不會返回'int''' – Kninnug

+0

@Kninnug這不是我的問題的原因。任何方式我添加了返回到我的主要功能 – MOHAMED

+0

在您的PC上「locate libmicroxml.so」的輸出是什麼? – stdcall

回答

11

從跟蹤看來你的程序加載相同的模塊,這應該是同一版本的不同的二進制文件:

/lib/libc.so.0(大小:413076個字節)/usr/lib/libc.so.0(大小:425968個字節)。

/lib/libgcc_s.so.1(size:78232 bytes)vs./usr/lib/libgcc_s.so.1(size:169712 bytes)。

這可能是因爲當你在模塊鏈接使用-rpath,你強迫它從/usr/lib加載的模塊,但你的程序中使用是/lib默認的搜索路徑(根據在http://tldp.org/HOWTO/Program-Library-HOWTO/dl-libraries.html的dlopen的文檔)。

因此:您的程序加載/usr/lib/libmicroxml.so.1(請注意,它找不到/lib/libmicroxml.so.1,儘管它首先搜索此路徑)。然後它繼續從/lib加載它需要的模塊(libgcclibc),最後,因爲libmicroxml要求從/usr/lib(因爲提供構建參數)加載這些模塊,所以它們也從此路徑加載。

一旦你有相同的名稱和接口,兩個不同的庫(因爲它們是同一版本)一起裝入,你可以不知道哪個版本,其中函數被調用,這可能會導致不一致。

我想你可以解決這個問題要麼你做的方式,或通過添加相同-rpath參數程序的版本。

原因消除-rpath解決這個問題是在加載時libmicroxml,裝載機首先搜索/lib作爲默認的第一個目錄所需要的模塊(因爲沒有指定其他目錄),並自該文件夾中的模塊已裝入沒有衝突。

在任何情況下,在相同驅動器上使用相同版本的同一模塊具有兩個不同二進制文件的情況非常不健康。

至於GCC版本,我只能假定正確的libc或libgcc與以前的GCC一起使用(甚至安裝),並由新的GCC取代,但我找不到支持該文檔的文檔。

1

你DSOFLAGS看起來是這樣的:

DSOFLAGS=-Wl,-soname,libmicroxml.so.1,-rpath,/usr/lib -shared -fPIC 

你嘗試編譯這個樣子?

gcc -L/usr/lib -Wl,-rpath=/usr/lib -Wall -o test main.c -lmicroxml 

您可以使用此行與CC和CFLAGS在一個Makefile,使編譯簡單,如果你能編譯它這樣。還有其他幾種鏈接方式。

好信息在this鏈接。