smbd 실행 시 Out of Memory 또는 실행이 되더라도 정상적으로 동작하지 않을때, 디버깅 및 실행에 관련된 사항을

확인하기 위하여, smbd 를 foreground 및 stdout 옵션을 주어 실행되는 내용을 확인한다.

 

$ smbd -F -S --debuglevel 3

 

위와 같은 메세지가 출력되는 것을 확인 할 수 있으며, 아래와 같이 top 으로 확인 시 메모리가 계속해서 누수가 발생하여, 결국 Out of Memory 로 인해 커널에서 프로세스가 죽게된다.

이런 경우, 위의 Debug 메세지와 같이 iconv 에서 변환하려는 과정에서 Memory Leak 이 연속적으로 발생하게 되고,

메모리 한계치에 도달하게 되면 위와 같이 프로세스가 강제로 죽게된다.

 

이 문제점을 해결하기 위해 /etc/samba/smb.conf 에서 아래의 옵션을 추가하여 iconv 함수 내에서 memory leak을 우회하여, samba가 정상적으로 동작 할 수 있도록 설정하여 막을 수 있다.

 

dos charset = UTF-8
display charset = UTF-8

 

위의 옵션을 추가하여 재실행을 하거나, cp850.so 파일을 생성하여 해결이 가능하지만, utf-8 로 손쉽게 처리가 가능하다.

포팅된 touchscreen을 TSLIB에서 사용하기 위해서, ts_test 등의 tslib를 사용 할 때,

나타나는 현상


/dev/input/event0로에서 'cat /dev/input/event0 | hexdump' 를 통해 정상적 이벤트가 발생됨을 확인을 전제


TSLIB 환경변수 및 ts.conf 또한 정상적으로 세팅 되어있을때,


동작하지 않을경우에는 커널버전 과 TSLIB Protocol 버전 또는


evbit 등의 세팅이 맞지 않을경우이다.


최신의 TSLIB는 뜨지 않으며, 낮은버전을 사용할 경우 발생 하게 되는데

patch work를 통해 확인한 결과는 아래와 같다.


 static int check_fd(struct tslib_input *i)
 {
 	struct tsdev *ts = i->module.dev;
 	int version;
-	u_int32_t bit;
-	u_int64_t absbit;
+	long evbit[BITS_TO_LONGS(EV_CNT)];
+	long absbit[BITS_TO_LONGS(ABS_CNT)];
+	long keybit[BITS_TO_LONGS(KEY_CNT)];
 
-	if (! ((ioctl(ts->fd, EVIOCGVERSION, &version) >= 0) &&
-		(version == EV_VERSION) &&
-		(ioctl(ts->fd, EVIOCGBIT(0, sizeof(bit) * 8), &bit) >= 0) &&
-		(bit & (1 << EV_ABS)) &&
-		(ioctl(ts->fd, EVIOCGBIT(EV_ABS, sizeof(absbit) * 8), &absbit) >= 0) &&
-		(absbit & (1 << ABS_X)) &&
-		(absbit & (1 << ABS_Y)) && (absbit & (1 << ABS_PRESSURE)))) {
-		fprintf(stderr, "selected device is not a touchscreen I understand\n");
+	if (ioctl(ts->fd, EVIOCGVERSION, &version) < 0) {
+		fprintf(stderr, "tslib: Selected device is not a Linux input event device\n");
 		return -1;
 	}
 


위와 같이 input-raw.c 에서 EV_VERSION과 ,evbit과 absbit 등을 ioctl로 확인 후에 touch driver로 인식한다.

이 과정에서 맞지 않을 경우 비정상 종료가 이루어져 driver가 제대로 호출되지 않게 된다.


그에 따라 input driver의 bit세팅값 또는 EV_VERSION을 확인해야 한다.


단적인 예로


낮은버전은 0x010000이여야만 가능하다.


TSLIB가 높은 경우 + 코드와 같이 버전과 관계없이 실행된다.

File - "<kernel home>/include/linux/input.h"

-- #define EV_VERSION              0x010000

++ #define EV_VERSION              0x010001

이외의 상황이라면,

driver의 문제 또는 ts.conf의 값을 변경해야함

라이브러리 로딩 ld.so.conf



  라이브러리란 프로그램들이 공통으로 사용할 수 있는 기능을 포함하고 있는 오브젝트 파일입니다.  


  동적 라이브러리는 프로그램을 컴파일하여 생성되는 바이너리에 포함하지 않고 바이너리가 실행하는 시점 또는 실행 후에 포함시킬 수 있도록 제작된 라이브러리를 말합니다. 그래서 동적이라는 이름이 붙게 된 것입니다. 이런 형ㅌ식의 라이브러리는 프로그램을 실행할 때 호출되는 로더에 의해서 메모리에 적재됩니다.


  동적 라이브러리를 호출하기 위해서는 path 지정이 필수적입니다. 해당 라이브러리가 어디에 위치해 있는지 모든 디렉토리를 탐색하고 로드하기에는 비효율적이기 때문입니다. 우리가 흔히 설정하는 LD_LIBRARY_PATH 환경변수가 동적 라이브러리 호출을 위한 path 지정에 사용되는 환경 변수이며 또 다른 방법으로는 시스템 설정을 통해서 지정할 수 있습니다. 시트템 설정을 위한 설정 파일이 리눅스는 /etc/ld.so,conf 파일 입니다. Kernel 버전이 2.6 이상부터는 /etc/ld.so.conf.d/ 디렉토레 내에 *.conf 파일 형식으로 여려 파일을 통해 설정을 할 수 있습니다.


  로더는 LD_LIBRARY_PATH 또는 ld.so.conf에 명시된 디렉토리 내에서 동적 라이브러리를 찾으며 해당 디렉토리에 없으면, Not Found 에러를 출력합니다. 컴파일 시 Link 오류나 실행시 Loading 오류가 발생한다면 우선적으로 두가지 설정을 확인해 봐야 합니다.


  LD_LIBRARY_PATH 나 ld.so.conf 두 곳 모두 설정할 필요는 없으나 다음과 같은 경우에는 ld.so.conf 에 설정하도록 유의해야 합니다. 바이너리에 setuid, setgid 등이 설정된 경우 리눅스의 로더는 LD_LIBRARY_PATH 환경 변수 설정을 무시해 버린다고 합니다. 그도 그럴것이 악의적으로 시스템 주요 함수들이 setuid를 가진 바이너리가 호출한 라이브러리에 의해서 오버라이딩 된다면 시스템에 엄청난 일을 가져다 줄 것 입니다.(프로세스 등의 문제들, 해킹) 그런 보안을 고려한 것인지 모르겠지만 로더는 ( uid != euid || gid != egid ) 상황에서 LD_LIBRARY_PATH 를 무시하기 때문에 아무리 컴파일시에 link가 정상이고 ldd로 확인해도 정상이지만 바이너리 실행시 해당 라이브러리를 찾을 수 없다는 오류를 만나게 됩니다. 이런 경우는 LD_LIBRARY_PATH가 아니라 ld.so.conf 에 설정을 해줘야 합니다.

 


관련 명령어 :

  • ldconfig - /etc/ld.so.conf 설정된 동적 라이브러리 정보를 /etc/ld.so.cache 파일로 만들어 주는 일을 한다. 이로서 로더는 ld.so.cache 정보를 기반으로 보다 빠르게 라이브러리를 찾아 낼 수 가 있다. ld.so.conf 설정을 변경하면 반드시 ldconfig 명령을 수행하여 cache 를 갱신해 주도록 하자.
  • ldconfig
    ldconfig -p

  • ldd - 공유 라이브러리의 의존성을 검사해 준다. 동적 라이브러리도 공유 라이브러리 이므로 link 시나 load 시에 에러가 난다면 점검을 해보자.
  • ldd <binary name>

  •  objdump - 오브젝트 파일에 대한 정보를 출력해 준다. Dynamic Section의 NEEDED 로 표기된 항목이 공유 라이브러리를 표시한다고 한다.
  • objdump -p <object(binary) name>


관련 링크 :  




'System Programming > Linux Kernel' 카테고리의 다른 글

udev  (0) 2016.09.12
커널 타이머  (0) 2016.06.08
[Linux] ticket spin lock  (0) 2016.05.17
spin_lock, spin_lock_irq, spin_lock_irqsave  (2) 2016.05.17

크로스 컴파일 실행파일 no such file or directory 문제




크로스 컴파일 하여 타겟 보드에 넣었을 때 실행되지 않고,

no such file or directory 가 출력되는 경우에 해결하는 방법입니다.


실행시 no such file or directory가 출력되는 실행파일을 file 명령어를 통해

Shared Library를 확인 합니다.


file 해당파일

ex)

test: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.16, not stripped


file 명령어를 실행하면 그 파일의 ELF 정보 및 사용하는 공유 라이브러리 정보가 나옵니다.


실행파일에서 사용하는 공유라이브러리가 /lib 혹은 /etc/ld.so.conf 파일에 저장되어 있는 경로에 있는지 확인 합니다.


없을 경우에는 타겟보드에 저장된 올바른 라이브러리 파일을 생성하거나 심볼릭 링크를 통해 생성 합니다.



ex) ld-linux.so.3 파일이 없어서 나타나는 경우


/lib 디렉토리내에 ld-linux.so.3가 없어 나타나는 경우에는 대게 arm 라이브러리 중 ld-linux-armhf.so.3가 있습니다.


ld-linux.so.3는 프로그램이 메모리에 적재되는 시점에서 실행에 필요한 라이브러리를 링킹해주는 파일입니다.


이 링킹은 target platform인 Arm 에서는 ld-linux-armhf.so.3가 담당합니다. 그에 따라 복사 또는 파일명 변경이 아닌 심볼릭 링크를 걸어주어야 합니다.



sudo ln -s /lib/ld-linux-armhf.so.3 /lib/ld-linux.so.3


정상적으로 파일을 생성 혹은 링크했다면, 재실행 시 문제되지 않고 정상 실행이 될 것 입니다.

+ Recent posts