Найти объектный файл, вызывающий зависимость

Я нахожусь в некоторой исключительной ситуации: у меня есть приложение, которое компилирует, связывает и запускает при компиляции с 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 описан здесь

Другие вопросы по тегам