Pergunta

Eu tenho um aplicativo que consiste em diferentes módulos escritos em C ++.
Um dos módulos é destinado a lidar com tarefas distribuídas em SunGrid Engine. Ele usa a API DRMAA para apresentação e monitorização da rede jobs.If o cliente não suporta grade, máquina local deve ser usado
O objeto compartilhado do libdrmaa.so API está ligada em tempo de compilação e carregado em tempo de execução.
Se o cliente usando a minha candidatura tem esse ".so" está tudo bem, mas no caso do cliente não tem que, sai do aplicativo falhando ao carregar bibliotecas compartilhadas.
Para evitar isso, eu substituí as chamadas de API com ponteiros de função obtidos utilizando dlsym () e dlopen (). Agora eu posso usar a máquina local em vez de rede se a chamada para dlopen não sucede e meu objetivo é alcançado.
O problema agora é que o aplicativo agora é executado com êxito para pequenas testcases mas com testcases maiores lança falha de segmentação, enquanto o mesmo código usando o carregamento dinâmico funciona corretamente.

Estou faltando alguma coisa ao usar dlsym () e dlopen ()?
Existe alguma outra forma de conseguir o mesmo objetivo?

Qualquer ajuda seria apreciada.

Thanx,

Foi útil?

Solução

É muito pouco provável que seja um problema direto com o código carregado via dlsym() -. No sentido de que o carregamento dinâmico torna seg-fault

O que ele pode fazer é expor um problema separado, provavelmente por mover coisas ao redor. Isso provavelmente significa um ponteiro de rua (não inicializado) que aponta em algum lugar 'legítimos' no caso de ligação estática, mas em outro lugar, no caso de ligação dinâmica - e em algum lugar gatilhos então o seg a falhas. Na verdade, isso é um benefício para você, a longo prazo -. Isso mostra que há um problema que de outra forma poderiam permanecer sem ser detectada por um longo tempo

Eu considero isso como particularmente provável, já que você menciona que ocorre com testes maiores e não com os pequenos.

Outras dicas

Como Jonathan Leffler diz, o problema muito provavelmente existe no caso em que você está usando a API diretamente; ele só não causou um acidente ainda.

O primeiro passo quando você começa um SIGSEGV deve ser analisar o dump de memória resultante (ou apenas executar o aplicativo diretamente sob depurador), e olhando , onde que caiu. Aposto $ 0,02 que ele está falhando em algum lugar dentro malloc ou free, caso em que o problema é simples corrupção de pilha de idade, e existem muitas ferramentas pilha-verificador disponíveis para ajudar a pegá-lo. Solaris fornece watchmalloc , que é um bom começo.

Se você está lançando uma exceção em uma função extern "C", em seguida, a aplicação tem de parar. Isso ocorre porque o C ABI não tem as facilidades para propagar exceções.

Para contrariar esta situação ao utilizar DLL (ou bibliotecas compartilhadas) você normalmente tem uma função de um C que retorna um objeto C ++. Em seguida, o remanescente é interacção com que C ++ objecto que foi devolvida a partir do DLL.

Este padrão sugere (e eu estresse sugere) uma fábrica como objeto, assim a sua DLL deve ter um único extern função "C" que retorna a * vazio que você pode reinterpret_cast <> de volta para a ++ objeto de fábrica C.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top