분류없음2014.12.01 19:50

natas4:Z9tkRkWmpt9Qr7XrR5jWRkgOU901swEZ

 

natas5:iX6IOfmpN7AYOQGPwtn3fXpbaJVJcHfq

 

natas6:aGoY4q2Dc6MgDq4oL4YtoKtyAg9PeHa1

natas7:7z3hEENjQtflzgnT29q7wAvMNfZdh0i9

natas8;DBfUBfqQG69KvJvJ1iAbMoIpwSNQ9bWe

natas9:W0mMhUcRRnG8dcghE4qvk3JA9lGt8nDl

natas10:nOpp1igQAkUzaI1GUUjzn1bFVj7xCNzu

natas11:U82q5TCMMQ9xuFoI3dYX61s7OZD9JKoK

natas12:EDXp0pS26wLKHZy1rDBPUZk0RKfLGIR3
natas13:jmLTY0qiPZBbaKc9341cqPQZBJv7MQbY
natas14:Lg96M10TdfaPyVBkJdjymbllQ5L6qdl1


natas12.html


natas13.php


 

Posted by 오리지날초이
Linux2014.09.23 14:28

1. logconv 라는 방화벽전용 파일을 타 서버에서 사용하고 싶음


2. 막상 copy 하고 실행하면 특정 lib 가 없다는 메세지가 나옴


3. 없는 so 파일을 원본서버에서 copy 함


4. 위 방법대로 하면 노가다이므로 ldd -v ogconv 로 관련 lib 를 모두 확인


5. 필요한 lib 를 모두 복사해 옴


6. export LD_LIBRARY_PATH="내 작업용 폴더" 로 신규 등록 또는 

   /etc/ld.so.conf 에 "내 작업용 폴더" 등록


7. ldconfig -p 로 LD_LIBRARY_PATH 를 메모리 에 올리고 확인함


8 .ldd -v logconv 로 확인하면 작업 폴더의 관련 모듈이 반영되어 있음



참고 : http://www.misari.codns.com/bbs/board.php?bo_table=linux&wr_id=9154&sfl=&stx=&sst=wr_hit&sod=desc&sop=and&page=5

Linux 시스템의 glibc 패키지의 버전을 바꾸지 않고 다른 버전을 glibc를 사용하고 싶은 경우가 있다면 어찌 해야 하나?

동적 라이브러리(so)를 사용하지 않는다면 문제가 되지 않지만 동적 라이브러리를 사용한다면 문제가 된다. ldd를 통해서 보이는 최종 라이브러리 경로를 시스템 기본 경로가 아닌 다른 경로로 바꾸어야 하는 것이 과제이다.

다른 라이브러리는 LD_LIBRARY_PATH 환경 변수를 통해서 변경을 하는 것이 가능하지만 dynamic linker는 절대 경로로 잡혀 있어서 이 방법도 통하지 않는다.

1. dynamic linker 위치 변경하기

ld의 옵션 중에 –dynamic-linker 옵션을 사용하면 다른 dynamic linker를 사용하도록 하는 것이 가능하다. 다음과 같다.

$ gcc -Wl,–dynamic-linker=/<some where>/lib/ld-linux.so.2 <…>

2. 라이브러리 경로 추가하기

시스템의 ld.so.conf 등에 설정된 라이브러리 경로 보다 우선하는 경로를 추가할 수 있다. LD_LIBRARY_PATH 환경 변수를 사용하는 방법도 있지만 불편하다. /etc/ld.so.conf 를 수정하는 것은 다른 프로그램에도 영향을 미치므로 사용하기 어렵다.

ld의 -rpath 옵션을 사용하면 된다. 다음과 같다.

$ gcc -Wl,-rpath=/<some where>/lib:/<some where>/usr/lib <…>

3. Runtime에 변경하기

이미 컴파일된 바이너리를 다른 버전의 glibc로 변경을 할 수 있다. 다음과 같다.

$ /<some where>/lib/ld-linux.so.2 –library-path /<some where>/lib:/<some where>/usr/lib ./a.out

a.out은 변경하고자 하는 실행 파일이다. 현재 디렉토리에 있더라고 ./를 붙여주어야 한다. –library-path 다음에는 =가 아닌 공백이 있다는 것에도 주의하자.

–list 옵션은 ldd와 같은 결과를 보여준다. 실제 실행 예는 아래와 같다.

$ /tmp/lib/ld-2.12.so –list –library-path /tmp/lib ./a.out      
        linux-gate.so.1 =>  (0×00288000) 
        libc.so.6 => /tmp/lib/libc.so.6 (0x008f6000) 
        /lib/ld-linux.so.2 => /tmp/lib/ld-2.12.so (0x008d0000)

자세한 내용은 man ld.so 하면 된다.


'Linux' 카테고리의 다른 글

바이너리 파일 옮겨서 사용하기  (0) 2014.09.23
so 파일 import 로 바이너리 실행환경 만들기  (0) 2014.09.23
idnoe 개념  (0) 2014.04.24
원격파일 복사  (0) 2014.04.22
리눅스 bash 고급  (0) 2014.02.24
linux bash 응용  (0) 2013.12.03
Posted by 오리지날초이
Linux2014.09.23 10:09

http://adnoctum.tistory.com/541



리눅스에서 어떠한 프로그램을 설치할 때 무슨무슨 so 파일, 가령 libX11.so.6 파일처럼 *.so.* 파일이 없다고 할 때는 다음과 같은 방법으로 문제를 해결해야 한다. 

   우선 so 파일이 무엇인지 알아 보자. so 파일은 shared object 파일이란 뜻으로 *.so.* 일텐데, 특정한 기능을 구현해 놓은 파일을 의미한다. 즉, 프로그램들은 일반적으로 필요한 기능을 전부 구현하기 보다는 특정 기능이 이미 구현되어 있으면 그 기능이 구현된 파일을 메모리에 올린 후 그 기능을 사용하게 된다. 마치 물건을 조립하는 것과 비슷한 이치인데, 컴퓨터를 조립할 때 쿨러가 필요하면 쿨러를 만드는 회사에서 잘만쿨러 같은 것을 사서 붙이듯이, 예를 들면 인터넷에서 파일을 다운로드 받는 기능이 필요하면 그 기능이 구현된 파일을 메모리에 올린 후 그 기능을 사용하게 되는 것이다. 이처럼 한 프로그램이라 하더라도 일반적으로 사용되는 여러 기능이 내부에서 다른 so 파일들을 통해서 이루어 지게 된다.

   그래서, 만약 내가 설치하고자 하는 파일이 특정 기능 때문에 어떤 so 파일이 필요하다고 할 때, 어떤 경우는 설치시 so 파일 존재 여부를 확인해 보거나, 어떤 경우는 설치된 이후 실제 so 파일에 구현된 기능이 필요할 때 메모리에 올리기 위해 그 so 파일을 찾다가 없어서 에러가 날 때도 있다. 그런 경우 주로 다음과 같은 에러 메세지가 나타난다. 

libstdc++.so.5: cannot open shared object file: No such file or directory
libgcc_s.so.1: cannot open shared object file: No such file or directory


왜 저런 말이 나타냤느냐 하면, 일반적으로 so 파일을 어디에서 찾아야 하는지를 설정해 놓은 경로를 모두 찾아 보았음에도 불구하고 libstdc++.so.5 와 libgcc_s.so.1 파일을 찾을 수 없었기 때문이다. 물론 저 파일이 실제로 어딘가에 있기 때문에, 심지어 현재 경로에 있기 때문에 대체 왜 저런 에러가 나타났을까 의아해 할 수도 있는데, so 파일은 그것과 상관이 없이 다음과 같은 순서로 경로들을 순회하면서 찾게 되고, 그렇게 돌았던 경로에서 찾지 못하면 위와 같은 에러 메세지가 나타난다. 

so 파일을 찾는 경로 설정
1. system default 경로
2. LD_LIBRARY_PATH
3. binary code 에 hard-coding 된 경로


(비슷한 개념으로 경로 설정에 관해 쓴 예전 글)

1. system default 경로

   일반적으로 /usr/local/bin 과 /usr/bin 이다. 이 값은 /etc/ld.so.conf 파일에 설정이 된 값이다. 한 번 살펴 보자. 



즉, /etc/ld.so.conf 파일에 설정된 경로를 차례대로 돌아 가면서 원하는 so 파일을 찾는다. 물론, 만약 내가 어떤 프로그램을 만들었고, 그것을 내 프로그램이 설치된 경로 밑의 lib 경로에 넣고 그것을 ld.so.conf 에 넣고 싶으면, /etc/ld.so.conf.d/ 경로 밑에 *.conf 파일 이름으로 저장 후 그 파일에 그 경로를 집어 넣으면 된다는 것을 위 첫 번째 줄로부터 알 수 있다. 즉, 첫 번째 줄이 

include ld.so.conf.d/*.conf

이니까, ld.so.conf.d 경로에 있는 conf 로 끝나는 파일들을 살펴 보면, 

[adnoctum@bioism ~]$ ll /etc/ld.so.conf.d/
total 16
-rw-r--r-- 1 root root 15 Sep  4  2009 mysql-i386.conf
-rw-r--r-- 1 root root 20 Sep 14  2007 qt-i386.conf
-rw-r--r-- 1 root root 25 Dec 10 08:44 xulrunner-32.conf

가 있고, 여기서 다시 mysql-i386.conf 파일의 내용을 보면, 

[adnoctum@bioism ~]$ more /etc/ld.so.conf.d/mysql-i386.conf
/usr/lib/mysql

꼴랑 한 줄이다. 즉, include 구문에 의해, ld.so.conf.d 안에 있는 *.conf 파일의 내용들이 ld.so.conf 파일에 모두 들어 가게 된다. 그냥 ld.so.conf 파일에 모두 넣지 왜 이렇게 하나 궁금할 수도 있는데, 만약 어떤 프로그램이 10 개의 경로에 so 파일을 분산시켜 넣는다고 하면 괜히 그것 때문에 ld.so.conf 파일이 지저분해 지게 되고, 또 다른 so 파일을 찾을 때 그것 때문에 여러 경로를 순회하므로 다른 프로그램들 성능까지 떨어 뜨리게 된다. 만약 그렇게 지저분했던 프로그램을 지우면 더 골치아파지겠지. 저렇게 했다면 ld.so.conf.d 에 있던, 가령 myprogam.so.conf 파일 (이 파일이 10개의 경로를 갖고 있었다면) 만 지우면 간단히 해결되는 것이었음에도 불구하고, 그 내용이 모두 ld.so.conf 파일에 있었다면 그 경로를 지워도 되는지 (다른 so 파일이 거기 있었으면 지우면 안 될테니까) 아닌지 곤란해 지게 된다1. 하여튼, 저렇게 되어 있는 것이 깔끔하다. 

저렇게 수정을 했으면 적용하기 위해 ldconfig 명령어를 실행시켜 준다. 


2. LD_LIBRARY_PATH

   이 값은 환경 변수인데, 다음과 같이 직접 써 넣어 줄 수 있다. 

~/.bash_profile 파일 내용중 일부.



물론 이렇게 한 후 그것을 적용시키기 위해 source 를 해줘야 겠지. 

[adnoctum@bioism ~]$ source ~/.bash_profile

그런데 이런 방법은 그리 권장되는 것은 아닌듯 싶다. 


3. binary code에 hard-coding 된 경로
   
   이 경우는 프로그래머가 아예 소스 코드에 so 파일 경로를 설정해 버린 경우인데, 실제의 예는, 내가 동적 라이브러리를 설명한 글에서 가져 온 다음의 코드이다. 

    9         const char* lib_path[] = { "/home/adnoctum/test/libabcd.so.1.0",

   10                                              "/home/adnoctum/test/libabcc.so.1.0"};



그런데 이런 경우는 별로 없을 것이다. 또한 이런 경우 문제가 생기면 사용자가 해결할 수 있는 유일한 방법은 그 경로에 so 파일을 가져다 놓는 것인데, 프로그래머가 hard-coding 한 경로를 알지 못하면 도무지 방법이 없겠지. 하여튼 이런 경우는 거의 없다. 


위와 같이 설정된 경로에서 찾지 못했다고 한 so 파일은 그렇다면 어디에 있는가? 일단 locate 명령어로 찾아 본다. 그런데 아직 index 가 update 되지 않았을지도 모르므로 root 권한으로 updatedb 를 해주고 나서 locate 를 해준다. 

(물론 위 결과는 실제 의미 없다. 저 위 에러 메세지도 나에게서 난 것은 아니다. 그냥 구글링 결과에서 가져 왔을 뿐이다)


그렇게 해서 원하는 so 파일을 찾았으면 /etd/ld.so.conf 파일에 그 so 파일이 있는 경로를 집어 넣거나, 아니면 so 파일을 /usr/local/bin 과 같은 곳으로 이동시키거나 link 를 만들어 준다. 그런데 일반적으로 프로그램은 여러 개의 so 파일이 사용하게 되므로 하나 옮기거나 링크 만들어도 또 다른 so 파일에서 동일한 에러가 날 수 있으므로 ld.so.conf 파일에 그 경로를 집어 넣는 것이 좋아 보인다. 혹은 LD_LIBRARY_PATH 에 그 경로를 덧붙이거나. 

그런데 locate 로 했는데 정말로 원하는 so 파일이 없는 것이라면, 마지막 방법으로 구글링을 해본다. 그러면 그 so 파일이 어떤 라이브러리에 있는지, 그래서 어떤 라이브러리를 설치해야 하는지를 알 수 있다. 다음처럼. 





  1. 윈도우즈에서도 프로그램 삭제할 때 "다른 프로그램이 이 파일의 기능을 사용할 수도 있는데 지울 것이냐?" 하고 dll 파일 삭제하기 전에 묻는 경우를 많이 봤을 것이다. 이 경우와 완전히 같다. [본문으로]



'Linux' 카테고리의 다른 글

바이너리 파일 옮겨서 사용하기  (0) 2014.09.23
so 파일 import 로 바이너리 실행환경 만들기  (0) 2014.09.23
idnoe 개념  (0) 2014.04.24
원격파일 복사  (0) 2014.04.22
리눅스 bash 고급  (0) 2014.02.24
linux bash 응용  (0) 2013.12.03
Posted by 오리지날초이