2

我的情况有点特殊:我有一个应用程序在使用 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 文件转储导入函数的名称?

4

2 回答 2

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不同之处在于 forbar它表示可以在SECT3wheras for fooit prints中找到该符号UNDEF

因此,为了找到从其他地方(例如 DLL)导入的所有符号,您只需UNDEFdumpbin /symbols.

于 2018-12-26T23:43:52.927 回答
1

如果您使用例如

dumpbin /symbols Source.obj >dump.txt

它将转储 COFF OBJECT 以及它说 External 和 UNDEF 链接需要找到这些外部符号的任何地方。

我创建了一个取决于

void foo();
int main()
{
    foo();
}

并且可以在转储文件中看到

01B 00000000 UNDEF  notype ()    External     | ?foo@@YAXXZ (void __cdecl foo(void))

UNDEF 和 External 意味着链接器将使用 this into 来搜索未定义的符号。

COFF 格式在此处描述

于 2018-12-26T09:42:37.767 回答