2009-06-17 5 views
4

ftest라는 테스트 프로그램이 있습니다. 테스트를 포함하는 .so 파일을로드하고 거기에서 발견 된 테스트를 실행합니다. 이 테스트 중 하나는 O/RM을위한 Postgres 데이터베이스 드라이버가 포함 된 .so를로드하고 실행합니다.공유 객체 (.so)의 Linux 예외

Postgres 드라이버가 .so 파일 (또는 ftest가 연결되지 않고 링크되는 파일)에 정의 된 예외를 throw하고 테스트 프레임 워크에서 캐치되면 예외 소멸자가 세그먼테이션을 트리거합니다.

이 segfault는 컴파일 된 예외가 동적으로로드 된 .so (dload를 사용)에있을 때마다 발생합니다.

동일한 종류의 아키텍처는 Windows에서 잘 작동합니다. 우리는 핵심 라이브러리의 예외 만 사용하도록 자신을 제한하고 싶지 않습니다. 추가 기능은 자체 예외 클래스를 만들고 자유롭게 처리해야합니다.

예외는 std :: exception의 하위 클래스입니다. 경우에 따라 예외 (예 : libpqxx)가 라이브러리에서 정의 될 수 있습니다. 이는 예외가 때때로 우리 제어 범위를 벗어나는 경우도 있음을 의미합니다.

예외가 같은 것을 사용 던져 :

throw exception_class(exception_arguments); 

을 그리고 사용 적발 :이 작업을 얻기 위해 필요한 몇 가지 특별한 컴파일러 옵션은

catch (std::exception &e) { 
    // handler code 
} 

있습니까? throw new exception_class(args)을 통해 예외를 던지기 위해 전환해야합니까 (실제로이 작업을 수행하고 싶지는 않습니까)?

답변

6

하여 사용 GCC 가정 -

추가] -Wl, -E 때 실행 호출 dlload를 구축(). 이것은 모든 타입 정보 심볼을 실행 파일에서 내 보낸다. RTTI (예외를 잡을 때)가 제대로 작동하도록해야한다.

VC++는 string을 비교하여 typeinfo와 비교하여 dynamic_cast가 더 느리고 더 작은 바이너리 인 < 등을 생성합니다. g ++는 포인터 비교를 사용합니다.

실행시로드 된 .so로 구현 된 순수 가상 인터페이스 클래스를 사용하려고 할 때 동일한 문제가 발생했습니다.

그물에 떠 다니는 주제와 관련된 몇 가지 기사가 있습니다.

희망, Hayman.

+0

실제로 문제가있는 소멸자입니다. 가상 테이블의 위치라면 놀라지 않을 것입니다. 아마도 .so는 테이블이로드 된 페이지에 대한 읽기 권한을 부여하지 않으므로 소멸자를 읽을 수 없습니다. 그것은 순수한 추측이다. Boost.Build를 통해 이러한 옵션을 설정하는 방법을 알아낼 수 있는지 확인합니다. – KayEss

+0

-Wl, E는 아무런 차이가없는 것처럼 보입니다. ( – KayEss

+0

사실 저는 -Wl, E가 영향을 미쳤습니다. 예외가 발생하기 전에 .so가 언로드되도록하는 두 번째 문제가있었습니다. 이 두 가지를 모두 고치는 것은 이제 segfaults없이 작동하는 예외를 얻는다는 것을 의미합니다. – KayEss

관련 문제