Проблема с использованием процедур динамической загрузки C.

StackOverflow https://stackoverflow.com/questions/1079808

Вопрос

У меня есть приложение, состоящее из разных модулей, написанных на C++.
Один из модулей предназначен для решения распределенных задач на SunGrid Engine.Он использует API DRMAA для отправки и мониторинга заданий сетки. Если клиент не поддерживает сетку, должна использоваться локальная машина

Общий объект API libdrmaa.so связывается во время компиляции и загружается во время выполнения.
Если клиент, использующий мое приложение, имеет это ».
Чтобы избежать этого, я заменил вызовы API указателями на функции, полученными с помощью dlsym() и dlopen().Теперь я могу использовать локальную машину вместо сетки, если вызов dlopen не увенчался успехом и моя цель достигнута.
Проблема теперь в том, что приложение теперь успешно работает для небольших тестовых случаев, но в более крупных тестовых случаях оно выдает ошибку сегментации, в то время как тот же код, использующий динамическую загрузку, работает правильно.

Я что-то упустил при использовании dlsym() и dlopen()?
Есть ли другой способ достичь той же цели?

Любая помощь будет оценена по достоинству.

Спасибо,

Это было полезно?

Решение

Очень маловероятно, что это будет прямая проблема с кодом, загруженным через dlsym() - в том смысле, что динамическая нагрузка делает его сег-разломом.

Возможно, он выявляет отдельную проблему, вероятно, перемещая вещи.Вероятно, это означает случайный (неинициализированный) указатель, который указывает где-то «законно» в случае статической ссылки, но где-то еще в случае динамической ссылки - и где-то еще вызывает ошибку сегмента.Действительно, в долгосрочной перспективе это принесет вам пользу: это покажет, что существует проблема, которая в противном случае могла бы оставаться незамеченной в течение длительного времени.

Я считаю это особенно вероятным, поскольку вы упомянули, что это происходит с более крупными тестами, а не с маленькими.

Другие советы

Как говорит Джонатан Леффлер, проблема, скорее всего, существует в том случае, если вы используете API напрямую;просто это еще не привело к сбою.

Ваш самый первый шаг, когда вы получаете SIGSEGV следует проанализировать полученный дамп ядра (или просто запустить приложение непосредственно под отладчиком) и посмотреть где оно сломалось.Ставлю 0,02 доллара, что где-то внутри он рушится. malloc или free, и в этом случае проблема заключается в старом старом повреждении кучи, и существует множество инструментов проверки кучи, которые помогут вам ее обнаружить.Солярис предоставляет watchmalloc, что является хорошим началом.

Если вы генерируете исключение во внешней функции «C», приложение должно закрыться.Это связано с тем, что C ABI не имеет средств для распространения исключений.

Чтобы противостоять этому при использовании DLL (или общих библиотек), у вас обычно есть одна функция C, которая возвращает объект C++.Затем оставшееся взаимодействие происходит с объектом C++, который был возвращен из DLL.

Этот шаблон предполагает (и я подчеркиваю, предполагает) объект, подобный фабрике, поэтому ваша DLL должна иметь одну внешнюю функцию «C», которая возвращает void*, который вы можете переинтерпретировать_cast<> обратно в объект фабрики C++.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top