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?