여러 개의 공유 라이브러리로 분리되고 플러그인 공유 라이브러리에서 추가 기능을로드하는 크로스 플랫폼 C++ 응용 프로그램이 있습니다. 플러그인 라이브러리는 호출 응용 프로그램에 대한 지식이나 종속성이 없어도 자체적으로 포함되고 함수로 간주됩니다.중복 심볼이있는 C++ 플러그인 라이브러리의 Segfault
플러그인 중 하나에 주 응용 프로그램의 복사 된 코드가 포함되어 있으므로 엔진의 코드 이름과 중복되는 기호 이름이 포함되어 있습니다. (네, 그렇습니다. 일반적으로 플러그 - 인이 작성된 시점에 엔진은 모 놀리 식 바이너리 였고 라이브러리를 공유 할 수 없었습니다.) Windows에서 모든 것이 정상적으로 실행됩니다. Linux에서 우리는 segfault를 얻고있었습니다. 오류의 스택 추적을 보면 복제 클래스 이름에서 함수를 호출 할 때 플러그인에서 발생했습니다. 약간 다른 버전의 공유 코드가있는 엔진과 플러그인의 결과 인 것으로 보입니다 (일부 클래스 기능은 플러그인에서 주석 처리되었습니다). 마치 플러그인이 심볼 대신 런타임 엔진에 링크 된 심볼을 얻는 것처럼 보였습니다. dlopen
의 매개 변수를 dlopen(pFilepath, RTLD_LAZY | RTLD_LOCAL)
으로 변경하여 문제를 수정했습니다.
그러나 엔진을 다시 작성하여 공유 라이브러리로 분할하면 (플러그인에서 최종 용도로 사용하기 위해) segfault 오류가 다시 발생합니다. 그리고 스택 트레이스를 보면, 엔진 -> 플러그인 -> 엔진이됩니다.
런타임 링커가 플러그인의 심볼을 엔진에 매핑하지 않도록 지정하는 방법이 있습니까 (특히 플러그인에서 정의 된 경우)?
감사합니다. 매트
편집 2009년 12월 3일
내가 먼저 자신의 네임 스페이스에 플러그인의 코드를 포장했습니다. 그것은 엔진에 링크되어있는 라이브러리에 정적으로 연결되어 있기 때문에 작동하지 않습니다. 정적 라이브러리의 버전이 다르므로 segfault!
그런 다음 엔진의 빌드를 변경하고 라이브러리를 정적으로 링크했습니다. 그리고 그것을 실행할 때 더 이상 문제가 없습니다. 따라서 공유 라이브러리 심볼을 내 보낸 다음 패키지를 열 때 동적으로 플러그인으로 재배치 된 결과입니다. 그러나 엔진의 모든 코드가 단일 실행 파일에있을 때 심볼을 내보내지 않으므로 (플러그인의 심볼을 엔진으로 재배치하려고하지는 않습니다).
Open-MPI를 사용하는 프로그램의 병렬화 된 버전이 있고 여전히 segfault를 얻으므로 여전히 문제가 있습니다. 그것은 여전히 엔진 심볼을 내보내고 플러그인을 재배치한다는 점에서 나타납니다. 이는 Open-MPI가 응용 프로그램을 실행하는 방법과 관련이 있습니다.
런타임에 심볼을 동적으로 재배치하지 않는다는 것을 알려주는 플러그인 공유 라이브러리에서 사용할 수있는 링커 플래그가 있습니까? 또는 기호를 숨기면 이동하지 않습니다. -s
("모든 기호 정보 생략")을 시도했지만 분명히 동적 기호가 변경되지 않았습니다 (nm -D <plugin>
을 사용하여 확인).
이러한 기호는 전역 또는 함수 이름입니까? 코드를 약간 변경할 수 있습니까? –
이들은 클래스 및 해당 멤버 함수입니다. 엔진 코드베이스에서 36 개의 파일이 사용되므로 각 클래스 이름이나 파일을 수정하고 싶지 않습니다. 최종 목표는 시간 제약과 코드 유효성 검사로 인해 플러그인을 다시 작성하는 것이지만, 필자는 그렇게하지 않으려 고하지 않습니다. – CuppM
@CuppM, 예를 들어, "bar"멤버가 2 곳 정의 된 "Foo"클래스가 있습니까? "Foo"는 두 경우 모두 동일한 네임 스페이스에 있습니다. 그렇다면 이것은 결코 당신을 위해 제대로 작동하지 않을 것입니다. "Foo"중 하나를 자신의 네임 스페이스로 이동하면 인생이 더 쉬워집니다. – Glen