unload — 컴파일된 기계어 라이브러리 내리기

unload — 컴파일된 기계어 라이브러리 내리기

load로 올린 공유 라이브러리를 다시 내리고 싶을 때가 있어요. 오래 실행되는 Tcl 프로그램에 C 모듈을 임시로 설치했다가, 더 안 쓰거나 새 버전으로 갱신하기 위해 제거하려면 전체 Tcl 프로세스를 끄는 대신 unload를 쓰면 돼요. 이 명령어가 라이브러리를 프로세스 주소 공간에서 내려주는 역할을 해요.

출처: 문서

본문

문법

unload ?switches? fileName
unload ?switches? fileName prefix
unload ?switches? fileName prefix interp

이 명령어는 이전에 load로 응용 프로그램의 주소 공간에 올린 공유 라이브러리를 내리려고 시도해요. fileName은 내릴 라이브러리가 담긴 파일의 이름으로, 라이브러리를 올릴 때 load에 준 파일 이름과 같아야 해요.

prefix 인자는 (load가 결정했거나 load에 전달된) 프리픽스로, unload 프로시저의 이름을 계산하는 데 쓰여요. 지정하지 않으면 load와 같은 방식으로 fileName에서 계산돼요.

interp 인자는 패키지를 내릴 인터프리터의 경로 이름이에요(interp 매뉴얼 참조). interp를 생략하면 unload 명령어가 호출된 인터프리터가 기본값이 돼요.

unload의 처음 인자들이 -로 시작하면 그 인자들은 스위치로 취급돼요. 현재 지원되는 스위치는 다음과 같아요.

-nocomplain

모든 오류 메시지를 억제해요. 이 스위치가 주어지면 unload는 절대 오류를 보고하지 않아요.

-keeplibrary

이 스위치는 unload가 라이브러리를 프로세스에서 내리는 운영체제 호출을 발행하지 못하게 해요.

--

스위치의 끝을 표시해요. 다음에 오는 인자는 -로 시작하더라도 fileName으로 취급돼요.

UNLOAD 동작

공유 라이브러리가 담긴 파일이 load 명령어로 로드되면, Tcl은 그 라이브러리 파일에 두 개의 참조 카운트를 연결해요. 첫 번째 카운터는 그 라이브러리가 일반(trusted) 인터프리터에 몇 번 로드됐는지, 두 번째는 safe 인터프리터에 몇 번 로드됐는지를 나타내요. 공유 라이브러리 파일이 담긴 파일은 Tcl에 (그 파일에 대한 첫 load 호출로) 한 번만 로드될 수 있으므로, 이 카운터들은 그 라이브러리를 사용하는 인터프리터가 몇 개인지 추적해요. 첫 로드 이후의 각 load 호출은 해당 참조 카운트를 1씩 증가시킬 뿐이에요.

unload는 반대 방향으로 동작해요. 첫 단계로 unload는 라이브러리가 내릴 수 있는(unloadable) 것인지 확인하는데, 내릴 수 있는 라이브러리는 특별한 unload 프로시저를 내보내요. unload 프로시저의 이름은 prefix와 대상 인터프리터가 safe인지 여부로 결정돼요. 일반 인터프리터의 경우 초기화 프로시저 이름은 pfx_Unload 형태예요. 여기서 pfxprefix와 같되 첫 글자는 대문자로, 나머지 글자는 모두 소문자로 변환된 것이에요. 예를 들어 prefixfooFOo라면 초기화 프로시저 이름은 Foo_Unload가 돼요. 대상 인터프리터가 safe 인터프리터라면 초기화 프로시저 이름은 pkg_Unload 대신 pkg_SafeUnload가 돼요.

unload가 라이브러리를 내릴 수 없다고 판단하면(또는 unload 기능이 컴파일 중에 비활성화됐다면), 오류가 반환돼요. 라이브러리를 내릴 수 있다면 unload는 unload 프로시저를 호출해요. unload 프로시저가 TCL_OK를 반환하면 unload는 진행해 (대상 인터프리터 유형에 따라) 올바른 참조 카운트를 감소시켜요. 두 참조 카운트가 모두 0에 도달하면 라이브러리는 프로세스에서 분리돼요.

UNLOAD 훅 프로토타입

unload 프로시저는 다음 프로토타입을 따라야 해요.

typedef int Tcl_PackageUnloadProc(
        Tcl_Interp *interp,
        int flags);

interp 인자는 라이브러리를 내릴 인터프리터를 식별해요. unload 프로시저는 성공 여부를 나타내기 위해 TCL_OK 또는 TCL_ERROR를 반환해야 해요. 오류의 경우 인터프리터 결과를 오류 메시지를 가리키도록 설정해야 해요. 이 경우 unload 명령어의 결과는 unload 프로시저가 반환한 결과가 돼요.

flags 인자는 TCL_UNLOAD_DETACH_FROM_INTERPRETER 또는 TCL_UNLOAD_DETACH_FROM_PROCESS가 될 수 있어요. unload 프로시저가 반환한 뒤에도 라이브러리가 프로세스에 붙어 있을(즉 다른 인터프리터가 그 라이브러리를 사용하는) 경우 TCL_UNLOAD_DETACH_FROM_INTERPRETER가 정의돼요. 반면 라이브러리를 대상 인터프리터만 사용하고, unload 프로시저가 반환하자마자 응용 프로그램에서 분리될 경우 flagsTCL_UNLOAD_DETACH_FROM_PROCESS로 설정돼요.

참고 사항

  • unload 명령어는 응용 프로그램과 정적으로 링크된 라이브러리는 내릴 수 없어요.
  • fileName이 빈 문자열이면 prefix 인자를 반드시 지정해야 해요.
  • prefix를 생략하거나 빈 문자열로 지정하면 Tcl은 프리픽스를 추측하려 해요. 이는 플랫폼에 따라 다르게 동작할 수 있어요. 대부분의 UNIX 플랫폼에서 쓰는 기본 추측은 fileName의 마지막 요소를 가져와, 처음 세 글자가 lib이면 떼어내고, 이어지는 영문자·밑줄 문자를 titlecase로 변환해 프리픽스로 쓰는 방식이에요. 예를 들어 unload libxyz4.2.so는 프리픽스 Xyz를, unload bin/last.so {}는 프리픽스 Last를 사용해요.

이식성 이슈

Unix — 모든 유닉스 운영체제가 라이브러리 언로딩을 지원하는 건 아니에요. 그런 운영체제에서는 (-nocomplain을 지정하지 않는 한) unload가 오류를 반환해요.

알려진 버그

같은 파일이 서로 다른 fileName으로 로드되면, 그 파일은 프로세스 주소 공간에 여러 번 로드돼요. 그 동작은 시스템마다 달라요(어떤 시스템은 중복 로드를 감지하고, 어떤 시스템은 그렇지 못해요). 운영체제가 조용히 라이브러리를 분리한 경우(그 결과 Tcl이 라이브러리가 여전히 로드됐다고 생각하는 경우), 그런 라이브러리에 unload를 쓰는 것은 위험할 수 있어요. 일부 인터프리터가 계속 사용하는 동안 라이브러리가 응용 프로그램에서 완전히 분리되거든요.

예제

foobar.dll 파일의 내릴 수 있는 모듈이 load 명령어로 (Windows에서) 이렇게 로드됐다면:

load c:/some/dir/foobar.dll

이렇게 내릴 수 있어요:

unload c:/some/dir/foobar.dll

이렇게 하면 C 코드 모듈을 오래 실행되는 Tcl 프로그램에 임시로 설치했다가, (더 필요 없거나 새 버전으로 갱신할 때) 전체 Tcl 프로세스를 끄지 않고도 다시 제거할 수 있어요.

더 알아보기

  • info sharedlibextension, load, safe — 라이브러리·safe 인터프리터 관련 명령어
  • 관련 키워드: binary code, unloading, safe interpreter, shared library