Найти объектный файл, вызывающий зависимость
Я нахожусь в некоторой исключительной ситуации: у меня есть приложение, которое компилирует, связывает и запускает при компиляции с MSVC. Сейчас я нахожусь в процессе перекомпиляции его clang-cl, что приводит к его компиляции, связыванию и падению.
Благодаря Dependency Walker я обнаружил, что загружаются неожиданные библиотеки DLL. В моем случае найти символ для std::allocator<char>::allocator(allocator const &)
,
С этим у меня в настоящее время есть следующая информация:
- DLL, требующая этот символ
- DLL, выставляющая символ
- Символ, который дает проблемы
Чтобы регистрировать ошибку, я должен иметь возможность уменьшить код до приемлемого размера. Загрузка всей базы проприетарного кода не возможна, загрузка 20-строчного файла.cpp.
Чтобы уменьшить, мне нужно найти.cpp/.obj-файл, который требует этот символ. Оттуда уменьшение становится легкой работой.
При этом я ищу способ определить, ищет ли файл.obj символ в другой DLL.
Я уже нашел:
- dumpbin / SYMBOLS: сообщает, куда экспортируется символ
- dumpbin /DEPENDENTS: говорит мне, что DLL зависит от DLL
dumpbin /DEPENDENTS
состояния:
Не сбрасывает имена импортируемых функций.
Как вывести дамп имен импортируемых функций на основе файла.obj?
2 ответа
dumpbin /symbols
действительно правильный инструмент для работы, поскольку он также перечисляет неопределенные символы.
Например, при использовании dumpbin /symbols
распечатать символы в объектном файле, сгенерированном из исходного файла, содержащего
void foo();
void bar() {
foo();
}
мы получаем
File Type: COFF OBJECT
COFF SYMBOL TABLE
[...]
008 00000000 UNDEF notype () External | ?foo@@YAXXZ (void __cdecl foo(void))
009 00000000 SECT3 notype () External | ?bar@@YAXXZ (void __cdecl bar(void))
[...]
Как видите, он содержит оба символа для определенной функции bar
и символ для функции foo
это просто объявлено. Разница в том, что для bar
это говорит о том, что символ можно найти в SECT3
где для foo
это печатает UNDEF
,
Таким образом, чтобы найти все символы, которые импортированы откуда-то еще (например, DLL), вам просто нужно найти UNDEF
на выходе dumpbin /symbols
,
Если вы используете, например,
dumpbin /symbols Source.obj >dump.txt
Он выбросит объект COFF и везде, где говорится, что External и UNDEF, связаны с необходимостью найти эти внешние символы.
Я создал небольшой пример, который зависит
void foo();
int main()
{
foo();
}
и можете увидеть это в файле дампа
01B 00000000 UNDEF notype () External | ?foo@@YAXXZ (void __cdecl foo(void))
UNDEF и External означает, что это в будет использоваться компоновщиком для поиска неопределенного символа.
Формат COFF описан здесь