Basicamente, são duas perguntas em uma - porque, se eu puder listar todos os símbolos exportados em um sistema, juntamente com o caminho de sua biblioteca compartilhada, poderia simplesmente obter grep
essa saída.
Para símbolos do kernel, acho que é um pouco mais fácil - porque sempre podemos cat /proc/kallsyms
obter uma lista de todos os símbolos desses módulos carregados na memória; em seguida sudo cat /proc/modules
, fornecerá uma lista de módulos carregados com seus endereços, mas não os caminhos de onde os módulos foram carregados (se eles forem criados como objetos .ko separados e fora da árvore)
Por exemplo, tento rastrear o programa kst
usando ltrace
:
$ ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce800
...
... e eu gostaria de saber onde isso _ZNK13QGraphicsItem10parentItemEv
reside.
Então, o que fazer com os símbolos da biblioteca compartilhada? Lendo através do [gcc-help] Re: localizando a biblioteca na qual o símbolo está definido. ; Eu tentei algo assim:
$ find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...
... mas isso me dá problemas adicionais: eu realmente não conheço todos os caminhos que são verificados em busca de bibliotecas compartilhadas no meu sistema; portanto, quando tentei pela primeira vez find /lib ...
, não encontrei nada; Acho essa palpite cansativa para diretórios, bem como a alternativa: escanear todo o sistema de arquivos-raiz com find
... E também pareço acertar * .sos que não podem ser abertos nm
(talvez porque sejam links simbólicos?), Que gerar várias mensagens de erro (das quais também não gosto).
A questão é - ldd
(ou ld
?) Provavelmente executa algumas dessas pesquisas de símbolos, mas tentei as respectivas páginas de manual e não consigo encontrar uma maneira de "encontrar" qualquer símbolo na linha de comando, sem fornecer algum tipo de arquivo executável como um argumento. Pergunta secundária - haveria uma maneira de usar essas ferramentas para isso?
Então, o que eu estou procurando uma ferramenta de linha de comando, que se comportaria algo como (pseudocódigo):
$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...
... onde eu não especifico nenhum diretório para pesquisar - mas que também manipula, por exemplo, LD_PRELOAD
ou LD_LIBRARY_PATH
; diga se eu fizer:
$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'
... então eu pegaria o local /path/to/mylib.so
onde o símbolo fornecido foi definido (dado que esse símbolo não existiria nas bibliotecas padrão) - e produziria "não encontrado" caso contrário. Caso contrário, ./findsymbol --dumpall
poderia produzir uma lista de todos os símbolos disponíveis e seus locais vistos em um determinado ambiente (por exemplo, um bash
shell específico ).
Existe uma ferramenta como esta para Linux?
fonte
scanelf
permite que você especifique diretórios específicos para pesquisar e oferecer suporte à pesquisa recursiva,-r
para que você possa ajustar seus caminhos de pesquisa ou pesquisar em todo o sistema sem muitos problemas. Por exemploscanelf -r -s SYMBOL /lib/* /usr/* /opt/*
, encontrará a maioria dos lugares que as bibliotecas estão escondidas.Nos sistemas GNU (ao usar o vinculador dinâmico GNU libc), você pode executar seu programa como:
Para descobrir onde os símbolos são resolvidos.
fonte
Eu já me deparei com isso várias vezes, tentando portar código de um sistema Linux para outro. Normalmente, acabo cumprimentando todos os diretórios padrão. Não consegui encontrar nada no Google. Então, aqui está um script rápido:
edt11x / findinsharedlibs
fonte